KMC37代のdamaです。
KMC外ではDNEK と名乗っています。
これはKMC Advent Calendar 2025 の6日目*1 の記事です。
対象読者
Pietの正しい仕様や開発環境に興味がある方
使っているPiet開発環境の挙動に疑問を感じている方
一次資料を読むことの大切さを知りたい方
Pietの仕様を知らない方は、とりあえず雰囲気で読むか、以下の解説スライドの16-37ページに目を通すと良いでしょう。
www.slideshare.net
概要
「Piet」はドット絵をソースコード として扱う難解プログラミング言語 です。
ざっくり説明すると「プログラムがドット絵の中を上下左右に移動しながら各点の色の違いに応じてコマンドを実行していく」というものです。
Pietの歴史は約四半世紀*2 の長きにわたり、その間にソースコード 画像や開発環境がいくつも生み出されていますが、実はその多くが公式の仕様に準拠していません。
また、仕様自体にも実装依存 や未定義部分が多く含まれるため、利用する開発環境により体験が大きく変わってきます。
本稿では、私自身がかつて仕様の一部を誤解してIDE を実装してしまった事例を取り上げ、Pietの仕様違反の発生と拡大の構造を分析します。
そして、そのような実態との向き合い方を考え、仕様を意識したPietプログラミングを実践するためのガイドを提示します。
仕様解釈の誤り(私の事例)
誤解の内容
私がかつて誤解していたのは「白ブロック上で行き止まりに突き当たった際の挙動」です。
以下は3x3 のソースコード を例に、正しい挙動と誤解に基づく挙動をそれぞれ模した図です。
普通の矢印は移動成功、バツ印は移動失敗を表しています。
正しい挙動(左)と誤解に基づく挙動(右)
つまり、左図のように
赤から右方向へ直線状に移動する
行き止まりに突き当たって移動に失敗し、CCが切り替わる
行き先が変わらずまた移動に失敗し、DPが時計周りに進む
右上の白からそのまま 下方向へ直線状に移動する
緑に入る(白ブロックから抜け出す)
というのが正しい挙動ですが、右図のように「3の直後、白でないカラーブロック(今回は赤)まで引き返してから 移動を再開する(そして青に入る)」と誤って解釈していました。
解釈を誤った原因
この仕様解釈の誤りは、当時の私が仕様を学ぶ際、不完全な和訳と古いデバッガの挙動に依存したことに起因します。
つまり「一次資料(=仕様原文)を読み解く努力を怠った」 ことが根本的な原因でした。
まず、私が頼りにしていたPietの仕様原文の和訳ページから「白ブロックの挙動について」という節の訳文を引用します。
白ブロックの挙動について(追記:2008.1.25) : (この辺り訳がちょっと微妙 by訳者)
インタプリタ は白ブロック上を一直線に 色の着いたブロックに当たるまで進みます。
先に説明した普通のカラーブロックの時のような動き方はしません。
白ブロックを通りすぎて黒ブロックや端に当たった時正確にどうなるのかが元の仕様では不明確でした。
私の解釈を以下に記しておきました。
インタプリタ は一直線に"滑って"白ブロックの上を通り過ぎる。
もし行き止まりにあたったらCCを切り替えるが、インタプリタ の行く先は変わらないのでDPを変える。
新しい向きのDPで今いる白codelの上からカラーブロックに到達するか別の行き止まりにぶつかるまで滑る。
白ブロックの上で行き止まりにぶつかる度にCCやDPを切り替えて滑りなおしてみる。
これをカラーブロックに到達するまで繰り返す(その場で)。
白ブロックの上から試してダメだった場合はもと来た道を引き返す。
引用元: DM氏の難解プログラミング言語 - Piet (和訳版) www.kembo.org
訳者自身も「この辺り訳がちょっと微妙」と注記している通り、最後の2行が一義的に解釈しにくい表現になっています。
後ろから2行目の「今いる白codelの上から」は正しく「引き返さない」ように読めますが、最終行の「(その場で)」「もと来た道を引き返す」は「引き返す」ように読めます。
続いて、最終行の原文を引用し、今の私による拙訳も付しておきます。
原文:
Each time the interpreter hits a restriction while within the white block, it toggles the CC and steps the DP clockwise, then tries to slide again. This process repeats until the interpreter either enters a coloured block (where execution then continues); or until the interpreter begins retracing its route. If it retraces its route entirely within a white block, there is no way out of the white block and execution should terminate.
引用元: DM's Esoteric Programming Languages - Piet www.dangermouse.net
拙訳:
インタプリタ が白ブロック内部で行き止まりに突き当たる度に、CCを切り替えてからDPを時計回りに進め、それから再度滑って行こうとする。
この手順は、インタプリタ がカラーブロックに入る(それから実行が再開する)か、同じ経路を再度辿り始めるまで繰り返される。
もしインタプリタ が同じ経路を完全に白ブロック内部だけで再度辿ることになった場合は、白ブロックの外部に出る方法は無く、実行は終了する。
このように、原文には「引き返す」解釈を促すような表現は無く、また、同じ経路を再度辿る場合の仕様が明記されています。
そして、当時はステップ実行機能が便利という理由で主にPietDev というオンラインIDE でデバッグ をしていました。
しかし、PietDevが作られたと推測される2006年*3 時点では、先述の挙動が未定義 でした*4 。
PietDevはおそらくその未定義動作を独自に実装した結果、まさに「引き返す」実装になっていました。
当時の私はデバッガが古い可能性を考慮せず、その挙動に整合する解釈を和訳から選択するだけで満足してしまったため、誤りに気付くことができませんでした。
仕様解釈の誤りがもたらした影響
2015年、私が自作のIDE 「Pidet」とPietの仕様解説スライドを合わせてKMC部内で発表したところ*5 、予想外の反響を受け、部内でPietが流行り始めました。
また、勉強会や外部イベントでの発表*6 に加え、何人かのKMC部員がPidetを参考に様々なPietアプリケーション*7 を開発していったため、2017年5月に外部から指摘を受けるまでの間、私を含む誰もがその誤りに気付かないままKMC外にも仕様違反を広める結果になりました。
2018年以降このPietブームは下火となったものの、「KMC Piet」*8 に基づくアプリケーションの一部は修正されないままインターネット上に残り続けています。
Pietの仕様との向き合い方
私個人として、当時の私の考慮不足が結果的に周囲へ混乱を招いた点について、反省すべき点が多かったと改めて感じます。
誤解に気付いた当時の私はPidetの当該仕様違反を修正し、翌年には新しいIDE の開発に移行して更なる修正を加えています。
一方で「OSS ライセンス等により明確に免責され、需要も少ないアプリケーションのメンテナンスをする必要は無い」という考え方も尤もであり、他の開発者にまで同様の対応を求めるつもりはありません。
また、その利用者の多くはPietの外見上の難解さやプログラムが動作する様子を見てカジュアルに楽しむのが目的であり、彼らにまで実装の精査を求めるのはナンセンスです。
したがって「インターネット上の多くのPiet実装が不確かであり、指摘を受ける機会も稀である」という事実を認識し、仕様に忠実なPietプログラミングを行いたければ最終的には自分で判断するしかない という意識を持つのが合理的であると考えます。
なお、Pietの最新仕様冒頭の注意書きには以下に引用する記述があります。
I have now added some clarifications to this specification to address some of the questions I have been asked over the years. Hopefully they are sensible and most implementations will already be compliant, but it's possible some do not comply. Caveat emptor .
引用元: DM's Esoteric Programming Languages - Piet www.dangermouse.net
拙訳:
これまでに寄せられた質問の一部に対応するため、私はこの仕様にいくつかの補足説明を追加しました。それらが理に適っており、ほとんどの実装が既にそれらに準拠していることを願いますが、一部はそうでない可能性もあります。買い手に用心させよ。
Caveat emptor (買い手に用心させよ)というのは、「商品の品質を確認する責任は購入者にある」という売買法上の原 則を表すラテン語 の法諺 です。
現実の商取引への適用はさておき、無料でオープンソース が基本の難解プログラミング言語 の世界ではそう考えておくのが無難なようです。
仕様重視型Pietプログラミングガイド
先述のように、Pietをカジュアルに楽しむのであれば、ググって一番上に出てくるものやAIのオススメに従うのも手軽で良いと思います。
しかし、本格的にPietプログラミングに取り組むのであれば、仕様を意識しない限りほぼ確実に罠に嵌まります。
過去に間違いを犯した私を信じるかの判断は勿論読者に任せられますが、ここでは仕様原文を隅々まで読み込んだ今の私が考える、仕様を重視してPietプログラミングをするための具体的な選択肢を紹介していきます。
入門資料2選
最終的に自己判断が必要であるとは言え、初学者が公式の仕様原文を読むのは骨が折れます。
原文は英語で書かれている他、画像をソースコード として扱うにも関わらず図による説明が一切ありません。
そこで、内容に大きな問題が無く図解が豊富な入門用の資料を2つ紹介します。
まずは入門でPietの具体的なイメージを掴み、厳密性を原文で補いましょう。
1つ目は冒頭で挙げたbase64 氏によるスライドです。
www.slideshare.net
もう読んだ方もいるかもしれませんが、発表用スライドということもあり要点がコンパクトにまとまっていて読みやすいです。
2つ目はy-mos 氏によるブログ記事シリーズです。
ymos-hobby-programing.hatenablog.com
5回にわたり、複数の例を図解しながら細部まで丁寧に解説されています。
Pietプログラミングには通常IDE (画像エディタ兼デバッガ)を用いますが、仕様を重視する上でその選択は特に注意が必要です。
今私が「Piet editor」 及び「Piet IDE」 というキーワードでそれぞれGoogle 検索をしたところ、一番上に表示されたものはそれぞれ別のIDE でありながら、いずれも白ブロック上の挙動が誤っており、しかもその誤り方はそれぞれ異なるものでした。
また、GPT-5.2の一時チャットで「お勧めのPiet開発環境を教えてください。」と尋ねたところ、「エディタ/IDE (画像ベース)」を3つ紹介されましたが、リンク切れが1つと最新仕様が定まった2014年*9 以前にインタプリタ 部分の更新が止まっているものが2つでした。
私の知る限り、ある程度実用的かつ仕様に忠実そうなIDE は現在2つしか無いので、それらを紹介します。
1つ目はBubbler-4氏によるブラウザベースのIDE です。
github.com
オンラインのIDE は手軽に使えて便利です。「Export」タブの「Permalink 」ボタンで、IDE と描いたソースコード 画像をまとめて共有するURLを取得できます。
2つ目は私がPidetの次に作った「Pietron」です。
github.com
ここで紹介しても良いと思える品質に仕上げるため、この記事の執筆と並行して改修作業をしていました。
改修したばかりで新しいバグを埋め込んでいたりしたら申し訳ないです。
デスクトップアプリなので手軽さでは負けますが、現存するIDE の中で私にとっては一番使いやすいUIになっています。
なお、これら2つの間にも以下のような実装依存 部分の差異があります。
整数が多倍長整数 vs 符号付き64ビット整数
in(number) コマンドで標準入力が整数にマッチしなかった場合に先頭の空白を消費する vs 消費しない
これ以上拘りたい方は是非それぞれの実装やPietの仕様原文を精読してみてください。
私は画像編集機能が無い普通のインタプリタ にはあまり詳しくないのですが、現在主流(?)と思われるものを2つ挙げます。
1つ目はErik Schoenfelder氏によるnpietです。
エディタも別アプリとして載っていますがIDE ではない普通の画像エディタなので、圧倒的に有名であるインタプリタ の方だけ紹介します。
www.bertnase.de
昔からPietインタプリタ のデファクトスタンダード とされており紹介しない訳にはいかないのですが、実はそのまま実行すると白ブロック上で無限ループすることになっても実行が終了しません。
マニュアルに書いてある通り -v11 オプションを付けて実行しましょう。
また、npietのソースコード を読むと mod コマンドがC言語 の % で実装されていることがわかりますが、Pietの仕様では「切り下げ除算」 を使うことになっているのでこれは仕様違反です。
2つ目はynn氏によるRust製インタプリタ です。
github.com
何故これを挙げたかと言うと、最近AtCoderでPietが使えるようになりそのインタプリタ として採用されたからです。
新ジャッジ運用開始のお知らせ - AtCoder
私はRust初心者ですが、READMEや実装を読むと仕様を忠実に守ろうとする姿勢が伺えます。
div コマンドに切り下げ除算が使われていないのが少し気になりますが、こちらは仕様に明記されていないので仕様違反ではないはずです。
また、こちらの in(n) コマンドはREADMEに書かれている通り、より積極的に標準入力を消費します。
先述のIDE を用いてAtCoderに参加する場合は特に注意しましょう。
ちなみに、AtCoderでは基本的にバイナリファイルを提出できないためPlain PPM というテキストベースの画像フォーマットを使う必要があるのですが、これを一般的な画像フォーマットと相互に変換するUserScriptを公開しているので紹介しておきます。
dnek.net
今後の予定
先ほど公開したPietron 2.0.0のリリースノート にも書いたのですが、PidetとPietronに続き3つ目のIDE を作ろうと思っています。
これ以上作り直す羽目にならないように保守性を重視して開発したいです。
また、今回の調査で改めて手軽さが重要であることを実感したので、利便性を向上させつつも純粋なウェブアプリとして作る予定です。
この記事と同様にどれくらい完成が遅れるかは不明ですが、興味のある方は以下のいずれかを適当に見ておいてください。
それでは、各々にとって良きPietライフをお過ごしください。