030 ひと箱の天気
実装・機能検証済み／面白さは人による確認待ち

花に降らせる2滴と、水門に残す1滴。
日差しで皿の水を雲へ移し、雲を動かし、雨を降らせる小さな環境パズルです。
自動の風・蒸発・制限時間はありません。考えている間、箱はそのままです。

起動
Windows: Python 3.10以上を用意し、setup.batを一度実行。以後play.bat。
Linux/macOS: bash setup.sh、次にbash play.sh。
Pyxel 2.9.9を固定。初回導入にはネット接続が必要です。
launch.shは開発用の共有Pythonも探します。配布先の通常手順はsetup/playです。
Linuxの実画面で操作確認済み。Windows実機GUI・macOSは未検証です。
cp932を既定にした模擬試験、日本語と空白を含む配置先、任意の作業フォルダからの起動は別に確認しました。

操作
タイトル: 左右でA/B/Cを選び、SPACE開始
左右: 雲を1列動かす
上: 日差し。真下の皿から雲へ1滴
下: 雨。雲から真下へ1滴
Z: 雲移動・日差し・雨を1行動戻す。成功してからも戻せる
R: 同じ箱を初期化
P: 説明と一時停止
M: 箱選択へ。選び直してSPACEを押すとその箱を初期化
成功後N: 次の箱
ESC: 終了
F12: media/manual_runtime.pngと操作ログを保存（上書き）
長押しは反復しません。複数矢印の同時押しは無効。
開始、次面、停止解除、戻す、リセット、メニューでは全操作キーを一度離します。
水の移送中は追加入力を溜めません。最大数小刻みの表示が落ち着いてから押してください。
移送中のキー解放も検出し、空きフレームの新しい押下は受付けます。Z/R/Pは移送中も使えます。

箱の読み方
雲の腹に3つの滴枠。各皿には名前と現在量/容量。
黄色の枠は日差しが最初に当たる物、青枠は雨が最初に当たる物です。
下の予告欄もその名前を表示。流れ着く経路は矢印で読みます。
屋根、取入口、閉じた水門は日差しを遮ります。細管は透明で、真上からの雨や日差しを遮りません。
これは1滴を1単位にした架空の天気模型です。現実の気圧や流体を再現するものではありません。

A 雨を引っ越す
源Sに2滴、花Fは空。花へ2滴で成功。まとめて運んでも1滴ずつ往復してもかまいません。
B 花の真上は屋根
花の真上に降らせると、屋根の矢印で別の受け皿Bへ。
Bの真上で日差しを当てれば回収できます。右の取入口から雨樋を通すと花へ届きます。
C 水門に一滴を残す
開閉皿Kの1滴が門の重りです。花2滴、K1滴の両方が必要です。
Kから吸い上げると門が閉じます。閉門時の雨は右の戻り樋でSへ戻ります。
花の真上で連続3回降らせるだけでは開きません。

水の契約
総水量 = 雲 + 全皿/流路 + 吸収済み帳簿。A/Bは2、Cは3で一定。
今作の花は水を保持するだけで消費しません。未成功時、屋根に遮られなければ回収可能。
吸収済み帳簿は明示的に0です。永久吸収や描画だけの追加水はありません。
雨が何にも当たらなければ底の戻り樋からSへ。皿の余りもSへ戻ります。
雲が空、満杯、皿が空、日差しが遮られる場合は状態・手数・履歴を変えません。
残機、減点、自動敗北はありません。間違った雨は回収するかZで戻せます。

更新のしくみ
model.pyはPyxelを読み込まない不変Level/Stateと純粋transition。
1小刻みの移送予定を旧配列だけから作り、新配列へ加算します。
細管/屋根は1小刻みに1滴を次へ。皿の容量超過は次の小刻みに1滴ずつあふれます。
同じ皿への複数流入は全て加算し、先着の走査順で消しません。
門の行先は旧配列のK量で決定。雨が同じ小刻みにKへ着いても、その刻みの門は旧条件です。
流路グラフは有向非循環。終息上限を超えるデータはエラーにし、水を捨てて続けません。
画面は同じ小刻み配列を表示。アニメの滴は別の資源として足しません。

再検証
python -m unittest -v
python solver.py
python tools/test_portability.py
python tools/verify_native.py
python app.py --headless --demo
python tools/export_video.py
python tools/capture_comparison.py
python tools/capture_comparison.py --baseline
実行時に必要な日本語字形は同梱。PillowやOSフォントはプレイには不要です。
字形再生成だけ、PillowとNoto Sans CJKがある環境でpython tools/build_font.pyを使います。

解の記録（自分で考える場合はここで読むのを止めてください）
U=日差し、D=雨、L/R=雲移動。
A: UURRRRDD。B: UURRRRRDD。C: UUURRDRRDD。
A/B/Cの全到達状態数は36/64/85、最短8/9/10行動。
成功状態から先へ進まないルール、手数を除いた安定状態の全探索です。
深さで打切っていません。探索上限20,000には到達していません。手順の唯一性は要求しません。
Bの回復例: UURRRRDLURRDD。
1滴ずつの例: A URRRRDLLLLURRRRD、B URRRRRDLLLLLURRRRRD。
Cの安全な分割輸送: URRDLLUURRRRDD。

映像と原稿
media/box_weather_automatic_silent.mp4: 実際のPyxel描画、自動入力の機能確認、無音。
749枚をすべて30fpsで一度ずつ使い、24.966667秒。GIFの丸められた表示時間には依存しません。
media/runtime_*.pngは同じ実描画、native_*.pngはクラウドLinuxの実キー操作から保存。
NOTE.txt、X_POSTS.txtは公開前の日本語原稿。投稿はしていません。
EXPERIMENT.txtは門の条件だけを替える比較。技術、設計の仮説、人の面白さを区別します。
音は実装していません。実聴確認や人の楽しさ、Windows実機の成功は主張しません。

ライセンス
オリジナルコード・描画: LICENSE.txt（MIT）。
同梱日本語字形: Noto Sans CJK由来、assets/NOTO-LICENSE.txt（SIL OFL）。
