Minecraftとタートルと僕スマートフォン用の表示で見るMinecraftとタートルと僕PCゲームMinecraftのMOD「ComputerCraft」の情報を集めたニッチなブログです。こちらのページは更新が滞っており、情報が古くなりつつあります。新しいCC情報サイトをはじめましたので、もしよければご参照ください。今後ともよろしくお願い申し上げます。(5)はじめにそれでは、お待ちかねの整地プログラムです。今回は、プログラム実行時のパラメータとして、奥行き・幅・高さ(Depth/Width/Height)を指定することで、その範囲内を掘るというプログラムを実装します。前回検討した、surelyFwd()やsurelyUp()を使っていく予定です。現在の設置場所を基準高度と考えたとき、それよりも上側を「切土」するアルゴリズムはいろいろ考えられます。最初に思いつくのが、最初からインストールしてあるexcavateプログラム形式の応用ですね。最初に奥行き・幅のパラメータを使ってその範囲の平面を整地する関数を作る。この関数を、指定された高さパラメータの分だけ、下から上へ(総合的に考えると上から下への方が良いかもしれませんが)繰り返すというアルゴリズムです。このアルゴリズムを使ってもいいのですが、この連載では別のアルゴリズムを使います。それは100%僕の好みです。うそですw実は今後の整地プログラムの改造、機能追加のことを考えると、これから説明するアルゴリズムの方が都合が良いからです。少々複雑になりますが、できるだけわかりやすく説明するのでお付き合いください。縦方向に削るアルゴリズム簡単に言うと、縦→奥行き→幅の順番に整地するプログラムです。surelyFwd()で1歩前進。surelyUp()で真上に掘り進める。指定された高さまで来たら、surelyFwd()で一歩前進するその位置から真下へ掘り進め、最初の高さまできたらストップこれを1つのセットと考えます。この1セットで、縦方向のブロックを2山分だけ掘ることができます。これを(surelyFwd()→上→surelyFwd()→下)→(surelyFwd()→上→surelyFwd()→下)・・・と繰り返すことで、まずは指定した奥行きまで掘ってしまいます。奥まで行ったら右(左)方向に折り返し戻ってきて、・・・という繰り返しで、指定した領域内を掘り進めるわけです。組み込む関数を検討する基本となる、(surelyFwd()→上→surelyFwd()→下)という一連の挙動の中で、(上→surelyFwd()→下)という部分をseichiTwoStep()という関数にして実行することにしましょう。毎回2つの山を掘ることになるので、指定した奥行きパラメータが奇数のときに困ってしまいます。そのまま素直に繰り返すと、範囲からはみ出してしまいますよね。そこで、(上を掘って→そのまま下に降りてくる)という1山だけ掘る関数も作ってしまいましょう。こちらは、seichiOneStep()という名前にしましょう。奥行きの長さをできるだけseichiTwoStep()で消化し、あまりが1のときにseichiOneStep()を使用しましょう。このあたりの細かい計算は、seichiOneLine()という関数を使ってまとめてしまいます。ソースコードhttp://pastebin.com/PpMRBU9p簡単な解説いつものようにソースコードを上から順に、設定項目(config)、関数定義(functions)、メイン部分(main)と見ていきましょう。configグローバル変数として、奥行き(DEPTH)、幅(WIDTH)、高さ(HEIGHT)という変数を使います。デフォルト値として値があらかじめ設定してありますが、このデフォルト値は、このプログラムをパラメータ指定無しで実行したときに使います。毎回パラメータを入力するのめんどくさいという方はこの値を書き換えてください。functionssurely系の関数は前回までに全て説明済みですので問題ありませんね?seichiTwoStep()指定された高度まで上へ掘り進み、1歩前進、最初の高さまで下へ掘り進む2つの山を掘ることになります。seichiOneStep()指定された高度まで上へ掘り進み、そのまま最初の高さまで降りてくる1つの山を掘ることになります。seichiOneLine()奥行き(DEPTH)分を、できるだけseichiTwoStep()で掘っていき、1山余ったらseichiOneStep()で掘ります。1列分を掘ることになります。countAllItems()現在のインベントリ内のアイテム数を数えます。プログラム実行完了後に、「○○個のブロックを入手しました」と表示するために使う関数です。mainパラメータチェックまず最初に、プログラム実行時のパラメータの処理を行っています。実行時の引数が3個のときは、その値をそれぞれ数字変換して、DEPTH/WIDTH/HEIGHTに代入します。引数無しのときには、ソースコード冒頭のデフォルト値をそのまま使います。以下は、変数にデフォルト値を指定するときの決まり文句です。仮に、args[1]すなわち第1引数が文字など不正な引数だったら、tonumber(args[1])はnilを返すので、結果として、DEPTHのデフォルト値を使うことになります。DEPTH燃料チェック掘る範囲がわかっているのですから、あらかじめ必要燃料を計算して、現在の燃料で足りないときにエラーで停止するようにしています。最後にいくつブロックを入手したかを表示するために、現在のブロック所持数を記憶しておく。1歩前進L118-130:基本的に、1列の整地seichiOneLine()を幅の値だけ繰り返す折り返しの計算は、現在の横方向位置が奇数か偶数かで行う。まとめアルゴリズムさえ理解できれば、比較的理解しやすいプログラムだと思います。実行しているといくつか不満点も出てくるのではないでしょうか。次回以降、このプログラムを改造・機能追加していく予定です。前回の最後に、以下のような課題を挙げました。はてなブログPro「Minecraft」「ComputerCraft」について知りたいならば「お勧めコンテンツ」の『ComputerCraftとは』をご覧下さい。