Minecraftとタートルと僕

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

こちらのページは更新が滞っており、情報が古くなりつつあります。新しいCC情報サイトをはじめましたので、もしよければご参照ください。今後ともよろしくお願い申し上げます。

「百億のマインクラフトと千億のタートル」(https://hevo2.hatenablog.com/)

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

前回挙げた問題点の改善回だよ。

問題1とその対策

問題1「プログラム実行時に、繰り返し回数を指定したい」

  • 実行時、以下のようにプログラム名のあとに1個の空白を入れて、「引数(Arguments)」を記述することで回数を変えられるにしよう
> harvest 20

問題2とその対策

問題2「10回くらいならいいけれど、数が増えると骨粉が尽きて未成熟の作物を収穫してしまう」

  • 各関数で種・骨粉の個数管理をしよう
    • 種はplace()関数の成功・失敗で判断しよう
    • 骨粉は4個未満になったら停止しよう
  • 種まき・骨粉の使用に成功したらtrue、失敗したらfalseを各関数が返すようにしよう

今回の仕様のプログラム

-- ########################
-- cultivate <n>
-- version 0.2
-- ########################

-- #############
-- config
ARGS = {...}  -- 引数を変数ARGSに代入。ピリオド3つと覚えておこうね
MAX = ARGS[1]  -- 引数を変数MAXに代入 
SEED_SLOT = 1
MEAL_SLOT = 2

-- ##################
-- define functions
function plantSeed()
  turtle.select(SEED_SLOT)
  -- place()を実行してそれが成功(true)か、失敗(false)かで判別しているよ。
  if turtle.place() then
    return true
  else
    print('failed: plantSeed')
    return false
  end
end

function useMeals()
  -- 骨粉の数が4未満だったらエラーメッセージ出してfalse返します
  if turtle.getItemCount(MEAL_SLOT) < 4 then
    print('failed: useMeals (meal < 4)')
    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)

  -- 以下のサブ関数は、それぞれ失敗(false)したらforループを抜けるよ。
  if plantSeed() == false then
    break
  end
  
  if useMeals() == false then 
    break 
  end

  harvest()
end

ざっと作ったので、ミスがあったらご指摘くださいな。
前回のプログラムにIF条件をいくつかつけただけなので、見やすさは相変わらずだね。
コメントをソース中に書いておいたのでだいたいわかると思うけれど。
以下、このプログラムのポイント

  • 使っているturtle APIの説明
    • turtle.place(): 現在の選択アイテムを設置(あるいは使用)しようと試みる。失敗したらfalseを返す
    • turtle.getItemCount(スロット番号): 指定したスロット番号にあるアイテムの個数を返す
  • 定義した plantSeed()とuseMeals()は、それぞれの作業が問題なく成功したら「true」、失敗したら「false」を返すようにしてある。
  • forループやwhileループを途中で抜け出るにはbreakを使うよ。ただしbreakが使える場所は、endの直前だけという制限があるので注意。
  • 「if plantSeed()==false then」ではなく、「if not plantSeed() then」でもOK。このあたりは好みで。

プログラム実行時の引数について追記(2013/12/18)

  • プログラム実行時の引数(Arguments)は、「...」というピリオド3つを記載することで、プログラム中で取り扱うことができる。
    • ピリオド3つのままだと引数がバラバラで取扱いづらいのでコンストラクタを使い、バラバラの引数をテーブル(table)の形で扱えるようにする。「{...}」
    • 「ARGS = {...}」は、変数名ARGSに、引数をテーブルの形で代入する。

実際には意味がないけれど、以下のような引数を与えてこのプログラムを実行すると
> harvest a b c d
「ARGS={...}」という記述によって、ARGSの中身は次のようになる
ARGS = {"a", "b", "c", "d"}

  • このうち前から3番目の引数を取り出したかったら ARGS[3]と書けばいい

コピペ時の注意

日本語がプログラム中に入っているとエラー起こすみたいなので注意。
以下のサイトにコピペ用に、日本語コメントついてないものを置いておきますね。
http://pastebin.com/57RjbXci


さらなる機能追加は次回

タートルの真上にチェスト置いて、骨粉が足りなくなったら補給するようにしよう。
そして、たくさん繰り返すうちにインベントリが満タンになるのを防ぐために、定期的に所持物を収納用チェストにしまおう。
ヒント: turtle.suckUp()、turtle.dropDown()