[今日のPiet]GridPietGenerator入門編1(無限ループを作る)
どもです。
前回までの、あまりの超大作(量的な意味で)に
疲れてしまったので、ちょっと趣向を変えます。
これまで紹介してきたGridPietGeneratorですが、
まともに説明していなかったので、今回からは
処理フローファイルの書き方の説明をしようかと思います。
とはいえ、体系的に説明してもつまらないので、
サンプルプログラムとして、ループを題材に取り上げようと思います。
無限ループを作ろう
まずはループの基本、悪名高き「無限ループ」を作ります。
処理フローファイルで無限ループを作るのは簡単です。
まず、お好きなテキストエディタを開きます。
次に、以下のプログラムをかきます。
:loop goto:loop
できました。
ね?簡単でしょう?
解説
まず大前提として。
処理フローファイルは半角スペース、タブ、または改行で区切られた命令の羅列です。
条件分岐を除いて、基本的にはファイルの初めから順番に命令を実行します。
処理フローファイルの命令は全部で18こあります。1
また、Pietのメモリはスタックと呼ばれる構造を持っています。(今更ですが・・・)
命令の中には、スタックに変化を与えるものもありますし、
スタックには影響を及ぼさないものもあります。
さて、これを踏まえて、先ほど書いたファイルを見てみます。
先ほど書いたファイルには、「:loop」と「goto:loop」の
2つの命令(と便宜上呼びます)が含まれていることがわかります。
まず、1つ目の:loop
の部分を「ラベル」と呼んでいます。
これは、プログラムのジャンプ先を表すものです。
色々ルールはありますが、ざっくり言えば、
コロン:
で始まる文字列はラベルです。
ジャンプ先以外の意味はないので、ラベルを書いてもスタックは変化しません。
次にgoto命令が来ています。
お察しの通り、これは無条件のジャンプ命令です。
gotoの直後にラベルを指定して、そのラベルに無条件でジャンプします。
今回の場合は、先ほど書いたラベル:loop
に無条件ジャンプさせています。
なお、goto命令を実行してもスタックは一切変化しません。
まとめると、先ほどのプログラムでは、
goto命令でラベル:loop
に戻る
を延々繰り返すため、無限ループができるのです。
命令解説
今日出てきた命令である、ラベルとgoto命令について説明します。
ラベル
書き方::ラベル名
入力:なし
スタック変化:なし
出力:なし
説明:ラベルを作るときは、コロン:
に続けて英数字またはアンダースコア_
を並べてください。
コロン:
の後ろの文字列が「ラベル名」です。
ただし、以下のルールがあります。
- ルール1:コロン
:
の後に、半角スペースなどの空白文字を入れてはいけません。 - ルール2:コロン
:
の直後の1文字は必ず英字にしてください。 2 - ルール3:同じラベルを複数回使ってはいけません。
goto命令
書き方:goto:ラベル名
入力:なし
スタック変化:なし
出力:なし
説明:指定したラベル名のラベルの位置に無条件でジャンプする。
コロン:
の前後に、半角スペースなどの空白文字を入れてはいけません。
Piet化してみる
ではGridPietGeneratorでPiet化してみます。
先ほどの処理フローファイルを適当な名前(ここでは"loop.txt")で保存します。
その上で、GridPietGeneratorを実行します。
お使いのOSでコマンド画面を立ち上げて(←この辺は調べてください。すみません・・・)
実行します。Windows風に書くなら次の通りです。
GridPietGenerator.exe loop.txt loop.ppm
Linux風に書くなら次のような感じでしょうか。
./GridPietGenerator loop.txt loop.ppm
これで生成した画像"loop.ppm"ができます。
以前も説明しましたが、ppmファイルはあまり一般的な画像形式ではないため、
OS標準のビューアではみられないかもしれません。
実装の都合でこのようになっており申し訳ないです。
私の手元でpngに変換して拡大すると、次のような画像が出てきます。
シンプルですね。
動作確認
さて、これをPietのインタプリタであるnpietでデバッグしてみます。
(npietも今度解説しないとなあ。。。)
npietがインストールされているとして、以下のように実行します。 (Linux風の表記ですが)
./npiet loop.ppm -tpic -tpf 30
tpicオプションは、デバッグ画像を出力するオプションです。
デバッグ画像は"npiet-trace.png"といった名前で出力されます。
(デバッグ画像ファイル名を指定するオプションはないようです。)
tpfオプションは、デバッグ画像の倍率を整数で指定するためのものです。
ここでは30倍にしています。
なお、npietはppm形式の画像に対応しています。
では実行します。
・・・
・・・
・・・
・・・
・・・
止まらん・・・
あぁ、無限ループだったわ(笑)
というジョークみたいなことをやらかした私のマネはしなくていいので、
すぐにcontrol-C(ctrl+C)で止めましょう。
さて、出力は次のようになります。
Pietは左上から出発するので、
下に見える四角形の黒線部分でループしているのだとわかります。
Pietのルールに則って丁寧に追えばわかるのですが、
この画像では時計回りにぐるぐる回り続けます。
なお、色々と色のマスがくっついており、所々命令も実行されていますが、
あくまでPietインタプリタを誘導して、
方向転換させるためだけに命令を実行させています。
Pietを方向転換させるだけでもメモリを使う必要が出てきます。
ですが、方向転換の際のメモリ使用は一時的なもので、
メモリの他の部分には影響を与えません。
つまり、一連の方向転換処理の前後を比較すると、
メモリの状態が保たれるようになっています。
こうした工夫によって、どんな状況でも自由自在に
Pietインタプリタの方向転換ができます。
メモリに影響しない方向転換は、
Piet画像生成自動化のポイントのひとつです。
最後に
・・・なんか、これで終わるとすごい怒られそうですね。
「えっ!無限ループなんか使えないやん。」ってな感じで。
ループの中で何か処理をさせるようなケースは次回解説します。
実は、無限ループでない方も、プログラム自体は書いたんですけどね。
ブログの方にまとめるのに労力がかかるみたいで、やはり気力との勝負になりがちです。
書く量を少なくしつつ、息長く続けていく方がいいのかな、
と思った今日この頃です。
最近その日の気分で「最後に」のコメント書いてるので、
方針ブレブレになっているかもしれませんが。。。
じゃ、今日はこのへんで。
では。