079 こだまする洞窟 — 五段階のPyxel教材

LESSON.mdを01から読み、lessons.jsonは同内容の五行データです。
Python 3.10以上を想定。作者が実行した環境はLinux / Python 3.12.14 / Pyxel 2.9.9。
初回の利用者セットアップ: python -m pip install -r requirements.txt
この制作・検査では既存環境を使い、インストールはしていません。
各01〜05の.pyは一ファイルだけを別フォルダへ移動・改名して実行できます。
ランタイム依存はPyxelだけ。assetsや元のmodel/controllerは読みません。

起動例
python 01_stone_roundtrip.py
python 05_public_forecast.py

各キーを押したら全操作キーを離してください。同時押しは不採用。
Space一刻、03以降Z送信/左右設定/1〜3洞窟、04以降Tab候補欄/上下候補/Z切替/A補助/Enter報告。
05のXは一刻でなく直前の判断へUndo。Bは苔待ち0刻と2刻を切替えて初期化。
Rは読込済みの同じコードで初期化。編集を反映するには保存→Esc終了→再実行。
全段階に原作MIT全文を含めています。LICENSE/LICENSE.txtとassets内のNoto/Pyxel通知を保持。
教材はASCII図形だけでNoto字形を使いません。音・表紙・連続再生・原作専用Controllerは省略。
03/04のState.report/reasonと共通UIの将来分岐は段階間の足場です。本文に説明があります。
05のモデルは原作定義・全A/B/Cデータを保持。公開予告は既知の証拠に両立する可能性の集合です。

再現検査（教材フォルダを作業ディレクトリにして実行）
python -B -S test_stages.py
python -B -S qa/cp932_check.py
python -B -S qa/exercise_checks.py
python -B -S exercises/01_distance.py
python -B -S exercises/02_moss.py
python -B -S exercises/03_window.py
python -B -S exercises/04_report.py
python -B -S exercises/05_wait_undo.py
SDL_AUDIODRIVER=dummy python -B qa/runtime_checks.py /絶対パス/新規runtime
SDL_AUDIODRIVER=dummy python -B qa/render_boundaries.py /絶対パス/新規boundary
python -B qa/reference_check.py /原作/079_echo_cave /絶対パス/新規reference
python -B qa/verify_freeze.py

出力先フォルダは新規のものを指定。環境変数の指定方法はOSとシェルに合わせてください。
個別の実描画: python 05_public_forecast.py --headless-smoke --demo-checkpoint --screenshot new.png --state-json new.json
初期画面は--demo-checkpointを外します。出力の親フォルダは既存、ファイルは未存在が必要です。
不正CLIはPyxel import前に拒否。相対出力先は起動した作業ディレクトリ基準に固定。
JSONもUTF-8で保存。CP932検査は実際に省略時のopen/Path.read_textをCP932へ変えて試験します。
ただしWindowsやmacOSのGUIを検証した意味ではありません。

qa/REVIEW.mdに作者の検査範囲。PNGは実Pyxel Linux headlessで合成キー入力により生成。
物理キーボード、ブラウザー、Windows/macOS実機、音の実聴、人による学習効果は未検証。
有限集合の比較であり、任意長のすべての入力履歴の正しさを証明するものではありません。
原作の作業前後SHA256一覧を保持。原作・他教材・公開Siteの変更はありません。
FROZEN_SHA256.jsonは自分自身とPythonキャッシュを除く全ファイルの正確な集合です。
練習でコードを編集すれば凍結検査が失敗するのは正常です。
