Minecraftとタートルと僕

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

こちらのページは更新が滞っており、情報が古くなりつつあります。新しいCC情報サイトをはじめましたので、もしよければご参照ください。今後ともよろしくお願い申し上げます。

「百億のマインクラフトと千億のタートル」(https://hevo2.hatenablog.com/)

sleep実装からイベントを学ぶ(12)―ラジコンプログラム(2)

はじめに(動画を見て、来てくださった方へ)


上記の動画について、ラジコンプログラムの導入方法を知りたい方は2014/01/11の記事をどうぞ。


今回の記事はラジコンプログラムを解説していますが、完全な初心者には難しい内容となっています。しかし、CCの初心者だけど(他の)プログラミング経験はあるという人ならば、だいたい理解できると思います。

このプログラムは、本サイトのチュートリアルである「sleep実装からイベントを学ぶ」という連載のまとめとして作ったものですので、完全に理解するためには、このイベントに関する連載を(1)から読むことをお勧めします。

以下、ラジコンプログラムの詳細解説

今回は、イベントに関するこれまでの連載内容を総まとめしたラジコンプログラムについて詳細に解説します。適時、過去の記事にリンクを貼りますので、解説が良くわからない方はそちらも参照してください。

f:id:hevohevo:20140111082218p:plain:w300

コントローラ(送信)側のプログラム

pastebin: uJfWnku6

コントローラプログラムの解説

いつもどおり、最初に設定パラメータであるグローバル変数の解説をして、
次に、プログラムのMain部分の解説を通してプログラム全体の流れを掴み、
そしてそこで使われている個々の自家製関数について解説をしましょう。

このプログラムは、2014/01/08の記事で紹介した「モニタボタンによるタートル操作プログラム」が8割で、残りは、前回の記事で紹介した「Rednet APIを使った無線通信」機能でできています。

設定パラメータ

以下は全てグローバル変数です。

  • CtrlMonSide: コントロールボタンを表示するためのモニタをコンピュータのどの方向に隣接させるのか。「top」「bottom」「right」「left」「front」「back」、いずれでも。
  • ModemSide: 上記と同様に、Wireless Modemを装着している方向を指示。なお、コンピュータではなくタートルでこのプログラムを動かす場合、右側「rihgt」がModemの装着方向になります。
  • TurtleIDs: 命令を出す対象であるタートルのIDをTableを使って(配列のように)指定します。
    • 裏技として、65535を指定することでブロードキャストチャンネルになりますので、全てのチャンネル(タートル)に命令を出すことになります。たぶん。
  • Btns: ボタンの名前(モニタに表示するラベル)と、そのボタンを押すことで実行させる関数名を記載します。
    • モニタを1台しか使わない場合、表示領域が狭いので1個のボタンで表示できる文字数は5文字が限界となります。
    • 関数は、タートル側が実行できる関数であることがポイントです。言い換えると、タートル(受信)側のプログラムで新しい関数をあらかじめ定義しておけば、その関数を指定することもできます。

Main部分の解説

  • L107-109: コントローラ(ボタン表示用モニタ)の初期化
    • モニタにできるだけ詳細な文字を表示するため、「setTextScale(0.5)」を指定しています。
    • このモニタ操作に関する基本解説は、こちら
  • L112-113: 設定パラメータからのボタンの作成、およびモニタへのボタン表示
    • モニタの表示領域を縦4横3の12分割してボタンを作成しています。ボタン作成部分に関する詳細解説はこちら
  • L116:  Wireless Modemの初期化。Modemを使うときには必須です。
  • L119-127: メインループ。ボタン押下イベントを拾い、押されたボタンに対応する関数名(文字列)をメッセージとして各タートルに送信します。
    • 自家製関数である「pullPushButtonEvent()」が押下イベントを拾い、
    • 自家製関数である「send_msg()」がメッセージを送信します。

個々の関数の説明

  • 「send_msg()」以外の関数の説明は、こちら
  • L38-43: 「send_msg()」は、メッセージ(文字列)とタートルIDリスト(Table)を引数にとって、タートルたちにメッセージを送信します。
  • rednet.send()関数については、前回解説しました。

タートル(受信)側のプログラム

pastebin: 0ian5ggx

受信プログラムの解説

このプログラムは、ファイル名(プログラム名)を「startup」にすることによって、
再起動(CTRL+Rによるリブート)時に自動実行させることを想定しています。

設定パラメータ

  • ModemSide: Wireless Modemを装着している方向を指示。ワイヤレスタートル(Wireless Turtle)は右側が装着方向になっているので、これを変更する必要はないでしょう。
  • ControllerID: 値が「nil」のときには、コントローラのIDが何であっても、無制限で命令を受け付けます。コントローラを制限したいときにはそのIDを入力してください。

Main部分

自家製関数も1個しかないシンプルなプログラムなので、まとめて説明します。

  • L14: モデムの初期化
  • L16-18: 自家製関数「eval()」は、引数として与えられた文字列を関数として解釈し実行します。
    • このプログラムの心臓部分です。この関数でなぜそのようなことができるのかの解説はこちらですが、Lua言語の仕様も含めてさらに理解を深めたい方はこちらもどうぞ。
  • L20-23: メインループです。とめるときには「CTRL+T」でどうぞ。
    • L21: 自分のIDと同じIDのチャンネルを開き、メッセージが流れてきたらそれを返します。「rednet.receive()」については、こちら
    • L22: 「ControllerIDの値がnil」であったり、あるいは「ControllerIDの値が受信したメッセージの送信者IDと同じ」であるときに関数を実行します。

おわりに

このプログラムは、モニタボタン+無線通信によるラジコンというアイデアを元に作ったプロトタイププログラムです。いちいち動きをプログラミングせずとも、タートルを動きを見ながら直接操作できるところがポイントです。

実は、無線操作のアイデア自体はそれほど新しいものではなくて、YouTubeにあがっているものだけでも結構あります。しかしたいてい、右クリックでターミナル画面を開いてターミナル画面上で操作するものばかりでした。これだとタートルの動きが見えない!
そこでモニタ1台でボタン操作ですよ。モニタ1台でコンパクトだから、タートルの動きを見ながら操作できるし*1

このプログラムはとても役立ちます。ざっと思いつくだけでも以下のような活用方法が。

  • 黒曜石が大量にあるけどダイヤピッケルで1個ずつ掘るのは面倒。採掘タートルを使うにしてもわざわざプログラミングするのはなぁ・・・
  • 採掘タートルを大量に並べてトンネル採掘じゃい。数は力やで、面で壁を削るんじゃ。直接操作できるから細かな調整もできるしな。
  • 何台同時にタートルを動かせるのかわからないけれど、16×16台くらい用意すればすごいことになるんじゃね? クァーリーなんていらなかったんや(言いすぎ
  • スポナーに向かってMeleeタートルを特攻。「行け!タートル! ついでに松明で制圧もな」

とはいえ使っているうちに、機能面で不満が出てくるのではないでしょうか。なにせプロトタイプですから。

このプログラムのソースは完全公開していますし、内容も詳細に解説しています。
CCやLuaがよくわからない初心者でも、設定パラメータをいじって、ボタンのカスタマイズくらいはできますよね。それだけでも十分役立つはずです。

そしてCCプログラマのあなたへ!!
あなた好みに、機能を付け加え、応用し、使い倒してもいいのよ?
そしてそれを公開していただけると、僕も幸せ、他のみんなも幸せ。

つまり、
「このプログラムは自由に改造、公開、利用してかまいません」

  • 機能追加の希望があれば、気が向いたら、やるかも。
  • でも基本は、使うあなたが自由に改造してください。
  • プログラムをこんな風に改造したよ、応用したよ、と報告いただけると僕が喜びの舞を踊ります。

ということで、この長期間の連載、「sleep実装からイベントを学ぶ」を終わります。
次回は、どんな連載にしようかな。考え中・・・。

*1:検索が甘くて、もしかしたらすでに同じようなのがあるかもしれませんががが。