さて前回のプログラムにさらに機能を付け加えようか。
ちょっとプログラムが長くなったので、今回の投稿の最後に掲載するよ。
例によって、コピペ用のものは以下のサイトに置くね。
http://pastebin.com/R0AVwq5h
機能追加の方針
機能追加の方針は前回にも言ったとおり以下の2つだよ
方針(1)真上のチェストから骨粉を補給する
- turtle.suckUp() メソッドで真上のチェストからアイテムを入手する。このメソッドはちょっと癖があって以下のような特徴があるよ
- 内部インベントリを持つ真上のブロックから入手しようとするが、このとき一番左上のスロットにあるものをまるごと(1スタック)入手しようとする。入手数を指定することはできない
- 入手したアイテムは現在の選択スロットに格納しようとするが、できなかったらそれ以降のスロットへ格納する
方針(2)定期的に収穫した作物を真下のチェストに格納する
- turtle.dropDown(個数) メソッドで現在の選択スロットにあるアイテムを真下のチェストに格納する(落とす)。個数を省略するとそのスロットのアイテムをすべて落とすよ。
- スロット1と2は種と骨粉用に使っているからそれ以降の、スロット3-16を収穫物格納用とみなして、定期的に落としてあげればいいよね。今回は50回収穫したら落としているよ。
ソース解説
このような方針から以下のようなプログラムを作ったよ。
相変わらずMain部分はシンプルだね。ソースを追っていくときはMain部分からがお勧め。
今回は基本的に前回のプログラムにいくつかサブ関数を加えて、そのサブ関数実行のトリガーとして条件節をつけただけだよ。
- 骨粉ゲット機能を実現するプログラムの解説
- getMeals() を新しく追加したよ。これは、骨粉4個未満なら上のチェストから補給するんだ。ただし補給に失敗したり、補給したけど在庫少量で4個に満たなかったらエラー返して終了するよ。
- そして、useMeals() に上記のgetMeals()を実行する条件節を加えたよ。ちなみにこの条件節の書き方はわかりやすいんだけど冗長で気持ち悪いので僕好みに書き直したのが useMeals2()ね。プログラム中では使ってないけれど機能はまったく同じだよ。
- アイテム格納を実現するプログラムの解説
- dropItems(開始スロット, 終了スロット) を新しく追加したよ。開始スロットから終了スロットまで順番にすべてのアイテムを下のチェストに格納するんだ。プログラム中では dropItems(3,16)で使っているね。
- そして、Main実行部分では、50回実行するごとにdropItems()を実行しているよ。ちなみに、「i%50==0」の意味は、繰り返し回数iを50で割ったときの余りを計算して余り0(割り切れる)の意味ね。
- それとすべての実行の終了後にもドロップさせているけど、必要なかったら削ってね。
-
プログラムソース
-- ######################## -- cultivate <n> -- version 0.3 -- http://hevohevo.hatenablog.com/ -- ######################## -- ############# -- config ARGS = {...} MAX = ARGS[1] SEED_SLOT = 1 MEAL_SLOT = 2 -- ################## -- define functions function plantSeed() turtle.select(SEED_SLOT) if turtle.place() then return true else print('failed: plantSeed') return false end end function getMeals() turtle.select(MEAL_SLOT) if turtle.suckUp() then -- succeed in sucking meals if turtle.getItemCount(MEAL_SLOT) < 4 then -- but, meals < 4 print('failed: getMeals, meal < 4 ') return false else -- ok, meals > 3 print('getMeals') return true end else -- failed to sucking meals print('failed: suckUp') return false end end function dropItems(begin_slot, end_slot) print('drop items: slots ',begin_slot,'-',end_slot) for i=begin_slot, end_slot do turtle.select(i) turtle.dropDown() end turtle.select(1) end function useMeals() if turtle.getItemCount(MEAL_SLOT) < 4 then if getMeals()==false then return false end end turtle.select(MEAL_SLOT) turtle.place() turtle.place() turtle.place() return true end -- useMeals() and useMeals2() are the same functions. function useMeals2() if (turtle.getItemCount(MEAL_SLOT) < 4) and (getMeals()==false) then return false else turtle.select(MEAL_SLOT) turtle.place() turtle.place() turtle.place() return true end end function harvest() turtle.select(SEED_SLOT) turtle.dig() end -- ################## -- Main turtle.dig() for i=1,MAX do print(i,'/',MAX) if plantSeed() == false then break end if useMeals() == false then break end harvest() if i%50==0 then dropItems(3,16) end end dropItems(3,16)
次回のお話
テストしたら、cultivate 1000 くらいまでは余裕で実行できたよ。
それ以上は骨粉の在庫ががががw
ただ収穫物のチェスト収納でちょっとだけ気になるところがあるのでそこを次回あたりに改造しようかな。