068 小さな博物館の夜 / 日本語5段階チュートリアル

架空の離散来客モデルです。現実の観客の行動や教育効果を実証するものではありません。
原作Cだけを使い、配置→隣接タグ→候補順位→三人の巡回→Undo/比較/再現保存を学びます。
説明はLESSON.md、機械可読本文はlessons.json、範囲・差分はlesson_meta.jsonです。
01〜03は巡回前の練習、04は履歴/比較/保存なし、05が原作Cの純粋モデルを再現します。

準備
Python 3.10以上とPyxel 2.9.9。検証環境はPython 3.12.14 / Pyxel 2.9.9。
python -m venv .venv
Windows: .venv\Scripts\python -m pip install -r requirements.txt
Linux/macOS: .venv/bin/python -m pip install -r requirements.txt
以下のpythonは用意した仮想環境のPythonへ読み替えてください。
Windows/macOS実機GUI、音声、人間の試遊は未検証です。

起動
python -B 01_exhibits.py
python -B 02_context_tags.py
python -B 03_choice_trace.py
python -B 04_visitors.py
python -B 05_replay.py
どの.pyも単独で動きます。原作・他の段階・assets・JSONの読込は不要です。
Pyxelはmain内でだけimportするため、モデル試験は標準ライブラリだけで動きます。

操作
矢印: 台を選ぶ。編集中Space: 品候補。Z: 置く/同じ品を戻す。R: 初期化。Esc: 終了。
03〜05の編集中Tab: 予告する来客を変更。
04〜05: Enterで開館/編集へ復帰。開館中Spaceで一つの観覧か退館。Pで停止。
05: Xで配置一手をUndo。巡回中/終了直後なら開館前へ巡回を丸ごと戻す。
05: Bで左右だけの隣接規則へ切替、配置とログは初期化。もう一度Bで通常版。
全操作は1キーずつ。全操作キーを離してから次へ。同時押しは拒否。

重要なルール
六品から四品。少ない配置も編集可能ですが、開館には四品必要。
配置済みの品を移すと元の台は空。置き先の旧品は収蔵庫へ戻り、位置交換はしません。
未取得の興味タグ2点、他の新タグ1点。魅力最大、同点は費用の少ない方、さらに台番号。
費用=マンハッタン距離+観覧1。興味と目標タグは別。目標取得だけでは巡回を終えません。
三人全員退館で完了。三人中二人の目標タグ取得で基本達成。初期Cは3/3です。

保存（05のみ）
python -B 05_replay.py --save-record "出力 記録/巡回.json"
起動だけではファイルを作らず、Sで親フォルダーとJSONを作成します。
同名ファイルへは上書き。未開館・巡回途中の記録も保存可能。保存は成功判定とは別です。
Sはゲーム状態を進めません。記録は原作Cの意味入力と再現用状態・ハッシュです。
画面からの読込機能はありません。replay関数と試験で検証できます。

検査
python -B -S -m unittest -v test_stages.py
python -B tools/render_qa.py
python -B tools/verify_original.py "/原作/068_night_museum"
python -B tools/check_freeze.py
通常の試験に原作フォルダーは不要。fixtureは変更していない原作Cから生成しました。

単体headless例
python -B 04_visitors.py --headless-smoke --screenshot initial.png --report initial.json
python -B 04_visitors.py --demo-checkpoint --screenshot checkpoint.png --report checkpoint.json
headless二モードは同時指定不可。screenshot/reportはheadless時だけ有効。
PNGは.png、reportとsave-recordは.json。出力パスは呼出元cwd基準、明示UTF-8。
不正引数はPyxel起動前にexit 2。save-recordは明示のSでだけ書くのでデモでは保存しません。
reportは描画証跡で、replay用の保存記録とは別形式です。

権利
LICENSEは原作MIT全文を保持し、各.py冒頭にも全文を埋込。
assets/NOTO-LICENSE.txtとassets/PYXEL-LICENSE.txtも原文を保持。
教材画面はPyxel標準ASCIIと図形。Noto字形データは使いません。
QA.txt、qa/validation.jsonを見て検証済み範囲と未確認範囲を区別してください。
