Minecraftとタートルと僕

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

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

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

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

はじめに


上記の動画についての概略を知りたい方は2014/01/11の記事をどうぞ。

f:id:hevohevo:20140111122827p:plain:w300

このラジコンプログラムを理解するために、今回は、前提知識であるCC無線通信を学びましょう。
無線通信について詳細な情報は全てCC非公式Wikiに書いてあります。詳しくはそちらをご覧ください。

無線通信の概要

Wireless ModemというパーツをつけたCCコンピュータ(タートル)は、電波の届く範囲で、
無線通信することができます。

無線通信のチャンネルは1-65535まで存在しており、好きなチャンネルにメッセージを流し放題・聞きたい放題となっています。
ただしRednet APIの仕様として、自分のIDと同じチャンネルを自分専用チャンネルとして使う(自分のIDが1なら、チャンネル1を優先して使う)ことになっています。またBROADCAST(ブロードキャスト、全CCコンピュータへの一斉通信)用のチャンネルとして、65535が予約されています*1

なお、コンピュータやタートルのIDを調べるには以下のコマンドが使えます(いえ別に、saveフォルダ開いて、「labels.txt」ファイルからそのコンピュータのIDを調べてもいいんですけどね)。

--プロンプトに入力するなら次のプログラム(コマンド)
> id

-- プログラム中で、自分のIDを調べるなら次の関数
os.getComputerID()


無線通信するためのAPIは、Rednet APIと、Peripheral APIがあります。

  • Rednet API: 有線・無線問わず通信系を司るAPIで、たいていのことはこちらを使えばOK。今回はこちらだけを説明します。ちなみに、MFR2のRedNet-Cableとは一切関係ない(まぎらわしいw)。
  • Peripheral API: Wireless Modemを直接操作するのでとても高機能。メッセージを送受信するチャンネルを自由に選ぶことができ、他のチャンネルを盗聴することだって可能*2。今回はこちらについては説明しません。

Rednet APIを使ったメッセージの送受信

WirelessModemの初期化

まず最初に、WirelessModemの装着方向を指定して利用できるようにします。
メッセージを送信する側も、受信する側も、必ず最初にこれを実行しなくてはなりません

-- 上に装着したWirelessModemを利用可能する
rednet.open("top")

メッセージ送信

以下の関数で、指定したチャンネルIDに「文字列」を送信します。
チャンネルIDがそのままそのIDを持つコンピュータ(タートル)の優先チャンネルなので、
結果として、指定したコンピュータIDに向かってメッセージを送信することになります。

rednet.send(チャンネルID, メッセージ文字列)
  • メッセージ送信に成功したらこの関数はtrueを返す。ただし注意したいのは、「送信」に成功であって、相手が受信したかどうかは保証されない。IPで言う、UDP/IPみたいなもの。
  • この関数には、もう一つ、省略可能な引数としてポートを開くまで待つかどうか(true/false)があるが、マルチユーザー環境以外では使わないので忘れてもいい*3

メッセージ受信

自分のIDと同じIDのチャンネルを監視し、メッセージ文字列が流れてきたら受信する。

rednet.receive(待ち時間)
  • 指定した待ち時間(秒)だけ、自分IDの(とBROADCAST用)チャンネルを監視する。待ち時間を省略したらずっと待ち続ける。
  • 返し値は以下のとおり
    • 第1返値: 送信者のID(数値)
    • 第2返値: メッセージ(文字列)
    • 第3返値: 自分と送信者間の距離(数値)
  • 例によって、coroutine.yieldをwrapしているので、「too long without yielding」エラーの発生は気にしなくて良い。

サンプルプログラム

とてもシンプルなので、実際試してみるのが一番ですよ。プログラムも短いから打ち込むのもそう大変じゃないし。
なお以下のプログラムは、(1)受信側プログラム(=受信待機)、(2)送信側プログラム(=メッセージ送信)の順に実行してください。順番を間違えないように。
また、受信者側のIDを「1」としています。WirelessModemの装着方向と合わせて、自分の環境に合わせ書き換えてください。

メッセージ受信側で動かすプログラム

rednet.open("top")

sender_id, message_str, distance = rednet.receive()
print(message_str)

メッセージ送信側で動かすプログラム

rednet.open("top")

rednet.send(1, "Hello!!")

次回のお話

「モニタボタンを使ったタートル操作プログラム」に、
今回説明したRednetAPIを使って、少し機能を付け加えることで、
「ラジコンプログラム」が完成します。

次回、「ラジコンプログラム詳細解説!!」 お楽しみに。

*1:GPS APIでGPS通信用に65534も予約されています。

*2:通信内容は素の文字列だし、チャンネルに鍵はかかっていないので好きなチャンネルの通信を見放題となっています。マルチユーザー環境でのセキュリティは全く考えられていません。

*3:マルチユーザー環境ではこの引数は必要なの? シングルでしかやったことないのでわかりません。誰か情報プリーズ。