013 棚からぼたもち
Python + Pyxel 2.9.9 / 単独起動の小さな支持パズル

もちを全部、白い皿へ落とす。板を全部消すゲームではありません。
主な迷い：どの板を引き抜き、重いものの支えをどこに残すか。

起動
Windows: Python 3.10以降を入れ、このフォルダの setup.bat を一度実行。
         次から play.bat を実行。失敗時は画面を止め、エラーを読めます。
macOS/Linux: bash setup.sh → bash play.sh
標準ライブラリ + pyxel==2.9.9 だけで遊べます。画像・フォントデータは同梱。
launch.sh は開発用（単独 .venv を優先、なければ同梱元の共有venv）。
Windows/macOS実機は未検証。cp932既定文字コード、日本語/空白パス、別作業
ディレクトリからの起動をLinux上で模擬試験しました。Linux実GUIはQA.txt参照。

操作
開始画面：左右で3つの棚を選び、Spaceで開始。
左右：板を選ぶ。Space：選んだ板を1枚引き抜く。
落下の演出中は次の除去を受け付けません。Z：直前の1手へ完全に戻す。
Zは演出途中や失敗後にも使えます。R：同じ棚の最初へ。
P：停止/再開（落下演出も停止）。成功後N：次の棚。Esc：終了。
F12：media/manual_runtime.pngへ現在の実画面を保存（QA用）。
時間制限・減点・操作の速さによる報酬はありません。安全に考えてかまいません。

見た目と約束
白い顔の箱＝もち。点1つが重さ1。数字3の灰色の箱＝石。
茶色の板＝引き抜ける棚。E/Fは斜線付きの細い支持板で耐荷重1.25。
斜線の青い四角＝壁に固定した支持ブロック（下まで続く見えない柱ではない）。
薄い白い器＝皿。皿の上の点線はもちの落下列。
黄色の枠＝選択板。上の重さ/耐荷重の数字と、重さの丸印で確認できます。
板の自重は1。耐荷重は「上から受ける重さ」で、自重は含みません。
支えへ渡すときは、上の重さに板自重を足します。

非回転・垂直だけの棚模型です。現実の棚の安全性を計算するものではありません。
もちも板も格子の箱で、横へ滑らず、回転しません。
両端の支えがある板は総重量を半分ずつ渡します。
片端だけになった板は、残る支えで止まり、全重量をその側へ渡します。
中央だけに固い接触があればそこでも止まります。固定物を貫通しません。
重さが耐荷重と等しいときは耐え、超えた支持板を同時に取り去ります。
破断は白い亀裂を少し長く表示。下の板は消えず、支えを失えば落ちます。
プレイヤーが「引き抜いた板」は盤面から消えるので、この違いが大事です。
石/板がもちや皿へ触れる、もちが床へ落ちると、その接触位置で失敗停止。
物体の重なりは作りません。赤い枠と原因文からZで戻せます。

3つの棚（固定配置、乱数なし）
A 下の皿を待つ：板Aを抜く短い1手導入。深い問題とは数えません。
B 石のふた：もちの下のAを抜き、石の下のBを残す。
  Cを先に抜くだけなら、Bは左の固定ブロックで止まります。
  Bを抜くと石がもちへ落ちる。残す判断を練習する面です。
C 荷重の引越し：A1/A2のもちを一度Dで受けられます。
  1つだけDに載るとE/Fは各1、2つ載ると各1.5で両方が割れます。
  A1→D→A2、左右を逆にした順、D→A1→A2などが成功します。
  Dを最初に抜く短い発見も正解。回り道や全除去を強制しません。
  E/Fの一方だけを残すと荷重が集中するため、同じ手でも結果が変わります。
解の全列・初手別の結果は solver_results.json。

モデルの作り
model.pyはPyxel非依存。不変Stateとtransition(state,action)で再現可能。
接触は格子の実座標から計算。別の手書き支持グラフは使っていません。
重さはFractionで正確に配分。上から荷重集計→同時破断→下の支持から
安定を判定→落下群を同時に1格子移動→再計算。128反復の異常検出付き。
座標の1格子は概念上12px、表示では22px。落下1段を4/30秒で描画します。
これは固定秒刻みの剛体積分ではなく、離散ターンモデルです。

検証
python -m unittest -v
python solver.py
python experiment.py
python tools/test_portability.py
app.py --baseline はCのE/F耐荷重だけを無制限へ戻します。
詳しい比較・判断の限界：EXPERIMENT.txt / QA.txt

媒体
media/mochi_automatic_silent.mp4 は実際のPyxel描画の自動操作・無音動画。
719フレームを30fpsで収録した23.966667秒、768×864、音声トラックなし。
元GIFはPyxelの30ms間隔で21.57秒。MP4は同じ719枚を30fpsへ時間補正し、
ゲームの論理30Hzへ合わせています。長い映像の切り貼りや人の試遊ではありません。
PNGは実Pyxel描画。基準/変更の同じ入力後のPNGも同梱。

状態
実装・モデル検証・Linux実GUI操作確認済み。詳細はQA.txt。
人による楽しさ・初見理解の確認は未実施。無音設計、音の実聴確認なし。
最初の3作品への好評を、本作の評価には転記していません。
NOTE.txtとX_POSTS.txtは日本語投稿の下書き。公開投稿はしていません。
