はじめに
それでは回転式直下掘りプログラムを考えていきましょう。
最初にアイデアをそのままプログラムで書いたものを紹介。
つぎにそれを具体化します。
最後はこのプログラムの問題点をいくつか挙げて次回の課題としましょう。
全体の流れ
- まずは、燃料補給。
- 「一回転しつつ四方掘り→直下掘り→下移動」をセットにして考えて、これを延々と繰り返す。
- 岩盤に突き当たるなどして、上記回転堀りセットの実行に失敗したら、上に戻ってくる。
このような流れになります。
まず、メイン部分のプログラムを書きましょう。
-- main myRefuel() -- 燃料補給する自家製の関数 local depth = 0 while revolve() do -- 「回転掘り&直下堀り&下移動」する自家製の関数 depth = depth +1 -- 下移動したらその分だけdepthの値を増やす end backToHome(depth) -- 引数depthの値だけ上移動して戻ってくる自家製の関数
- 「myRefuel()」「revolve()」「backToHome()」という3つの自家製関数は、前述の全体の流れ1、2、3に対応しています。自家製関数の実装については後回し:P
- ローカル変数 depth に、いくつ下に移動したのかを保存します。初期値はもちろん0です。
- revolve()は、「回転して四方掘り&直下掘り&下移動」をまとめた関数です。この行動に成功したら真(true)を、失敗したら偽(false)を返すよう(今後)定義します。
- 真の反対は偽、偽の反対は真です。裏表の関係にある真/偽のことをboolean(ブーリアン)といいます。
- つまり、関数revolve()は実行の成功/失敗によってブーリアンを返します。
- 「while 条件式 do 実行部分 end」というループ文は、(1)条件式を確認。(2)条件式が真ならば実行部分を実行しまた(1)の条件式を確認……という繰り返し、偽ならば実行部分を飛ばして次に進む。というループ構文です。
- この条件式部分に関数を書いておくと、毎回その関数を実行してその返す真偽値で判断します。
- つまり、関数revolve()が成功(真)の間は、depthの値を1ずつ増やしていき、失敗(偽)になったら、次の処理部分に進んでいきます。
- revolve()成功 → depthを+1 → revolve()成功 → depthを+1 → …繰り返し… → revolve()失敗 → while文の次へ
- backToHome(depth) は、与えた引数depthの値だけ上に移動して元のスタート地点に戻ってくるという自家製関数です。
ね? メイン(main)部分は、とてもシンプルでしょ?
あとは、それぞれの自家製関数を定義してしまいましょう。
完成版
ソースコード解説(3つの自家製関数を定義)
- L7-10: myRefuel()関数の定義(引数も返値も使いません)。ただ燃料補給するだけ。
- 選択スロットを16番にして、スロット16にある(はずの)燃料アイテムを全て補給します。
- L12-21: revolve()関数の定義(ブーリアンを返します)。
- for文で4回繰り返すことで、4方向のブロックを掘る
- 下を掘って
- そして下に移動できたらtrue、できなかったらfalseを返値として返す。
- 最重要ポイントは、L20の、revolve()のreturn文です。
- return 文によって、関数の返値を設定することができます。
- 「turtle.down()」関数自体が、 成功/失敗によりtrue/falseを返すので、その値をそのまま関数revolve()の返値として用います。
- L23-27: backToHome()関数の定義(引数のみ使います)。
- 引数nをとり、for文でn回の「上昇」を繰り返します。
- なおここでのnは、ローカル変数として作成されるため、この関数backToHome()の中でしか利用できません。
- 変数のローカル/グローバルについての解説は以下を参照のこと
このプログラムの問題点
実際に試しているといくつか気になるところがあります。
燃料が足りないと面倒なことに
y=64から掘り始めるならば燃料は128程度で良いのですが、燃料補給を忘れていると大変なことになります。
たとえば、岩盤付近で燃料が切れて止まってしまうと、その回収にとても苦労します。
採掘を開始する前に燃料が足りているかどうか判断する機能を追加しましょう。
岩盤直通穴は危険
岩盤まで掘って戻ってきてくれるのは良いのですが、岩盤直通の穴をそのままにしているのはとても危険です。
特別な装備をしていない限り、落ちたら即死ですから(ええ即死でした)。
一時的に穴に蓋をしておくオプションもつけるようにしましょう。
次回はこのあたりの機能をプログラミングしてみましょう。