026 音のないピアノ
Python + Pyxel / 小さな実験推理パズル / 日本語UI / 無音

どの鍵なら情報が得られるか。どの鍵なら仕上がるか。
修理中のピアノの鍵は、音の代わりに3つの灯りを反転する。
全配線を当てるゲームではなく、目標の灯りを作るゲームです。
手作り3状況。時間・回数・失敗への罰はありません。
実装・機能検証済み。面白さと初見理解は人の試遊待ちです。

起動
Python 3.10以降を使用。実装時の確認は Python 3.12 / Pyxel 2.9.9。
Windows: このフォルダを丸ごと展開 → setup.bat → play.bat。
setup.batは初回にPyxelを導入します。通信が必要です。
日本語と空白を含む配置先を想定。BATはASCII、パス引用、失敗時pause付き。
macOS/Linux: sh setup.sh → sh play.sh。
独立配置でも上記で起動できます。親プロジェクトは不要です。
launch.shは開発用で、独立.venvがなければ共有pilotのPythonを探します。
Windows/macOS実機は未確認。Linuxの実画面と実キー入力を確認しています。

操作
左右: 鍵を選ぶ。タイトルでは面を選ぶ
SPACE: 開始 / 選んだ鍵を1回押す
Z: 灯りだけを直前へ戻す。観測メモ・累積押下数は残る
R: 同じ実物配線のまま000へ戻す。観測メモ・累積押下数は残る
上下: 観測記録を1行ずつさかのぼる / 新しい記録へ戻る
P: 説明と一時停止
M: 面選択。SPACEで選び直すと配線・メモ・押下数を面の初期状態へ戻す
N: 成功後、次の面
ESC: 終了
F12: 技術確認用の画面と操作ログをmediaへ保存

通常の全状態undoとの違い
知った事実は、灯りを戻しても忘れません。観測記録は押した鍵の前後だけを記録します。
Z/Rそのものは観測行を増やしません。前行の後と次行の前が違えば、その間に灯りを戻しています。
「押下」は実際に鍵を試した累積回数。Z/Rで減らしません。制限・評価点ではありません。
undo後の新しい操作は物理履歴の未来を捨てますが、古い観測記録は読み返せます。

画面の読み方
大きい3灯と3桁の数は、常に左→右です。100は左だけ点灯。
各候補図の小さい3灯は、その鍵を押すと反転する灯りです。1=反転、0=そのまま。
観測記録は「鍵 / 押す前 -> 押した後 / 反転した灯り」。色だけでなく数字でも確認できます。
枠付きのo行は観測に一致。x行は観測と矛盾。矛盾行も消去せず比較できます。
「観測で確定」は、観測に合う全図で一致した鍵だけを示します。?は図によって違います。
「実物図」は別情報です。成功するまで未開封。成功後に実物の番号を開示します。
開封後も候補数と「観測で確定」は、押下の観測だけから導く値です。
実物番号が分かったことと、観測だけで全配線を特定できたことを混同しません。
一度開封した番号はZ/Rで再び隠しません。面の選び直しで未開封へ戻ります。
候補数1は成功条件ではなく、目標との灯り一致だけが成功条件です。

再現できる成功例（解答。先に自分で考えたい場合は読み飛ばしてください）
A 実物図2: 鍵A → Z → 鍵B。押下2回、観測に合う図1枚。
  実キー: SPACE開始、SPACE、Z、右、SPACE。
B 実物図3: 鍵A → 鍵D。押下2回、観測に合う図2枚。
  実キー: SPACE開始、SPACE、左（AからDへ循環）、SPACE。
C 実物図3: 鍵A → 鍵B。押下2回、観測に合う図2枚。鍵Cは未観測。
  実キー: SPACE開始、SPACE、右、SPACE。
実物の指定はmodel.pyのLevel.actual_index。Rで抽選しません。乱数を使いません。
全候補図の可達性は検査済みです。別の図での再演は純粋モデルのinitial(level, actual_index)で再現できます。

検査と資料
python -m unittest -v test_model test_ui
python solver.py
python experiment.py
python tools/test_portability.py
python app.py --headless --demo
python tools/export_video.py
tools/build_font.py と export_video.py は開発用にPillow、動画変換にffmpeg/ffprobeが必要です。
ゲーム本体は同梱glyphs.jsonを読み、フォントの再生成は不要です。
solver_results.json: 全10実物図×8灯の可達性、896の有限観測状態と3,200押下辺の検査。
experiment_results.json: 方策比較と薄色化だけの一変更比較。実在した旧版の成績ではありません。
media/silent_piano_automatic_silent.mp4: 実Pyxelの自動操作・無音映像。人のプレイ映像ではありません。
media/timing_validation.json: 元GIFの全719フレームを各1回、30fpsへ変換した検査。
QA.txt: 技術確認の範囲と限界。NOTE.txt / X_POSTS.txt: 日本語発信用の未投稿草稿。

権利
コード・独自ピアノ絵は同梱MIT License。
日本語ビットマップはNoto Sans CJK由来、SIL Open Font License。assets/NOTO-LICENSE.txtを同梱。
音声処理を使用しません。音を聞けなくても情報は欠けません。音質の実聴評価はしていません。
