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

Minecraftとタートルと僕

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

クラフティタートルプログラミング チュートリアル(3)

チュートリアル Lua ComputerCraft Minecraft

昨晩のうちに公開するつもりが、思わず寝てしまいました。
出勤前に急いで投稿です。

自動クラフトプログラム再考

サトウキビ→砂糖のように、1個のアイテムをそのままクラフトするような不定形レシピ。
これを以降では、「1x1レシピ」と呼びます。

1x1レシピの代表例として、サトウキビ→砂糖があります。Modを入れている場合は他にもたくさん追加されるでしょう。

僕の環境で言うと、以下のようなものがあります。

  • 各種鉱石キビ1個 → 鉱石1個
  • 砂岩1個 → 砂4個
  • 砂利1個 → 火打石1個

多くのModを入れているので、どのModの追加レシピかは不確かですが・・・・・・。

前回のプログラムは、この中の一部のレシピで不具合を起こしてしまいます。

不具合1:「スタック数が64でないアイテムへクラフトする場合」

Useful_Milletで追加されるアイテムの中にEndermanMilletというキビがあります。
そして1x1クラフトによって、1個のEndermanMilletから1個のエンダーパールを作成できます。

しかし前回のプログラムを使い、スロット1に64個のEndermanMilletがある状態で「turtle.craft()」とすると、次の画像のようになってしまいます。
エンダーパールは16個しかスタックできないのが原因です。
そしてプログラムは、このままEndermanMillet48個とエンダーパール16個を下にドロップしてしまいます。クラフトが中途半端ですね。
f:id:hevohevo:20131205004901p:plain

不具合2:「1個から大量にクラフトできる場合」

また僕の環境のレシピだけど、砂岩1個から砂を4個作成することができます。これもまた「turtle.craft()」すると以下のようになります。
一度にクラフトできる数が制限されているため、材料の砂岩16個→完成品の砂64個というクラフトでとまってしまうのが原因です。
そして前回のプログラムは、このまま砂岩48個と砂64個をドロップしてしまいます。
f:id:hevohevo:20131205005504p:plain

プログラム修正の方針

この不具合に対応するために以下のような修正をプログラムに施しましょう。

  • 材料アイテムをチェストからとってきたらまずスロット1に格納する(MATERIAL_SLOT=1)
  • 完成品はスロット4に格納する(PRODUCT_SLOT=4)
  • プログラムの流れ
  1. スロット1に材料があるならクラフトする。完成品はスロット4に格納する。
  2. スロット4の完成品を下にドロップする。
  3. スロット1にまだ材料が残っているあいだ1~2を繰り返す。
  4. もし材料がなくなったら上のチェストからゲットする。

上のチェストから材料ゲットできなくなったらプログラムを終了する。

プログラム


プログラムの簡単な解説

プログラムを追っていくときには、プログラムのmain部分を中心に見ていくのがポイント。

  • config (L17,18)
    • 材料を置くスロット(MATERIAL_SLOT)と完成品スロット(PRODUCT_SLOT)を最初に設定。
  • メイン部分(L55-60)
    • L55,60: プログラムの最初と最後にスロット1から16までのアイテムを全部下にドロップしている
    • L56: このプログラムは、「getMaterials()」が「true」を返す間だけずっと繰り返し実行される
      • L32-41: ここで定義している「getMaterials() 」は上のチェストからアイテムを1スタック取って、MATERIAL_SLOTに格納する。成功ならtrue失敗したらfalseを返す。
      • L34: getItemCount(MATERIAL_SLOT)で、MATERIAL_SLOTが0であることを確認してからsuckUpしているが、このロジックは特に必要ないかもしれない。気休めということで。
    • L57: 「craft1x1()」は、このプログラムの最重要関数。
      • L45: MATERIAL_SLOTに確保している材料を使いきる(0以下になる)までwhileループし続ける。
      • L46: 「turtle.craft(0)」と引数0を与えると、実際にクラフトせずに、現在の材料でなにかクラフトできるかどうか調べることができる。ここでクラフトできないことがわかったらbreakでループを抜ける。
      • L47: 実際のcraftの前に、turtle.select(PRODUCT_SLOT)しておくことで、完成品を PRODUCT_SLOTに格納する。
      • L48-49: そして一度craft()したら、PRODUCT_SLOTの完成品を下にドロップすることで次のクラフトに備えている。
    • L58: ゲットした材料によるクラフトが終了したので、次の材料ゲットに備えてスロット1から4を空っぽにしている。

次回予告

次の改善は、以下の2本立てで行く予定です。

  1. 2x2 レシピの追加。たとえば金属の小さい粉をまとめるとか、焼石→焼石ブロックとか。
  2. 3x3ドーナツ型レシピの追加。たとえば、木の苗や葉っぱをPlantBallにまとめるレシピのことを、ここではこう呼ぶ。

あるいは、「minecraft 日本語Wiki」のComputerCraftページを見て思いついたのだけど、今のチュートリアルから脱線して、モニタ利用のチュートリアルを書くのもありかもしれません。
どちらにするかは、そのときの気分ということで。

それでは。