[Piet入門編]Piet入門2
どもです。
時間かかると言った割には早く書き上げることができました()
前回、Pietの概説と、色と命令の関係を説明しました。
今回は、Piet入門編の2回目です。
本日のメニューはこちら
目次入れるとわかりやすくていいですね。(自画自賛)
Pietの移動ルール
今回はPietインタプリタの移動ルールについて説明します。
Piet用語:カラーブロック
説明に入る前に、移動ルールに関するPiet用語「カラーブロック」の説明をします。
カラーブロックとは、同色のコーデルのかたまりのことです。
ここでいう「かたまり」とは「4連結1」、つまり、辺同士で繋がっているものです。
頂点が接触しているだけでは、同一のカラーブロックにはなりません。
たとえば、
この図には以下の4つのカラーブロックがあります。
- 右上の横一文字の領域(ピンク色)
- 右下の縦一文字領域(水色)
- 左上のL字の領域(ピンク色)
- 右下の長方形領域(ピンク色)
最初の2つはわかりやすいと思いますが、後の2つの領域もそれぞれ独立したカラーブロックです。
後の2つの領域は角で接触していますが、角だけで接触している場合は別のカラーブロックとして考えます。
同様に考えると、以下の図には2つのカラーブロックがあることもわかります。
ちなみに、白色のかたまりはカラーブロックとは呼びません。
移動に関するパラメータ
カラーブロックについて説明したところで、
ここからはPietの移動ルールに関係する
2つのパラメータDP、CCについて説明します。
パラメータその1:DP
まず一つ目のパラメータはDP(Direction Pointer)です。
これは、Pietインタプリタの進行方向を表します。
DPのとる値は、「左」、「下」、「右」、「上」の4つです。
パラメータその2:CC
次に二つ目のパラメータ、CC(Codel Chooser)です。
これは、今の時点では説明が難しいのですが、
Pietインタプリタがカラーブロックのどこから出ていくかを決めます。
CCのとる値は、「左」、「右」の2つです。
これは、画像上での「左」、「右」ではなく、
DP方向を「前」とした時に、「左」か「右」か、という意味合いとなります。
DPとCCのイメージ
以上2つのパラメータですが、特にCCがややこしいです。
そこで私は「車に乗った人」というイメージで考えています。
つまり、
- DP : 画像の上を走る「車」
- CC : 車の「運転手の見ている向き」
というイメージです。
たとえば、DP=「右」、CC=「左」の場合の
イメージを絵で描くとこんな感じです。
なんだかファンシーですね。
青いホームベース型のものが「車」を表しています。
尖っている方向が進行方向(=DPの方向)を表します。
また、中央の丸が運転手の頭を上から見た様子を表しています。
よく見ると鼻がついていて、運転手の見ている方向がわかります。
(この例では、上方向を向いています。)
CC=「左」ではありますが、運転手は「上」方向を見ています。
その理由は次の通りです。
車の進行方向(=DP方向)は「右」であり、運転手にとってはこちらが前です。
それに対し、運転手の見ている方向(=CC)が「左」であるので、
結局運転手は画像の「上」方向を向いていることになります。
他にもいくつか例を挙げておきます。
DP、CC、運転手の顔の向き。この3つの関係を確認してみて下さい。
Pietの移動ルール解説!
ではいよいよ具体的な説明をします。
初期状態
まず、Pietインタプリタは、画像の左上の角のコーデルから出発します。
パラメータの初期状態は次の通りです。
- DP=「右」
- CC=「左」
つまり、Pietインタプリタは、画像の左上コーデルから左に出発します。
移動ルール1:カラーブロック内を進む場合
まず、Pietインタプリタがカラーブロックに入った時の移動ルールを説明します。
移動ルールは次の通りです。
- カラーブロックのうち、最もDP方向側にある「辺」を探す。
- 見つけた「辺」のうち、DP方向に対してCC方向の「端点」を探す。
- 見つけた「端点」から、DP方向に1コーデル移動する。(カラーブロックから抜ける)
- もし「端点」から移動できない場合は、CCを反転し、再度1~3を実行する。
- それでももし「端点」から移動できない場合は、DPを時計回りに90°回転し、再度1~3を実行する。
- それでもなお「端点」から移動できない場合は、4と5を交互に繰り返す。
- 4と5を4セット繰り返してしまったらプログラムを停止する。
ね?簡単でしょ?
まぁ、そんなわけないのは私もよくわかっているので、
解説していきますだ。
さて、このフローは大きく2つに分けることができます。
- 基本的な処理(ステップ1〜3)
- 例外的な処理(ステップ4〜7)
ステップ1〜3は基本的な処理です。
基本的にはステップ1〜3のみで移動が完結します。
一方で、ステップ4〜7は例外的な処理です。
ステップ1〜3を実行した結果、Pietインタプリタが先に進めないときに実行します。
今回はまず、基本的な処理であるステップ1〜3を説明したいと思います。
ステップ1:DP方向の「辺」を探索する
早速ですが、難解ポイントその1です。
おそらくなんとなく言っていることはわかると思うのですが、
ここは正確に理解する必要があります。
ここで使う移動パラメータはDPだけです。
このステップでは、いま居るカラーブロックのみに着目し、
カラーブロック内の最もDP方向にあるコーデルを全て探します。
それが探索すべき「辺」です。
たとえば次のPietソースコード画像を考えます。しれっと車も待機しています。
今の状態を整理します。
- Pietインタプリタの位置:「明るい赤」カラーブロックの左上
- DP:右
- CC:左
このとき、探索すべき「辺」とは、
最もDP方向にある(つまり、最も右にある)、次の3コーデルです。
また、別の例も考えてみます。
今の状態を整理します。
- Pietインタプリタの位置:「明るい青」カラーブロックの上辺
- DP:下
- CC:右
このとき、探索すべき「辺」とは、
最もDP方向にある(つまり、最も下にある)、次の3コーデルです。
『「辺」を探しているのに白コーデルで分離されているけどいいのか』
と思われるかもしれませんが、「辺」の探索方法は、あくまで、
「同じカラーブロックの中から、最もDP方向にあるコーデルを全て探す」ことです。
その条件を満たすコーデルは、全て「辺」のひとつです。
「辺」と言うのは、あくまで説明のために便宜上つけた名前です。
また、
『PietインタプリタがDP方向に直進したら右端のくぼみに入るため、
左の2つの図のようにはならないのではないか』と思われるかもしれません。
しかし、このステップで行なっているのは、
DP方向に最も離れた場所を見つけることであり、
DP方向に直進することではありません。
言い換えれば、Pietインタプリタは
カラーブロックの形状全体を見ているのであって、
真正面だけ見ているわけではないのです。
もう一つ例です。
今の状態を整理します。
- Pietインタプリタの位置:「明るいマゼンタ」カラーブロックの右辺
- DP:左
- CC:左
このとき、探索すべき「辺」はどこでしょうか?
答えは次の1コーデルだけです。
形状が複雑ですが、「辺」の探索手順、すなわち、
「同じカラーブロックの中から、最もDP方向にあるコーデルを探す」
に忠実に従うと、この1コーデルのみが「辺」に該当します。
なお、以上はあくまで、カラーブロック内でのPietインタプリタの挙動であり、
白色領域内ではPietインタプリタの挙動が変わります。
白色領域については次回以降に説明します。
ステップ2:「辺」の中からCC方向の「端点」を探す
「辺」が見つかったら次は「端点」を探します。
「辺」が正しく見つけられれば、このステップは簡単です。
この段階で使う移動パラメータはCCだけです。
ここでは、先ほど見つけた「辺」のうち、
「DP方向に対するCC方向」(=運転手の見ている方向)の端を探し、
そのコーデルを「端点」とします。
たとえば例1の場合は、運転手が上を見ていたので、
端点はここです。
例2だと、運転手は左を見ていましたので、
端点は次の位置になります。
例3は、そもそも「辺」に含まれるコーデルが1つしかないので、
問答無用で次の位置が端点です。
ステップ3:カラーブロック脱出
Pietインタプリタは、先ほど選ばれた「端点」に到達すると、
カラーブロックからの脱出を試みます。
ここでは移動パラメータのDPのみを使います。
脱出する際には、「端点」からDP方向に1コーデル進みます。
首尾よく脱出できた場合、
Pietインタプリタが異なるカラーブロックに進入するため、
色の変化が生じますので、命令が実行されます。
たとえば例1の場合は、
明るさ変化2、色味変化2でnot命令が実行されます。
例2の場合は、明るさ変化0、色味変化2でdiv命令と解釈されます。
例3では、明るさ変化0、色味変化3でgt命令となります。
カラーブロックを脱出したPietインタプリタは、
多くの場合、また別のカラーブロックに入ります。
次のカラーブロックでも上記ステップ1〜3を繰り返して、
次々に命令を実行していくのです。
次回予告
次回は今回説明できなかった「例外的な処理」であるステップ4〜7を中心に解説します。
あわせて、黒コーデルや画像フチにおけるPietインタプリタの挙動、
Pietインタプリタを停止する方法についても、次回解説したいと思います。
おわりに
前回は完全にモチベ不足で更新が遅れましたが、
今回はなぜかモチベが回復して、ほぼ翌日更新に漕ぎ着けました。
なんということでしょう!読者に対する裏切りですよ、これは!
まあ今回の場合は、良い方に裏切ったのでいいかもしれませんが。
前回の予告通り、やはり移動ルールの解説は、
2部構成または3部構成になりそうです。
結構重たいですが、Piet理解の要なので、
次回もしっかり書いていこうと思います。
じゃ、今回はこの辺で。
では。