ちょっとだけ元気になったので更新。
はじめに
前回は、Fortune Mining Turtleを使ったフォーチュン付きブロックブレイカープログラムを紹介しました。
ダイヤ鉱石などを上のチェストに入れておくと、フォーチュン採掘で破壊して入手素材を増やしてくれます。
今回は、前回のプログラムで問題となった燃料関係を中心にプログラムを修正しましょう。
プログラム修正の方針
1.燃料補給のタイミング
上のチェストからブロックを1スタックとって、その個数だけフォーチュン採掘を行うので、その個数分の燃料を最低限必要な燃料としましょう。
具体的には、チェストからブロック入手するたびに燃料を確認します。 燃料が足りなかったら一時的に停止して燃料アイテムの補給を待つという以下の関数を作り利用しましょう。
- waitForEnoughFuel()関数の作成
2.アイテムドロップについて効率化
前回のプログラムでは、スロット1から16まで全てのアイテムを下のチェストにドロップしていました。しかしよく考えると、たかだが1スタック64個のブロックを破壊したとして、スロット16までドロップしようとするのは無駄です。
このプログラムでは、選択スロットを1にしたままブロックを破壊しているので、入手したアイテムはスロット1以降、順に前のスロットから詰まっていきます。
ということは、スロット1,2,3,4……と前のスロットから順にアイテムをドロップしていき、空のスロットに突き当たってドロップできないことがわかったらそこでドロップ作業を切り上げてしまえばいいわけです。
今回は、前のスロットから順に落としていく以下の関数を作成します。
- dropSeq()関数の作成
3.設定(config)できる項目を増やす
前回のプログラムでは、燃料を入れるスロット(FUEL_SLOT)と入手ブロックのスロット(BLOCK_SLOT)を設定できるようにしていましたが、今回はそれに加えて、鉱石ブロック用チェストの位置とアイテムドロップ用チェストの位置を変えられるようにします。
具体的には、アイテム入手用関数(SUCK_FUNC)とアイテムドロップ用関数(DROP_FUNC)を直接指定できるようにします。
プログラム
インストール
プログラム名「bb」としてインストールする。
> pastebin get pCY3K7vs bb
ソースコード
プログラムの解説
設定項目(config)
アイテム入手用関数(SUCK_FUNC)とアイテムドロップ用関数(DROP_FUNC)直接指定します。
デフォルトは、以下のとおり。つまり、鉱石ブロック用チェストは上、ドロップ用チェスとは下です。
関数を直接指定するのですから、turtle.suckUp()
のように末尾に「()」をつけてはダメです。つけてしまうと、その関数を実行してしまいますから。「()」をはずして関数名を指定してください(詳細はこちらを参照のこと)。
SUCK_FUNC = turtle.suckUp DROP_FUNC = turtle.dropDown
メイン(main)部分
print("Start: fortune BB") while suckBlock() do placeDig(turtle.getItemCount(BLOCK_SLOT)) dropSeq() end print("Finished: fuel ",turtle.getFuelLevel())
- 最初にプログラムスタートするよ!と宣言
- まず上のチェストから鉱石ブロックを入手(suckBlock())
- 手に入れた鉱石ブロックの数だけ、ブロック設置&フォーチュン破壊
- 入手した素材をアイテム用チェストにドロップ
- 上のチェストから鉱石ブロックを入手できなかったら、whileループを抜けて、終了。
- 最後にプログラム終了宣言。念のため燃料の残量も表示。
自分で定義した関数
suckBlock()
チェストから1スタックのアイテムを入手する関数で、入手に成功したらtrue、失敗したらfalseを返します。このtrue/falseで、メイン部分のwhileループを制御します。
なお前回のプログラムとの相違は、すでにインベントリ内のBLOCK_SLOTにアイテムがあるときには、すでに入手済みということで強制的にtrueを返すようにしています。
waitForEnoughFuel(minLevel, slot)
引数slotの燃料アイテムを補給した上で、最小燃料値minLevelに満たないのなら、さらなる燃料アイテムの挿入を待つ関数です。この関数のポイントは以下のとおり。
- 現在燃料値を一時的に保存しておく変数qty
- 関数内でローカル関数refuel()を定義して見やすさを重視。
- 指定スロットの燃料補給&変数qtyに現在の燃料値を保存
- 返値としてqtyの値を返すようにすることで、whileループの条件式として使えるように
- 現在の燃料値が最低値より多くなるまでwhileループを繰り返す
- インベントリ内容が変化するまで待つ
os.pullEvent("turtle_inventory")
を使用。 - sleep(1)は、os.pullEvent()が過敏に反応するを防ぐためのウェイト。
- インベントリ内容が変化するまで待つ
placeDig(count)
関数内の最初でwaitForEnoughFuel()を使うことにより、ブロック設置&破壊を開始する前に必要燃料を確保できるようになった。
そのため、前回のようにassert()関数を使ってプログラムを強制停止する必要がなくなった。 シンプル!
dropSeq()
基本的には、スロット1から16まで順にアイテムをドロップしていくのだけど、 途中でドロップ関数の実行に失敗(たとえばそのスロットにはアイテムがないのでドロップできないなど)したら、forループを抜けて、この関数を終了する。
これで、前のほうのスロットからアイテムを順に落としていき、空スロットにきたらもうそれ以上は落とさないという処理が完成。
なお注意しないといけないのは、この関数は所持アイテムは前のほうのスロットから順に詰まっているという前提を元にしていること。 たとえば、選択スロットを1(turtle.select(1))にしたまま、ひたすらアイテムを入手したときがこれにあたる。
仮に、選択スロットを次々と切り替えてアイテムを入手することで、アイテムが入っているスロットが飛び飛びになっていたら、この関数は破綻する。要注意。
おわりに
フォーチュン付きブロックブレイカーは、これでひとまず完成とします。
ぶっちゃけうちの環境だと、たまにしか使わないんですよね。ブロックブレイカー。
次回は、ブロックブレイカーつながりで、黒曜石生成プログラムとか丸石生成プログラムあたりを考えています。お楽しみに。