どもです。
時間かかると言った割には早く書き上げることができました()
前回、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理解の要なので、
次回もしっかり書いていこうと思います。
じゃ、今回はこの辺で。
では。