[Piet入門編]Piet入門1
どもです。
いよいよ今回からPietそのものの解説です。
何をいまさら
感がすごいですが、気にせず解説します。
Pietとは
そもそもPietとは、David Morgan-Mar氏が考案した難解プログラミング言語です。
特徴はご存知の通り、ソースコードが画像であることです。
この特徴は超印象的ですが、実は言語の種類としてはそこまで特殊なものではなく、
スタック志向プログラミング言語という分類になります。
(まぁ、スタック志向言語も、あまりポピュラーではありませんが。)
また、ソースコード画像には、さまざまな色ブロックが配置されていますが、
これらは次の役割を果たしています。
したがって、Pietのソースコード画像は、
「本来は文字(=プログラミング言語)で記述すべき内容を、色ブロックに置き換えて記述したもの」
と捉えることが出来ます。
スタック志向プログラミング言語
さて、Pietのベースとなる「スタック志向プログラミング言語」について簡単に説明します。
と言っても、過去記事で説明していますね。
ざっくりおさらいすると、メモリが「スタック」という構造を持つことが特徴です。
スタックのイメージは「底のついた筒状の入れ物」です。
この中に値を順次入れていくことができますが、
取り出すときは最後に入れたものからしか取り出せない、
というものでした。
詳細は、下記記事の「スタック」の項をご参照ください。
ymos-hobby-programing.hatenablog.com
なお、スタック志向プログラミング言語には、Ghostscript などがあります。
Ghostscriptは、昔ちょろっとだけ触ったことがありますが、
独特で興味深い言語だったなあという印象を持ちました。
はい。小並感。
Pietの色と命令
ここで、Pietの色と命令の関係を説明していきます。
コーデル(Codel)
その前にまず、Pietの用語をひとつ説明します。その後の説明に便利なので。
「コーデル(Codel)」とは、
Pietインタプリタにとっての「ピクセル(Pixel)」です。
堅苦しく言い換えると、コーデルとは、
Pietのソースコード画像の単位正方形のことです。
つまり、Pietインタプリタから見た、
サイズが11の正方形のことを指します。
なぜわざわざ「コーデル」という特別な名前を与えて
「ピクセル」と区別するかというと、
Pietのソースコードは拡大して表示することが多いからです。
拡大した時の1コーデルの1辺の長さは、必ずしも1ピクセルではありません。
たとえばいつぞやあげた無限ループのプログラム:
このプログラムの下辺中央付近には、
黒・ピンクの正方形が横向きに連結して配置されています。
これらの黒・ピンクそれぞれは1コーデルです。
したがって、このプログラム内では、これらの正方形より小さなサイズの四角形は現れません。
一方でこの画像をダウンロードして調べていただくとわかるのですが、
これら黒・ピンクの正方形の1辺の長さは、1ピクセルではありません。
30ピクセルのはずです。
もし1辺1ピクセルのまま掲載すると、
見えんですな。
「画像がどこにあるかわかりますか?」というレベルの小ささですね。
このように、
画像の一般的な画素単位である「ピクセル」と
Pietにとっての「画素単位」である「コーデル」を区別することで、
これらを混同しないようにしたのです。
Pietに使える色
さて、次は色の説明です。
なんとなく想像がつくかと思いますが、
Pietソースコードで命令を書くときに使える色は決まっています。
どんな色でも使えるのであれば、ルールが複雑になりそうですよね。
できなくはないと思いますが。
もとい、Pietの命令に使える色ですが、具体的には次の20色です。
表にはカラーコードも示しています。
明るい | 普通 | 暗い | |
---|---|---|---|
赤 | #FFC0C0 | #FF0000 | #C00000 |
黄 | #FFFFC0 | #FFFF00 | #C0C000 |
緑 | #C0FFC0 | #00FF00 | #00C000 |
シアン | #C0FFFF | #00FFFF | #00C0C0 |
青 | #C0C0FF | #0000FF | #0000C0 |
マゼンタ | #FFC0FF | #FF00FF | #C000C0 |
黒 | |||
白 |
命令を実行するにあたり、重要なのは
- 色味(Hue)
- 明るさ(Brightness)
の2つです。
「色味」とは、いわゆる「何色か」に相当するものです。
「赤」、「黄」、「緑」、「シアン」、「青」、「マゼンタ」の6種類あります。
「明るさ」は、文字通りですね。「明るい」、「普通」、「暗い」の3種類あります。
Pietの命令を解釈するには、「明るい・赤」、「暗い・緑」など、
「明るさ」と「色味」の組み合わせが重要になります。
Pietの命令
では、Pietの命令を見ていきます。
Pietの命令は、全部で17個あります。
以下、命令一覧表を示します。
明るさ変化0 | 明るさ変化1 | 明るさ変化2 | |
---|---|---|---|
色味変化0 | push プッシュ |
pop ポップ |
|
色味変化1 | add 加算 |
sub 減算 |
mul 乗算 |
色味変化2 | div 除算 |
mod 剰余算 |
not 否定 |
色味変化3 | gt 比較 |
- DP変更 |
- CC変更 |
色味変化4 | dup 複製 |
roll ロール |
inn 数値入力 |
色味変化5 | inc 文字入力 |
outn 数値出力 |
outc 文字出力 |
まず、黒文字の命令は、前回までの記事で見たことのある命令だと思います。
同じ名前の命令が、拙作の「GridPietGenerator」にも存在し、
しかも全く同じ処理をしています。
(というより、GridPietGeneratorの命令を、Pietに合わせたのですが。。。)
ここでは詳細の解説は割愛しますが、いずれもスタック内の値を操作する命令です。
そして、赤文字の命令は、今回初めて出てきました。
これらは、Pietインタプリタの進行方向を変化させるのに使う命令です。
これらは追々説明をすることにします。
命令の決定方法
次にPietの命令がどう決まるかです。
Pietを理解するポイントの一つですね。
Pietでは、Pietインタプリタが画像をスキャンしていく途中で、
通り道のコーデルの色が変化したとき、その色の「変化」に応じて命令が決まります。
したがって、色そのものと命令とは、対応していません。
実行される命令は、具体的には、
- 前後の色の「明るさ」の変化量
- 前後の色の「色味」の変化量
で決まります。
先ほどの命令表のフチにしれっと
「色味変化」「明るさ変化」と書いてあります。
それぞれの変化量の交差する場所の命令が実行されます。
なお、変化量を数えるときは、次の順序に沿って数えます。
- 色味:「赤」→「黄」→「緑」→「シアン」→「青」→「マゼンタ」→「赤」→・・・
- 明るさ:「明るい」→「普通」→「暗い」→「明るい」→・・・
「順序」とは言っていますが、「マゼンタ」まで行ったら再び「赤」に戻るなど、
循環していることに注意してください。
命令の決定方法の具体例
具体例を出します。
例1
まず次の画像を考えます。
Pietインタプリタが、この画像を左から右に移動する場合には、
どの命令が実行されるでしょうか。
この場合は、「明るい赤」から「明るい緑」への変化です。
まず、色味ですが、「赤」から「緑」まで、
「赤」→「黄」→「緑」と2段階で変化していくため、変化量は2です。
次に、明るさですが、「明るい」から「明るい」までの変化、
つまり、変化なしで、変化量は0です。
以上から、先ほどの表より、
「色味変化2」と「明るさ変化0」が交差する箇所の
割り算の命令「div」が実行されます。
例2
次に、以下の画像を考えてみます。
Pietインタプリタが、この画像を左から右に移動する場合を考えます。
この場合は、「普通のマゼンタ」から「明るいシアン」への変化です。
まず、色味ですが、「マゼンタ」から「シアン」まで、
「マゼンタ」→「赤」→「黄」→「緑」→「シアン」と4段階で変化していくため、
色味変化量は4です。
「マゼンタ」から「赤」に戻っていることに注意してください。
次に、明るさですが、「普通」から「明るい」まで、
「普通」→「暗い」→「明るい」と2段階で変化していくため、
明るさ変化量は2です。
こちらも「暗い」から「明るい」へと循環しています。
以上から、先ほどの表より、
「色味変化4」と「明るさ変化2」が交差する箇所の
数値入力の命令「inn」が実行されます。
例2 - 逆走した場合
なお、もしPietインタプリタが、今までの方向とは逆に、
この画像を右から左に通り抜けた場合はどうなるのでしょうか。
この場合は、「明るいシアン」から「普通のマゼンタ」への変化です。
今までと同様に考えて、
- 色味は「シアン」→「青」→「マゼンタ」の2段階変化
- 明るさは「明るい」→「普通」の1段階変化
なので、「色味変化2」と「明るさ変化1」の交差する箇所の
除算命令「mod」が実行されます。
このように、同じ色の組み合わせでも、逆走すると命令は変化します。
例3
以上の例でだいぶ慣れてきたのではないでしょうか。
以上の例のように、Pietの命令は、色の変化に関連づけられています。
色そのものには関係しないので、
同じ変化の仕方であれば、異なる色でも同じ命令を表現できます。
たとえば、以下の画像は全て同じ命令を表します。
いずれも、
左から右に移動する場合は「明るさ変化1」、「色味変化0」でpush命令、
右から左に移動する場合は「明るさ変化2」、「色味変化0」でpop命令、
となります。
次回予告
さて、命令の決め方の例の中で、Pietインタプリタが
- 左から右に動く場合
- 右から左に動く場合
の両方を考えました。
では、実際、Pietインタプリタはどのように画像上を動くのでしょうか。
実は、Pietインタプリタの移動ルールを理解するのは結構難しいです。
ですが、Pietの理解のためには避けて通れないところです。
というわけで、次回はPietインタプリタの移動ルールを説明します。
(もしかしたら2〜3部構成になるかも)
おわりに
ようやく書き終えたよ。。。
今回は更新遅れてすんませんでした。
Pietの解説をしようとしたら途端に
「説明難すぃいいいいい!!!!」となり、
不覚にも画面とのにらめっこに時間を浪費してしまいました。
次回のPietインタプリタの移動ルールの説明は、
かなり骨であることが予想されるため、
また更新が遅れるかもしれません。
申し訳ないですが、あらかじめ宣言しておきます。
じゃ、今回はこの辺で。
では。