Minecraftとタートルと僕スマートフォン用の表示で見るMinecraftとタートルと僕PCゲームMinecraftのMOD「ComputerCraft」の情報を集めたニッチなブログです。こちらのページは更新が滞っており、情報が古くなりつつあります。新しいCC情報サイトをはじめましたので、もしよければご参照ください。今後ともよろしくお願い申し上げます。APIはじめにまたまた更新が遅くなりましたが、前回の記事を元に実際のコードを示します。前々回の記事では、ルールベースプログラミングの基本的な考え方を紹介しました。指定した範囲内の床ブロックを選択スロットと比較し、異なっていたら床ブロックを貼り換えるという、「床張り替えプログラム」の作成をめざし、複数のルールを考え、そのコードを示しました。今回は、このプログラムを実現するソースコード全体を紹介します。簡単に言うと、前回の記事で紹介したルールコードを中心として、その前後にこまごまとした処理を追加しただけです。ルール(タスク)の追加」→「メイン部分(プログラム初期化処理や実際の処理)」となっているので順番に解説します。設定項目このプログラムを実行するときには、以下のように引数を与えて実行することを基本とします。引数なしでプログラムを実行するとこの値をデフォルト値として使います。以下のような6つのタスクを追加することで、プログラムが動きます。したがって実行されるタスクが一つだけ選ばれることです。本システムに置ける競合解消戦略は以下のとおりです。基本的には以下のように、タスク作成時に名前と同時に優先度も指定します。タスク名「harikae」を優先度-1として作成する。ai:addTask('harikae',-1)タスクが実行可能になる条件をしっかりと記述し、また複数のタスクが同時に実行可能になったとしても正しいタスクが選ばれるよう適切に優先度を指定することが重要です。優先度については、絶対に実行(発火)してほしいタスクに高めの優先度(値が低いほど優先度が高いことに注意)を指定しておくことがポイントです。メイン部分まず最初にプログラム実行時に指定する引数の処理を行っています。引数の数が0のときには、奥行き・幅としてMAX_DEPTH・MAX_WIDTHの値をそのまま使います。引数が2個の時はそれは奥行き・幅の値であるとしてそれぞれ上記2つの変数に値を代入します。引数の数がそれ以外の時はエラーとします。次に実際の推論エンジンを実行する前に、実行履歴の表示の為にログファイルを設定(書き込み用ファイルハンドルを作成)しています。ターンが進むにつれて、どのような推論を行い、どのようなタスクを実行しているのかを細かく表示していくとなると、画面にログを表示するだけではどんどんスクロールしてしまい内容を追えなくなってしまいます。ログファイルをあらかじめ設定しておき、推論途中の様々な情報をログファイルに書き込むことにします。最後に推論エンジンの記述です。ai:generate(ターン数)というジェネレータ関数を使うことによって、汎用for文を回し推論を進めていきます。汎用for文のtask変数には実行されたタスクが、turn変数は現在のターンが入っています。汎用for文の内部でログを書き込んでいるのがポイントです。ai.runable_tasks変数には現在実行可能なタスク一覧が入っているので、それを直接参照しています。入っているのはタスクオブジェクトなので見やすくするために、ai:tasksToString(ai.runable_tasks)関数を使ってタスクオブジェクトの名前だけを取り出しています。このような情報をログとして書き出すことで、以下のようにログがまとめられます。各ターンで、どのようなタスクが実行可能か、そしてどのタスクが実行されたのか、そして現在のタートルの状況がまとめられています。fuel=4999(以下、つづく)自分が想定した順番どおりにタスクが実行されなかったら、タスクの実行条件をより具体的で厳しいものにしたりまたあるいは優先度の値を調整しましょう。まとめ紹介したコードはコメントも含めて100行を軽く超えていますが、内容的にはそこまで複雑なことをやっていません。基本的に、ルール(タスク)を追加するだけでプログラミングしています(実際には初期値の処理など細かい部分の追加がありますがw)。いえ今回の床張りのような簡単な作業ならば、手続き型で普通にプログラミングした方がシンプルであることは事実です。その点で、ルールベースプログラミングは、冗長で無駄の多いプログラミング手法であると言えるでしょう。現在の作業内容にさらに他の作業を付け加えたり、また複雑な条件で作業を切り替えたりなど、「後から機能を追加」する場合を考えてみましょう。手続き型プログラミングでは、全体との整合性を考えつつ既存のサブ関数に手を加える必要があります。場合によってはサブ関数を廃棄して全体の構成をリファクタリングする必要があるかもしれません。それに対してルールベースでは、ただ新しいタスクを付け加えるだけで良いのです。今回のプログラムは床張りでしたが、たとえばこれに正面にある山を削る機能を追加することを考えてみましょう。指定した範囲の凸部を削り凹部にフタをするという、本当の意味で「整地」プログラムの実現です。凸部を削るためのタスクは以下のような4つを追加すればよいでしょう。奥行きに余裕がない(つまり一番奥である)run():そのまま真下に降りてくるあとは、インベントリ内のアイテムがいっぱいのときにチェストを設置してブロックを詰め込むタスクや、松明を設置するタスクを追加しても良いかもしれませんね。様々な条件により作業内容を切り替えるような複雑なプログラミングをシンプルに記述する後から機能をどんどん追加していくといった点で一般的なプログラミング手法に比べて優位性があります。はてなブログPro「Minecraft」「ComputerCraft」について知りたいならば「お勧めコンテンツ」の『ComputerCraftとは』をご覧下さい。