Minecraftとタートルと僕

PCゲームMinecraftのMOD「ComputerCraft」の情報を集めたニッチなブログです。

農業タートルプログラミング チュートリアル(3)

さて前回のプログラムにさらに機能を付け加えようか。
ちょっとプログラムが長くなったので、今回の投稿の最後に掲載するよ。
例によって、コピペ用のものは以下のサイトに置くね。
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
ただ収穫物のチェスト収納でちょっとだけ気になるところがあるのでそこを次回あたりに改造しようかな。