090 一夜の探検隊 — 五段階で作るPyxel教材

動作環境
Python 3.11以降、Pyxel 2.9.9。モデルとテストは標準ライブラリのみです。
教材フォルダへ移動してから実行してください。以下のpythonはPython 3.11以降です。

準備（最初の一回）
python -m venv .venv
Windows: .venv\Scripts\activate
macOS/Linux: source .venv/bin/activate
python -m pip install -r requirements.txt

起動
python 01_walk.py
python 02_leaders.py
python 03_tools.py
python 04_camps.py
python 05_undo.py

各段階は独立した一つの.pyです。他の段階やassetsがなくても起動できます。
別フォルダへコピーして改名できます。Pyxelの導入は必要です。
全文はLESSON.md、構造化本文はlessons.json。差分はdiffs/01_02.diffから順です。

五段階
01: 一人・平地・体力6で入力と状態を学ぶ。
02: 原作Aの三人と得意地形。道具/休憩なし。
03: 後衛の道具と一人二個上限。配り直しは出発前のみ。
04: 原作A/B/Cの全地形と分岐、二/四区間後の一回休憩。初期ルートB。
05: 歩行直前の全状態へUndo。先頭本人の道具も使える比較規則。

操作（各キーを離してから押し直します）
Enter: 一歩進む。04以降の休憩待ちは選択中の一人を回復。
1/2/3: 人を選ぶ。L: 選んだ人を先頭にする（02以降）。
T: 道具を次へ。G: 選んだ人へその道具を渡す（03以降）。
Up: 次の分岐を選ぶ。C: ルートをB→C→Aと替えて初期化（04以降）。
X: 一つ前の歩行直前へ戻す。V: rear/self規則を替えて初期化（05のみ）。
R: 初期化。Esc: 終了。C/V/Rは進行を保存せず即時初期化します。

主な規則
先頭だけが地形の負担を払い、得意分野と後衛の対応道具で各1軽減。
体力0の後衛は支援可、先頭は負担0でも不可。足りなければ全状態不変。
道具は一人二個まで、04/05は区間0/2/4で配布可能。
二/四区間後の休憩で一人だけ+2、上限5。回復と歩行は別のEnterです。
六区間目の到着を全員0の救援より優先します。死亡・締切・乱数なし。
Undoは歩行単位。歩行後の回復/配布も、その歩行と一緒に取り消します。

単体テスト（Pyxelも原作も不要）
python -B test_stages.py

任意の原作照合
原作のmodel.py/controller.pyがある090_night_expeditionフォルダを
環境変数PYXEL_ORIGINAL_090に指定し、同じテストを実行します。
PowerShell: $env:PYXEL_ORIGINAL_090="C:\path\to\090_night_expedition"
macOS/Linux: export PYXEL_ORIGINAL_090="/path/to/090_night_expedition"
指定なしは原作比較四件だけSKIP。通常テストは省略せず、取得通信もしません。
-Bは__pycache__作成を抑え、原作の読み取りのみを行います。

実Pyxelの自動描画（導入済みPyxelが必要）
python -B qa/render_check.py
全段階の初期/操作後/改名一ファイル起動の画像・状態・結果をqaへ出力。
子プロセスでSDL_AUDIODRIVER=dummyを設定します。
例: python 03_tools.py --headless-smoke --demo-checkpoint --screenshot qa/check.png
状態も保存: --state-output qa/check.json
--framesの下限は初期4、デモ2×操作数+4。上限600。小さすぎる値は拒否。
QAオプションには--headless-smoke必須、画像は.png、状態は.jsonです。
不正値はPyxel初期化前、argparse終了コード2で拒否します。

最終ファイル照合
python -B qa/verify_freeze.py
FROZEN_SHA256.json自身以外の全配布ファイル集合とSHA-256を検証します。
再描画/編集で証拠を変更すると照合は失敗します。元の凍結物と区別してください。

原作との差
教材は英数字480×352、直接キー操作、入力の構文エラーを安全に拒否。
原作の日本語描画、表紙/停止、確認ダイアログ、イベント保存は省略。
04/05で日本語の一言をvoices(state)として再現しますが画面へは描画しません。
モデル規則の一致と、操作や画面全体の一致を混同しないでください。

権利
LICENSE.txtは原作の原文、LICENSEは同じバイトの別名。
全五段階の先頭にも原作ライセンス全文をコメントで保持。
assets/glyphs.json、NOTO-LICENSE.txt、PYXEL-LICENSE.txtは元の同一バイトです。
実行時にassetsは不要。字形のSIL OFL 1.1とコードのMITは別です。

検査と限界
qa/REVIEW.md、portable-tests.txt、full-tests.txt、render-results.jsonを参照。
実Pyxel Linuxヘッドレスで自動意味入力を与えた証拠です。
OSキー入力、音の実聴、人の理解・面白さ、Windows/macOS実機、ブラウザは未検証。
