077 からくり郵便室

色を見る台、重さを見る台をつなぎ、六つの便を自動で仕分ける玩具です。
一個ずつ原因を追い、手順が分かったら流して眺めます。速さだけでなく、読みやすい箱の並びも選べます。

起動
Windows: Python 3を入れ、setup.batを一度実行。その後play.bat。
macOS/Linux: Python 3でsetup.sh、続いてplay.sh。実行時はPyxel＋標準ライブラリのみ。
Linux / Python 3.12 / Pyxel 2.9.9で検証。Windows/macOS実機は未確認です。

操作
Spaceで開始。矢印で台、Zで次のカード。Tabで台／箱札の編集を切替。
箱札もZで順送り。Enterで試運転、Spaceで一刻、Pで連続／停止。
Xは編集一手／試運転一刻のundo。試運転開始まで戻すとカードを編集できます。
Rで同じ便を初期配置へ。1/2/3で状況、Bで比較版、Hで説明、Mで表紙。
Sで再現記録、F12で画像、Escで終了。一度押したキーは全部離すまで再発火しません。
一試行の履歴はundoを含め512操作まで。上限では案内を表示し、Rで同じ便を再開できます。
同時操作は不採用。説明や結果でもキーの解放を追跡し、押し残しは次の操作にしません。

ルール
入口→A→B/C→箱1/2/3/4の固定二分木。カードは色、重さ、左、右の四種です。
色は赤が左／青が右。重さは2が左／1が右。判定カード上限はA=1、B=3、C=2枚。
宛先は公開の荷物データと同じ規則。箱札の重複、空箱、使わない台は合法です。
六便は時刻0～5に投入。台は各一便まで。着いた台のカードを読むのは次の刻。
原版は刻の初めに空いた台だけへ移動。同刻に空いても「刻の初めは使用中」と待ちます。
下流、A、投入口の許可を古い台配列から決め、全て同時反映。二台を一刻で飛び越えません。
箱到着時に照合。誤配では全体を止め、届いた便と通り道を残します。
32刻以内に全6便を正しく配れば達成。速さや少ない判定は任意の記録です。
選択台の出口予告と次の一刻は同じモデルを参照。未試験の全便成功を断言しません。

状況と確認済みの構成
A: Aで色、B/Cは左。箱1は赤、箱3は青。Aを左へ素通り、Bで色を読む別案も成立。
B: Aで色、B/Cで重さ。箱札は赤重／赤軽／青重／青軽。
別案はAで重さ、B/Cで色。箱札は赤重／青重／赤軽／青軽。
C: Aで色、Bは左、Cで重さ。箱札は赤／赤／青重／青軽。
赤側を右箱に移す案も成立。先に重さを見る構成は判定上限2では成立しません。
全カード4^3×箱札（A=2^4、B=4^4、C=3^4）を有限検査し、成立数と構成をpolicy_results.jsonへ保存。
原案の数値は変更していません。素通りや重複札を隠し減点しません。

比較
Bキーで空き台の条件だけ変更。比較版は同刻に下流へ移動して空く台も使えます。
新到着便の再判定はどちらも次の刻。荷物、カード、上限、箱、正確な仕分け目標は共通です。
両版で同じ構成が達成する記録をcomparison_results.jsonへ保存。架空の旧版ではありません。

記録と開発
model.pyは純モデル、controller.pyは一操作ずつの入力、app.pyは描画と記録です。
意味入力、論理時刻、規則版、状況、完全な状態、正規化JSON SHA-256を保存。
python -m unittest -vでテスト。experiments.pyは開発時の有限列挙専用。
media/native_*はエージェントがLinux実窓を操作した記録、automatic_*は実際のPyxel自動操作映像。
各セッションには当時のソースを保存し、後の修正で上書きしません。テストは撮影資料を書き換えません。
動画は全ソースフレームを一度ずつ30fpsへ変換した約25秒の無音MP4です。
人による面白さ、Windows実機、音の実聴は未確認です。

権利
自作ソースはLICENSE.txtのMIT。日本語ビットマップはNoto Sans CJK由来、SIL OFL全文を同梱。
Pyxelのライセンス全文もassetsへ同梱。画像素材、外部投稿、アカウントは不要です。
