百億のマインクラフトと千億のタートル

つまり、マイクラワールド1つあたりタートルが10匹生息しているわけですね。

わしのインベントリは16スロットまであるぞ

はじめに

hevo2.hatenablog.com

前回までに床ブロック敷設プログラムを改造してきましたが、 実はあえて、致命的な弱点に触れていなかったんですよね。

・・・これ、タートルの1スロットの容量である64個までしかブロックを敷設できないんです。

つまり、

> yuka4 64

より大きな数は無理なんですね。 しかもこの実行では、片道64歩分だけ敷設して、復路は何もせず帰ってきちゃいます。

タートルはインベントリを16スロットも持っているのですから、これらをうまく活用したいものです。

タートルのインベントリについての基礎知識

まずはタートルのインベントリに注目しましょう。

f:id:hevohevo:20191009142626p:plain
タートルのインベントリ

タートルのインベントリには16個のスロットがありそれぞれに番号がついています。最初タートルは一番左上のスロット番号1に注目しています。スロット1が少しだけ太い枠で囲まれているのがその証になります。

このようなタートルが注目しているスロットを「選択スロット」と呼びます。タートルがブロックを採掘したりブロックを設置するときは原則としてこの選択スロットを使います。1

タートルが自分のインベントリを操作する関数はたくさん用意されているのですが、今回はその中でもよく使う関数を抜粋して紹介しましょう。

サンプルプログラム1

以下が今回のサンプルプログラム「countSlots.lua」になります。

これは、タートルがスロット1から16まで順に選択スロットを変えていき、そのスロットにあるアイテムの個数を順に表示するプログラムです。

それではこのサンプルプログラムを解説しましょう。

まずはプログラム中の2つの新しい関数を紹介します。

関数名 機能
turtle.select(slotNum) 選択スロットを、指定したスロット番号slotNumに変更する。
turtle.getItemCount(slotNum) 指定したスロット番号slotNumにあるアイテムの個数を返す。なお、スロット番号を省略したら選択スロットのアイテム個数を返す。

プログラムの基本的な構造は、2行目のfor slot=1,16 doから6行目のendで挟んだ部分を、カウンター変数slotの値を1から16まで順に増やしながら、合計16回繰り返すf形になります。

つまり以下のように、変数slotが1から16まで変化しながら、16回繰り返すわけですね。

  • 変数slotが1: 選択スロットを1にして(3行目)、その選択スロットのアイテム個数を変数kosuuに代入(4行目)、その個数を画面表示(5行目)
  • 変数slotが2: 選択スロットを2にして(3行目)、その選択スロットのアイテム個数を変数kosuuに代入(4行目)、その個数を画面表示(5行目)
  • 変数slotが3: 選択スロットを3にして(3行目)、その選択スロットのアイテム個数を変数kosuuに代入(4行目)、その個数を画面表示(5行目)
  • 変数slotが16: 選択スロットを16にして(3行目)、その選択スロットのアイテム個数を変数kosuuに代入(4行目)、その個数を画面表示(5行目)

さあこれでこれら2つのインベントリ操作系関数の使い方が理解できましたね。それでは、実際に「アイテムが入っているスロットを選択するプログラム」を作りましょう。これまで学んできたfor文とif文を組み合わせて使います。

サンプルプログラム2

以下が、アイテムが入っているスロットを選択するプログラムである「selectItem.lua」です。

あたらしい記述が二つありますので順に解説しましょう。

比較演算子とは

まず注目して欲しいのは、5行目にあるif文の「条件式」です。 前回の記事では、if 「条件式」 then 「やって欲しいこと」 endというif文の基本構造を紹介し、「条件式」に「真(true)」または「偽(false)」が入るのだという解説をしました。

今回は条件式として(kosuu > 0)を記述しています。

「>」という不等号は、数学の世界では「5 > 3」のように使って、「5は3よりも大きい」という事実を表現するわけですが、プログラムの世界では違います。

現在使っているLua言語では、「A > B」と記述することで「AはBよりも大きいかどうかをチェック」します。もしこの記述(A > B)が正しいならば真(true)を返し、この記述が間違っていれば偽(false)を返します。

このように数学の世界とプログラムの世界で「>」の挙動が違うので注意しましょう。Lua言語では「>」のような記号を「比較演算子」(左側と右側を比較して演算する記号、の意味)と呼びます。

この不等号以外にも比較演算子はあります。他の比較演算子を知りたい方はココをクリック

比較演算子 機能 使用例(と返す値)
> 左が右より大きいなら真(小さいなら偽)を返す 3 > 1 (→true
< 右が左より大きいなら真(小さいなら偽)を返す 3 < 1 (→false
>= 左が右以上なら真(以下なら偽)を返す 3 >= 1 (→true
<= 右が左以上なら真(以下なら偽)を返す 3 <= 1 (→false
== 左と右の値が同じならば真(違うなら偽)を返す 4 == 2 (→false
~= 左と右の値が違うならば真(同じなら偽)を返す 4 ~= 2 (→false

よく間違えるのが比較演算子「==」です。「=」だと変数に代入する記号(代入演算子)になるのでご注意ください。

比較演算子を使ったkosuu > 0という式は、変数kosuuが0より大きければ真(true)を返し、0より小さければ偽(false)を返します。

つまり今回は、「kosuu」の値が0より大きければ(つまり、アイテム個数が1個以上)ならば、then 〜 endの中を処理することになります。

break文とは

もう一つの新しい記述として7行目のbreakがあります。 この記述をコンピュータが処理するとfor文が処理途中であってもいきなりそのforの処理をやめてforの外に抜け出す(ブレークする)という挙動になります。

よってこのプログラムの挙動を詳細に追うと

  • 変数slotが1: スロット1のアイテム個数を変数kosuuに代入(3行目)、その個数が0より大きいかチェック(5行目)
  • 変数slotが2: スロット2のアイテム個数を変数kosuuに代入(3行目)、その個数が0より大きいかチェック(5行目)
  • 変数slotが3: スロット3のアイテム個数を変数kosuuに代入(3行目)、その個数が0より大きいかチェック(5行目)
  • 変数slotが16: スロット16のアイテム個数を変数kosuuに代入(3行目)、その個数が0より大きいかチェック(5行目)

という動作をするのですが、それぞれのスロットの個数チェック時(5行目)に0より大きいことがわかったら、タートルの選択スロットをそのスロットに変えた後、いきなりforの処理を抜けて外に飛び出します。 たとえslotが1であろうと10であろうと、ifの処理によって強制的forの処理を中断してforの外に飛び出すところがポイントです

選択スロットをそのスロットに変えてからforの外にブレークするので、このプログラムによって、「アイテムが入っているスロットを選択できる」わけなのです。

床ブロック敷設プログラムの改善版

それではこれまで学んだことを生かして、今回の課題である「yuka4」プログラムを改善し、以下のような「yuka5」プログラムを作りました。

元の「yuka4」プログラムとの変更点は2カ所です。

turtle.placeDown()というブロックを真下に設置する関数がありますが、その関数の実行直前に、これまで学んできた「アイテムを持っているスロットを選択する」処理を埋め込んでいます。

このturtle.placeDown()が2カ所あるので、埋め込んだのも2カ所ですね。

さあこれでインベントリの全てのスロットを使ってブロックを設置できるようになりました。16スロット全てに64個のブロックを入れておけば、合計1024個のブロックを設置できますね!


  1. ブロックを採掘する時にこのスロットが満タンだったり他のアイテムで埋まっている時には、その隣のスロットに入れようとします。逆にアイテムを設置しようとした時に、このスロットが空っぽだったり設置できないアイテムならば、設置に失敗します。