読者です 読者をやめる 読者になる 読者になる

Minecraftとタートルと僕

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

【More Turtles Mod使用】シルクタッチ回転式直下掘りプログラムを改造しよう

チュートリアル Lua ComputerCraft Minecraft

これまでのお話と今回の目標

前回の記事で、シルクタッチを使った穴掘り用としては、ほぼ問題なく動くプログラムができました。

ただし実際にこれを使っているといくつかの不満が出てきます。
その中でも特に気になるのが、一つの穴を掘った後、その次の穴を連続して掘ろうと思った時に意外と手間がかかることです。

現状では、具体的な手順としては以下のようになります。

  1. タートルが採掘を完了し、穴にもフタをしてプログラム終了。
  2. ユーザーがタートル破壊してアイテム化、同時にこぼれ落ちた採掘アイテムもゲット。
  3. 次の採掘予定地へ移動し、タートル設置。
  4. フタ用のブロック(5個以上)をタートルのインベントリに挿入。
  5. ターミナル画面上で、プログラム名を入力してプログラム実行
  6. (必要なら燃料アイテムも与える)
  7. やっと採掘開始

これはめんどくさい。

そもそも十字型採掘の一番の弱点として、十字型で正方形の土地をきれいに無駄なく掘り抜くのが難しいということがあります。

たとえ話をしましょう。
正方形の白紙があります。十字型のハンコを使ってその全面を埋め尽くしなさいと言われたとき、どうすれば良いか悩みますよね。 
それだったらまだ1x2の長方形型ハンコの方が、整然と並べればいいだけなので埋め尽くしやすい*1

だから、この十字型採掘プログラムでは、プログラム自体で連続して複数の穴を掘ることを私は想定していません。あくまで、ユーザーが採掘予定地へ設置するという形式をとりたい。だから、プログラム実行までの手間をできるだけ省きたいのです。

そこで、採掘プログラムを「startup」で自動実行することで、以下のような手順で実行できるようにプログラムを改造します。

  1. タートルが採掘を完了し、穴にもフタをしてプログラム終了。
  2. ユーザーがタートル破壊してアイテム化、同時に採掘アイテムもゲット。
  3. 次の採掘予定地へ移動し、タートル設置。
  4. (自動起動するプログラムの要求に従って、フタ用ブロックと燃料を挿入)
  5. 次の採掘開始

今回の目標は、採掘開始までの流れを簡略化すること

つまり、タートル設置、アイテム挿入、動き出す、というスムーズな流れを目標とします。

好きな場所を探して、
f:id:hevohevo:20140219000052p:plain:h200

タートル設置。
f:id:hevohevo:20140219000056p:plain:h200

右クリックで画面開いたらアイテムを入れるだけで、採掘スタート!
f:id:hevohevo:20140218232012p:plain:w450


プログラムの使い方

実際のソースコードは本記事の末尾に掲載しています。
これを使って以下のように準備してください。

1.プログラムのダウンロード&インストール

pastebinコマンドを使うのが一番楽だと思います。
以下のコマンドで、手元に「boring4」という名前でプログラムをインストールします。

> pastebin get JWt99iVW boring4

2.スタートアップファイルを作る

タートル設置時に、「startup」というファイル名のプログラムを自動起動することになっています。これを利用しましょう。

「edit」コマンドを利用して、以下のような内容の「startup」ファイルを作ってください。

> edit startup

startupファイルの内容。「boring4」というプログラムを実行するというコードです。

shell.run("boring4")

3.あとは使う!

これで準備完了。あとはタートルを掘りたい場所に設置してアイテムを突っ込むだけです。

補足

なお以下のように、pastebinコマンドの時点で、このプログラムをそのまま「startup」として保存しても構いません。一応念のため。

> pastebin get JWt99iVW startup


shell.run()関数をいったん経由した方が、プログラム実行時の引数も指定できるのでいろいろと応用範囲が広いのです。
そう、このプログラムは、引数を与えて実行すると穴にフタをしないようにできるのでしたね。

-- "boring4"プログラムを、文字列"nolid"という引数を与えた上で実行する。
shell.run("boring4", "nolid")

ソースコード解説

どのくらいの人がこの解説を読んでいるんだろうと思いつつ以下に説明します。

改造は、以下の2つの関数を作成して使っているだけです。
それぞれ、アイテムが必要数だけ挿入されるまで待つ、燃料が補給されるまで待つ、という機能を実現しています。

アイテムが挿入されるまで待つ waitForEnoughItems()

某Modの名前を彷彿する関数名ですが、それはさておき。

function waitForEnoughItems(itemName, n, slot)
  turtle.select(slot)
  os.sleep(0.5)
  while turtle.getItemCount(slot) < n do
    if itemName then print(string.format("Insert %s into slot %d",itemName,slot)) end
    os.pullEvent("turtle_inventory")
    os.sleep(1)
  end
end
  • この関数の引数として、表示メッセージ埋め込み用の「アイテム名」、「必要数」、「監視するスロット番号」
  • 基本的にはwhileループで回し、ループ中に「os.pullEvent("turtle_inventory")」を仕込んでおくことでタートルのインベントリ内容の変化を待つ。
  • 監視スロット内のアイテムが揃ったらwhileの条件式でループを抜ける。
  • 途中に埋め込まれているsleep()は、発生してからの残留時間が長い"turtle_inventory"イベントの影響を取り除くため(sleep()がないと2周ループすることがある)。
    • どうやら、turtle.select()で選択スロットを変えるだけで"turtle_inventory"イベントが発生しているようです。なぜにw
  • 表示メッセージを出したくない時は、「itemName」としてfalseを与えること。

燃料が補給されるまで待つ waitForEnoughFuel()

function waitForEnoughFuel(minLevel, slot)
  turtle.select(slot)
  turtle.refuel()
  while  turtle.getFuelLevel() < minLevel do
    print(string.format("Insert fuel-items into slot %d: %d/%d",slot, turtle.getFuelLevel(), minLevel))
    os.pullEvent("turtle_inventory")
    turtle.refuel()
    os.sleep(1)
  end
end
  • 基本的な構造は、waitForEnoughItems()と変わらず。
  • 引数として、最小燃料値と監視するスロット番号を指定。
  • まず最初にrefuel()しなくてはならないため、repeat~until構文で書くともっとシンプルになるかなと書いてみたが、行数はさほど変わらなかったのでこちらのwhile構文の方を採用。

今回のまとめ

さあこのプログラムを使いまくって、ワールドに十字の穴を開けまくろう!

次回は、Mining Turtleの性能について細かく調べてみたいと思います。

打倒BCクァーリー! (さすがにQuarry plus!に勝とうとは思いませんw)
シルクタッチを使った上で、クァーリーよりも早く1チャンク掘り抜くことができればすごいですよね。
これを最終的な目標としてみましょう。夢は大きく持たなくては!

そのための性能調査です。

ソースコード

http://pastebin.com/JWt99iVW

おまけ

こっそりと、Fortune Mining Turtle(More Turtles Modで追加)でも使えるプログラムを追加。
そのうちFortune Mining Turtleについても記事を書かなくてはいけませんね。
SilkTouch Mining Turtleと内容がかぶるところが多いので迷うところですが。

*1:この、四角形の土地を掘り抜くという需要に答えるプログラムについてはいくつかのアイデアがあるので、そのうち取り上げましょう。