YouTube とニコニコ動画で投稿中の動画シリーズで、動画に収まりきらなかったこぼれ話や詳細解説を掲載しています。
動画はこちらから
目次
作成したプログラム
auto_farming.lua
動画内の自動農場で使っているプログラム。動作には動画と同じような目印となるブロックを設置する必要がある。
pastebin get XzBE6jWr auto_farming.lua
でゲーム内からダウンロードできる。
コメント付き版
-- const
-- 床に設置する目印となるブロックを指定。
local BOTTOM_MARKERS = {
['minecraft:deepslate_tile_slab'] = {type = 'turn', direction = 'right'},
['minecraft:deepslate_brick_slab'] = {type = 'turn', direction = 'left'},
['minecraft:cobbled_deepslate_slab'] = {type = 'turn', direction = 'back'},
['minecraft:barrel'] = {type = 'storage'},
}
-- 天井に設置する目印となるブロックを指定。対応する作物を収穫する成長段階もしていする。
local TOP_MARKERS = {
['minecraft:jungle_slab'] = {type = 'farm', age = 7, slot = 1}, -- minecraft:carrot
['minecraft:spruce_slab'] = {type = 'farm', age = 7, slot = 2}, -- minecraft:potato
['minecraft:oak_slab'] = {type = 'farm', age = 5, slot = 3}, -- tofucraft:seeds_soybeens
['minecraft:birch_slab'] = {type = 'farm', age = 7, slot = 4}, -- minecraft:wheat_seeds
}
-- 燃料補給はこの値以上になるまで行う。
local FUEL_MIN = 1000
local TURN_FUNCS = {
left = turtle.turnLeft,
right = turtle.turnRight,
}
-- memory
local lastTurn
-- functions
-- 目印となるブロックから行動を決定する。
function getAction()
local isTop, top = turtle.inspectUp()
local isBottom, bottom = turtle.inspectDown()
return (isTop and TOP_MARKERS[top.name]) or (isBottom and BOTTOM_MARKERS[bottom.name]) or nil
end
-- 正面が壁かを判定する。特定のブロックのみに反応するようにしてもよい。
function isWall()
return turtle.detect()
end
function reset()
turtle.select(1)
end
function step(isFirst)
reset()
local action = getAction()
if action == nil then
turtle.forward()
lastTurn = nil
elseif action.type == 'farm' then
local isThere, crop = turtle.inspectDown()
turtle.select(action.slot)
-- 種が十分にあり、下が空気(何も植えられていない)とき
if turtle.getItemCount() >= 2 and not isThere then
turtle.placeDown()
-- インベントリに余裕があり、作物が十分成長して植わっているとき
elseif turtle.getItemCount(16) == 0 and isThere and crop.state.age >= action.age then
turtle.digDown()
-- それ以外
else
turtle.forward()
end
lastTurn = nil
elseif action.type == 'turn' then
if action.direction == 'back' then
if lastTurn then
TURN_FUNCS[lastTurn]()
turtle.forward()
else
-- 壁を向くように回転
while not isWall() do
turtle.turnRight()
end
-- 回れ左
turtle.turnLeft()
turtle.turnLeft()
turtle.forward()
end
else
if isFirst then
-- 壁を向くように回転
while not isWall() do
turtle.turnRight()
end
end
TURN_FUNCS[action.direction]()
turtle.forward()
lastTurn = action.direction
end
elseif action.type == 'storage' then
-- 種を入れておくスロットをメモ
local seed_slots = {}
for name, data in pairs(TOP_MARKERS) do
seed_slots[data.slot] = true
end
for i = 1, 16 do
turtle.select(i)
if seed_slots[i] == true then
-- 種スロットなら 16 個残す
turtle.dropDown(math.max(0, turtle.getItemCount() - 16))
else
-- そうでなければ全部
turtle.dropDown()
end
end
-- 十分な燃料を補給するまで繰り返す
while turtle.getFuelLevel() < FUEL_MIN do
turtle.suckUp(1)
if not turtle.refuel() then -- 燃料補給に失敗したとき
print(("Fuel: %d"):format(turtle.getFuelLevel()))
os.sleep(1)
end
end
turtle.forward()
else
turtle.forward()
lastTurn = nil
end
end
function main()
step(true) -- first step
-- メインループ
while true do
step()
end
end
-- main
main()
Lua使い方
まず、耕地の3ブロック上に、植える作物の目印となるブロックを設置する。デフォルトでは各木材のハーフブロックが指定されている。このとき、畑に高低差があってはならない。あとは、全ての耕地を通るように、床に目印となるブロックを設置する。デフォルトでは、深層岩レンガのハーフが左回転〈壁に向かって左を向く〉、深層岩タイルのハーフが右回転〈壁に向かって右を向く〉、深層岩の丸石ハーフが直前の動作と同じ方向にもう一度回転(直前の動作が回転でなければ壁を背にするように回転)〈壁を背にするように回転〉。(起動時には〈山括弧〉内の動作をする。)そして、移動経路を環状になるように指定したら、そのどこか一か所の上下を樽にする。上は燃料補給用、下は収穫物の回収用。なお、回収用の樽が満杯だと予期せぬ動作を行うかもしれない。最後に、タートルのインベントリの対応するスロットにタネを少量持たせ、プログラムを起動する。(最初は手動で耕地に種をまいておくとなお良い。)
詳細解説
動画に登場した要素を詳しく解説します。
用語集
動画内に出てきた専門用語やアイテムなどの解説です。
農業タートル
クワを持たせたタートル。農作物や適性ツールがクワのブロックの破壊の他、土を耕すことができる。ツルハシよりもクワの方がダイヤの要求量も少ないので、自動農場を作るなら採掘タートルよりこっちがいいだろう。耕すにはturtle.dig()
を使うことに注意。
フローチャート
アルゴリズム(ある目的を達成するための手順)などを視覚的に分かりやすく表現した図。ひし形は条件分岐を表すなど、その形によって、各プロセスの種類を示す。
状態遷移
ゲームで例えてみる。あるゲームでは、タイトル画面で決定ボタンを押すとゲームが開始され、開始後一分経つとタイトルに戻ってくるとする。このとき、"タイトル画面"と"ゲーム中"という二つの状態があり、ボタン操作や時間経過をきっかけに、その状態が移り変わる。これを状態遷移という。当然ながら、これには現在の状態を記憶しておく必要があり、ワールドから出ると再起動してしまうCCとの相性はあまり良くない。そのため、今回の自動農場では記憶の必要が無いように、天井や床に目印となるブロックを設置することによって、この問題を解決している。
コマンド
動画内で使用した、CC のコンピューターなどで実行可能なコマンドの解説です。
id コマンド
その機械に割り当てられたID(不変)と、label(可変)を確認する。CCのコンピューターなど保存されたデータは、[プロファイルディレクトリ]/saves/[ワールドフォルダー]/computercraft/computers/[ID]
に保存される。そのため、ここにあるファイルを開けば、任意のテキストエディタで編集することもできる。
プログラム関連
実際に CC でプログラミングするときに必要な知識です。基本的にプログラミング経験者向けの情報になります。
turtle.detect()
正面に障害物があるかを取得する。
turtle.inspectUp()
/turtle.inspectDown()
上下のブロックの情報を取得する。正面版にturtle.inspect()
がある。第一戻り値としてブロックが存在するか、第二戻り値としてその情報を返す。ブロックが存在した際には、その情報を持つテーブル(=name
にブロックID、state
にブロック状態、tags
にそのブロックが持つブロックタグをキーに持ち値がすべてtrue
のテーブルを持つ)を返す。
turtle.suckUp(count)
上に落ちているアイテムを拾う。あるいは、上にチェストなどがあれば、そこからアイテムを取る。count
が省略されるときは1スタック取る。
turtle.getFuelLevel()
現在の燃料補給量を返す。
turtle.refuel(count)
燃料補給をする。refuel コマンドとほぼ同じ。成功でtrue
を返す。
編集後記
ちょっとした裏話として、最後のカットでタートルがニンジンを収穫してますが、植えてるのはジャガイモです。つまり、バグです。(もちろん修正済み)