046 消防水路
消したあとの水が、次の火を止める。

架空の25マス水路パズル。現実の消火、防火、避難手順として使わないでください。
Windows: Python 3.10以上を入れ、setup.bat、次にplay.bat。フォルダー単独で動きます。
Linux/macOS: sh setup.sh、sh play.sh。実行時はPyxel+標準ライブラリのみ。音はありません。
Windows/macOS実機は未確認。日本語・空白パス、任意cwd、cp932既定を模したUTF-8検証済み。

SPACEで開始。左右で放水口W/E、上下で量1/2、Zで放水して1刻。SPACEで放水なしの1刻。
Xで直前の一刻を戻す。Rで同状況再開。Pで停止/説明。1~3で状況切替。Mで表紙。ESC終了。
Bは濡れ持続2/0の管理比較を切り替え、初期化します。F12は検証用の画像/入力記録を保存。
停止中はP/R/Mのみ。全キー解放を毎フレーム追い、長押しで次の状態へ操作を持ち越しません。

ルール
貯水4。水1単位で火1マスを消し、蒸気1へ。残水は1刻に低い隣へ1歩だけ進みます。
最も低い候補を優先し、同高なら下→左→右→上。低い隣なしなら溜まり、下端は排水。
各マスに別の小さな容量上限はありません。合流は全部合算。総水4が1マスの最大値でもあります。
水が触れたセルの濡れ残は2。通過刻と次刻の着火を防ぐが、濡れは再利用できる水の在庫ではありません。
火は風下に隣一マスへ延焼し、燃料を1減らします。新しい火は燃料2で次の刻から働きます。
自然に燃え尽きたマスは灰になり再燃しません。水で消えた草は、濡れが切れれば再び燃えます。
家は一度燃えると被害。火がすべて消えた時、指定数以上の家を守れば成功。残水も成績として表示。
成功後は盤面の水もそのまま残ります。鎮火後の排水を強制せず、undoで前の判断へ戻せます。

更新順
旧濡れ-1→放水→現在セル消火→残水を二重バッファで一歩→移動先消火→触れたセル濡れ2→
生き残った旧火の延焼先を集合化→旧火燃料-1→新しい火を一括生成→判定。
予告はこの純粋モデルと同じ計算。水不足の拒否は時間も資源も変えません。

三状況と確認済みの別案
A: Wへ1→待つで全3家、貯水3。Wへ2でも全3家、残水が下流へ届きます。
B: Eへ1、あとは待つだけで全3家、貯水3。上の目立つ火は自然鎮火を待てます。
   E1→W1も成功。W1→E1は東の家に間に合わず2家。W放水を必須にしていません。
C: 3刻待つ→E1→待つで2家、貯水3。W1→E1も2家、貯水2。
   全合法行動木の探索では全3家は不可能。設計通り目標2を保ち、全保護可能とは書きません。
時間制限や隠れた罰はなし。予報を見て待つ、自然鎮火を利用するのも正当な解です。

検査: python -m unittest test_model test_ui（24項目）
探索と方策再計算: python experiments.py。全合法な放水/待機列を鎮火まで列挙。
実画面自動収録: python app.py --headless --demo。通常のゲームと同じupdate/drawを使用。
media/fire_waterways_automatic_silent.mp4:779元フレームを30fpsで保持、25.966667秒、無音。
Pillow/ffmpegは開発時の字形生成と動画変換だけ。プレイ時は不要。
QA.txt、EXPERIMENT.txt、NOTE.txt、X_POSTS.txtに確認範囲と下書きを分離。
