はじめに
前回の、
クロージャとコルーチン(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")
ソースコード
- 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: 関数初期化(関数生成)と初期化したことを示すメッセージ(このプログラムを実行したことを示すため)。