さて前回は気になる引きをしたけれど
プログラムを動かしてみると、すぐにプログラムの問題点に気づくよね?
定期的に収穫物を下のチェストにドロップするのだけど、
そのときに少量の骨粉もドロップしてしまうんだ。
- 収穫物用チェストに骨粉が混じるのが気持ち悪い
- 貴重な骨粉を無駄にしたくない。使い切りたい
という意図で、今回はこれを修正したいと思う。
原因と対策
この原因は、手持ちの骨粉が2~3個残っている状態で
真上のチェストから1スタック取ってきてしまうことだよね。
64個を超えてしまって、後のほうのスロットに骨粉がはみ出してしまう。
ではどうすればいいのか。
一番の正攻法は、骨粉が0個になったのを確認してから骨粉を取ってくればいいよね。
これまでは、骨粉を振り掛けるときに、turtle.place()を連続3回まとめてやっているけれど、
毎回振り掛ける前に自分の骨粉の個数を確認すればいい。
0なら骨粉を取りにいくわけ。
そして実装したのが以下のプログラム
促成栽培プログラムはこれで一応完成のつもりだよ。
プログラム
-- ######################## -- cultivate <n> -- version 0.4 -- 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 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 useOneMeal() if (turtle.getItemCount(MEAL_SLOT) ==0) and (turtle.suckUp()==false) then print('failed: suckUp, and meal = 0') return false else turtle.select(MEAL_SLOT) turtle.place() return true end end function useMeals() local flag = true for i=1,3 do if useOneMeal() == false then flag = false break end end return flag 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)
プログラムの解説
- 以前あった、 getMeals()関数は全削除だよ。代わりに useOneMeal()関数を新しく作って、その中で骨粉補給もこなしている。
- useOneMeal()は、実行前に骨粉の個数を調べ、0なら補給しようと試みるよ。補給に失敗したらエラーを返すんだ。
- それに伴い、useMeals()関数も全面的に書き換えているよ。useOneMeal()が3回連続成功(trueを返す)ならそのまま収穫作業を続け、途中1回でも補給に失敗し(falseを返し)たらすぐにループを抜けて、終了するんだ。
まとめ
前回よりもプログラムの文量は減っているよね?
3回振りかけという大雑把な作業単位よりも、1回振りかけというさらに細かい作業単位にモジュール化したほうが、プログラム全体でわかりやすくなっている。
とりあえず動くプログラムを作って動かして、タートルをじっくり観察する。問題を発見したら、やりたい作業をどんどん細かく分けてモジュール化することで機能を修正・追加していく。
このような行き当たりばったりのプログラミング方法は、動きがすぐに見えて問題点が目に見えてわかるというタートルならではだよね。
このようなツギハギプログラミングによる試行錯誤と、最終的に思ったとおりに動くタートルのかわいさ。これが、僕がComputerCraftに感じる魅力なんだ。
これからもこんな感じで行き当たりばったりでBlogを続けていくつもりだよ。