[Piet入門編]Piet入門1

どもです。

いよいよ今回からPietそのものの解説です。

 

 

何をいまさら

 

感がすごいですが、気にせず解説します。

Pietとは

そもそもPietとは、David Morgan-Mar氏が考案した難解プログラミング言語です。

特徴はご存知の通り、ソースコードが画像であることです。

 

この特徴は超印象的ですが、実は言語の種類としてはそこまで特殊なものではなく、

スタック志向プログラミング言語という分類になります。

(まぁ、スタック志向言語も、あまりポピュラーではありませんが。)

 

また、ソースコード画像には、さまざまな色ブロックが配置されていますが、

これらは次の役割を果たしています。

  • Pietのインタプリタが実行すべき命令を決める。(今回説明します)
  • Pietのインタプリタが画像上をどのように移動するかを決める。(次回以降説明します)

したがって、Pietのソースコード画像は、

「本来は文字(=プログラミング言語)で記述すべき内容を、色ブロックに置き換えて記述したもの」

と捉えることが出来ます。

スタック志向プログラミング言語

さて、Pietのベースとなる「スタック志向プログラミング言語」について簡単に説明します。

と言っても、過去記事で説明していますね。

 

ざっくりおさらいすると、メモリが「スタック」という構造を持つことが特徴です。

スタックのイメージは「底のついた筒状の入れ物」です。

この中に値を順次入れていくことができますが、

取り出すときは最後に入れたものからしか取り出せない、

というものでした。

 

詳細は、下記記事の「スタック」の項をご参照ください。

ymos-hobby-programing.hatenablog.com

なお、スタック志向プログラミング言語には、Ghostscript などがあります。

Ghostscriptは、昔ちょろっとだけ触ったことがありますが、

独特で興味深い言語だったなあという印象を持ちました。

はい。小並感。

Pietの色と命令

ここで、Pietの色と命令の関係を説明していきます。

コーデル(Codel)

その前にまず、Pietの用語をひとつ説明します。その後の説明に便利なので。

 

「コーデル(Codel)」とは、

Pietインタプリタにとっての「ピクセル(Pixel)」です。

 

堅苦しく言い換えると、コーデルとは、

Pietのソースコード画像の単位正方形のことです。

つまり、Pietインタプリタから見た、

サイズが1\times1の正方形のことを指します。

 

なぜわざわざ「コーデル」という特別な名前を与えて

ピクセル」と区別するかというと、

Pietのソースコード拡大して表示することが多いからです。

拡大した時の1コーデルの1辺の長さは、必ずしも1ピクセルではありません。

 

たとえばいつぞやあげた無限ループのプログラム:

f:id:y-mos:20210817230849p:plain
無限ループ

このプログラムの下辺中央付近には、

黒・ピンクの正方形が横向きに連結して配置されています。

これらの黒・ピンクそれぞれは1コーデルです。

したがって、このプログラム内では、これらの正方形より小さなサイズの四角形は現れません。

 

一方でこの画像をダウンロードして調べていただくとわかるのですが、

これら黒・ピンクの正方形の1辺の長さは、1ピクセルではありません。

30ピクセルのはずです。

 

もし1辺1ピクセルのまま掲載すると、

f:id:y-mos:20210828001932p:plain
無限ループ(1ピクセル

見えんですな。

「画像がどこにあるかわかりますか?」というレベルの小ささですね。

 

このように、

画像の一般的な画素単位である「ピクセル」と

Pietにとっての「画素単位」である「コーデル」を区別することで、

これらを混同しないようにしたのです。

Pietに使える色

さて、次は色の説明です。

なんとなく想像がつくかと思いますが、

Pietソースコードで命令を書くときに使える色は決まっています。

どんな色でも使えるのであれば、ルールが複雑になりそうですよね。

できなくはないと思いますが。

 

もとい、Pietの命令に使える色ですが、具体的には次の20色です。

表にはカラーコードも示しています。

明るい 普通 暗い
#FFC0C0 #FF0000 #C00000
#FFFFC0 #FFFF00 #C0C000
#C0FFC0 #00FF00 #00C000
シアン #C0FFFF #00FFFF #00C0C0
#C0C0FF #0000FF #0000C0
マゼンタ #FFC0FF #FF00FF #C000C0
#000000
#FFFFFF

命令を実行するにあたり、重要なのは

  • 色味(Hue)
  • 明るさ(Brightness)

の2つです。

 

「色味」とは、いわゆる「何色か」に相当するものです。

「赤」、「黄」、「緑」、「シアン」、「青」、「マゼンタ」の6種類あります。

 

「明るさ」は、文字通りですね。「明るい」、「普通」、「暗い」の3種類あります。

 

Pietの命令を解釈するには、「明るい・赤」、「暗い・緑」など、

「明るさ」と「色味」の組み合わせが重要になります。

Pietの命令

では、Pietの命令を見ていきます。

Pietの命令は、全部で17個あります。

以下、命令一覧表を示します。

明るさ変化0 明るさ変化1 明るさ変化2
色味変化0
push
push
プッシュ
pop
pop
ポップ
色味変化1
add
add
加算
subtract
sub
減算
multiply
mul
乗算
色味変化2
divide
div
除算
mod
mod
剰余算
not
not
否定
色味変化3
greater
gt
比較
pointer
-
DP変更
switch
-
CC変更
色味変化4
duplicate
dup
複製
roll
roll
ロール
in(number)
inn
数値入力
色味変化5
in(char)
inc
文字入力
out(number)
outn
数値出力
out(char)
outc
文字出力

まず、黒文字の命令は、前回までの記事で見たことのある命令だと思います。

同じ名前の命令が、拙作の「GridPietGenerator」にも存在し、

しかも全く同じ処理をしています。

(というより、GridPietGeneratorの命令を、Pietに合わせたのですが。。。)

ここでは詳細の解説は割愛しますが、いずれもスタック内の値を操作する命令です。

 

そして、赤文字の命令は、今回初めて出てきました。

これらは、Pietインタプリタの進行方向を変化させるのに使う命令です。

これらは追々説明をすることにします。

命令の決定方法

次にPietの命令がどう決まるかです。

Pietを理解するポイントの一つですね。

 

Pietでは、Pietインタプリタが画像をスキャンしていく途中で、

通り道のコーデルの色が変化したとき、その色の「変化」に応じて命令が決まります。

したがって、色そのものと命令とは、対応していません。

 

実行される命令は、具体的には、

  • 前後の色の「明るさ」の変化量
  • 前後の色の「色味」の変化量

で決まります。

先ほどの命令表のフチにしれっと

「色味変化」「明るさ変化」と書いてあります。

それぞれの変化量の交差する場所の命令が実行されます。

 

なお、変化量を数えるときは、次の順序に沿って数えます。

  • 色味:「赤」→「黄」→「緑」→「シアン」→「青」→「マゼンタ」→「赤」→・・・
  • 明るさ:「明るい」→「普通」→「暗い」→「明るい」→・・・

「順序」とは言っていますが、「マゼンタ」まで行ったら再び「赤」に戻るなど、

循環していることに注意してください。

命令の決定方法の具体例

具体例を出します。

例1

まず次の画像を考えます。

f:id:y-mos:20210901213145p:plain
 

Pietインタプリタが、この画像を左から右に移動する場合には、

どの命令が実行されるでしょうか。

 

この場合は、「明るい赤」から「明るい緑」への変化です。

まず、色味ですが、「赤」から「緑」まで、

「赤」→「黄」→「緑」と2段階で変化していくため、変化量は2です。

 

次に、明るさですが、「明るい」から「明るい」までの変化、

つまり、変化なしで、変化量は0です。

 

以上から、先ほどの表より、

「色味変化2」と「明るさ変化0」が交差する箇所の

割り算の命令「div」が実行されます。

例2

次に、以下の画像を考えてみます。

f:id:y-mos:20210901220638p:plain
 

Pietインタプリタが、この画像を左から右に移動する場合を考えます。

この場合は、「普通のマゼンタ」から「明るいシアン」への変化です。

 

まず、色味ですが、「マゼンタ」から「シアン」まで、

「マゼンタ」→「赤」→「黄」→「緑」→「シアン」と4段階で変化していくため、

色味変化量は4です。

「マゼンタ」から「赤」に戻っていることに注意してください。

 

次に、明るさですが、「普通」から「明るい」まで、

「普通」→「暗い」→「明るい」と2段階で変化していくため、

明るさ変化量は2です。

こちらも「暗い」から「明るい」へと循環しています。

 

以上から、先ほどの表より、

「色味変化4」と「明るさ変化2」が交差する箇所の

数値入力の命令「inn」が実行されます。

例2 - 逆走した場合

なお、もしPietインタプリタが、今までの方向とは逆に、

この画像を右から左に通り抜けた場合はどうなるのでしょうか。

f:id:y-mos:20210901220638p:plain
再掲

この場合は、「明るいシアン」から「普通のマゼンタ」への変化です。

今までと同様に考えて、

  • 色味は「シアン」→「青」→「マゼンタ」の2段階変化
  • 明るさは「明るい」→「普通」の1段階変化

なので、「色味変化2」と「明るさ変化1」の交差する箇所の

除算命令「mod」が実行されます。

このように、同じ色の組み合わせでも、逆走すると命令は変化します。

例3

以上の例でだいぶ慣れてきたのではないでしょうか。

以上の例のように、Pietの命令は、色の変化に関連づけられています。

色そのものには関係しないので、

同じ変化の仕方であれば、異なる色でも同じ命令を表現できます。

 

たとえば、以下の画像は全て同じ命令を表します。

f:id:y-mos:20210901221853p:plainf:id:y-mos:20210901221902p:plainf:id:y-mos:20210901221906p:plain
 

f:id:y-mos:20210901221912p:plainf:id:y-mos:20210901221918p:plainf:id:y-mos:20210901221922p:plain
 

いずれも、

 左から右に移動する場合は「明るさ変化1」、「色味変化0」でpush命令、

 右から左に移動する場合は「明るさ変化2」、「色味変化0」でpop命令、

となります。

次回予告

さて、命令の決め方の例の中で、Pietインタプリタ

  • 左から右に動く場合
  • 右から左に動く場合

の両方を考えました。

 

では、実際、Pietインタプリタはどのように画像上を動くのでしょうか。

実は、Pietインタプリタの移動ルールを理解するのは結構難しいです。

ですが、Pietの理解のためには避けて通れないところです。

 

というわけで、次回はPietインタプリタの移動ルールを説明します。

(もしかしたら2〜3部構成になるかも)

おわりに

ようやく書き終えたよ。。。

 

今回は更新遅れてすんませんでした。

Pietの解説をしようとしたら途端に

「説明難すぃいいいいい!!!!」となり、

不覚にも画面とのにらめっこに時間を浪費してしまいました。

 

次回のPietインタプリタの移動ルールの説明は、

かなり骨であることが予想されるため、

また更新が遅れるかもしれません。

申し訳ないですが、あらかじめ宣言しておきます。

 

じゃ、今回はこの辺で。

では。