Minecraftとタートルと僕

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

クロージャとコルーチン(2)-クロージャでturtle APIを拡張してみた

はじめに

前回の、
クロージャとコルーチン(1)-状態遷移関数をつくってみた - Minecraftとタートルと僕
より少し間をあけてしまいましたが、
クロージャを使ったTurtleAPI拡張をご紹介します。

補足

なぜこのようにAPIを拡張したのか3行で説明

  • 標準のturtle.select(スロット番号)では、スロット番号を直接指定して選択スロットを変更する。
  • 標準のTurtleAPIでは、現在の選択スロット番号を知る方法がなく、「次のスロット」「前のスロット」のように相対的に選択スロットを変更する方法がない。
  • よって、現在の選択スロットを返す関数と、相対指定で選択スロットを変更する関数を作った。

Turtle APIの拡張

以下のプログラムは、標準のTurtleAPIに対して以下のような変更を行い、機能を拡張する。

turtle.select_org(<スロット番号>)

  • 標準の turtle.select()のバックアップ。

turtle.select(<スロット番号>)

  • ユーザーからみると元からある関数と機能的な違いはない
  • しかし内部処理としては、turtle.select()を実行するたびに、新しくその選択スロットを初期位置とした以下の3つの関数を新しく作成する。
    • turtle.getSelectedSlot()
    • turtle.selectNext()
    • turtle.selectPrev()

turtle.getSelectedSlot()

  • 引数なし
  • 返値1:現在の選択スロット番号を返す。

turtle.selectNext()

  • 選択スロットを次のスロットに移す。
  • 現在の選択スロットが1ならば2に移す。また、現在がスロット16ならばスロット1に移す。
  • 引数なし
  • 返値1: true/false

turtle.selectPrev()

  • 選択スロットを一つ前のスロットに移す。
  • 現在の選択スロットが2ならば1に移す。また、現在がスロット1ならばスロット16に移す。
  • 引数なし
  • 返値1: true/false

インストール方法・利用方法

ダウンロード

pastebinコマンドを使うなら以下のとおり。

> pastebin get 1dCNsXNi ex_turtle_select

利用方法

このプログラムを1度実行することでTurtle APIを書き換え、その変更はコンピュータを再起動するまで有効になる。
あるいは、自分のプログラムの先頭部分に本ソースコードを埋め込んでも良い。

利用方法1: 手動実行
> ex_turtle_select
利用方法2: 再起動するたびに自動実行

「rom/autorun/」フォルダ以下に、「ex_turtle_select」プログラムを設置する。

利用方法3:自分のプログラムに埋め込み

コピー&ペーストで自分のプログラムに本ソースコードを埋め込むか、あるいは以下のコードを埋め込む。

loadfile("ex_turtle_select")

ソースコード

http://pastebin.com/1dCNsXNi

  • L16: オリジナルのturtle.select()は、turtle.select_orgとして退避。
  • L18-31: turtle.select()を再定義。
    • turtle.select()を実行するたびに、クロージャを使った状態遷移関数funcを一つだけ作成。
    • このfuncを使って、getSelectedSlot()、selectNext()、selectPrev()を生成。
  • L19: オリジナルselect()を使って選択スロット変更。なおこのオリジナルは引数がおかしいときのエラー処理と、成功したというtrueしか返さない(falseは無し)。そのため、L30でtrueのみ返している。
  • L21-24: 関数funcは現在の選択スロット"slot"を「上位値」として保持、func()を実行するたびに"slot"の値を変更する。
    • この関数が返す値は、1~16までの値をとり循環する(16の次は1、1の前は16)。
    • func(x)において引数xは変位量。0なら現在の選択スロット、正ならその値だけプラス、負ならマイナスした値を返す。
  • L26,27,28: getSelectedSlot()、selectNext()、selectPrev()はこの状態遷移関数func(x)を内部的に使用して選択スロットを実際に変更するラッパー。
  • L32,33: 関数初期化(関数生成)と初期化したことを示すメッセージ(このプログラムを実行したことを示すため)。