即席オーケストラ：五段階のPyxel教材

必要環境: Python 3.11以上 / Pyxel 2.9.9。
五つの.pyは各一本だけでも実行できます。外部画像・音声・原作ファイルは不要。
配布時はLICENSE/第三者noticeも一緒に保持してください。
学習はLESSON.md、構造化本文はlessons.json、原作との差はlesson_meta.json。

Windowsの起動例:
py -3 -m venv .venv
.venv\Scripts\python -m pip install -r requirements.txt
.venv\Scripts\python 01_score.py
.venv\Scripts\python 05_performance.py

macOS/Linuxの起動例:
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python 01_score.py
.venv/bin/python 05_performance.py

上記は利用者向け手順です。今回の制作検査では既存環境を使用し、新たなソフトを導入していません。
検査環境はLinux/Python 3.12/Pyxel 2.9.9。Windows/macOS GUIの実測ではありません。
ZIP内のまま実行せず全展開し、README.txtのあるフォルダへ移動してください。

01_score.py: 元譜の時刻と音高。Spaceで手動カーソルを進める。
02_phases.py: 隣のKは+1、Bは-1。配置と交換、元譜への一回だけの位相。
03_ensemble.py: 同時発音と全員休符を数え、原作Aの四条件を判定。
04_reservations.py: 整数frameの無音試奏、次小節の予約、停止と再同期。
05_performance.py: 四小節の本番、配置だけのUndo、結果からの再編集。

操作:
左右: 選択席。上下: 候補奏者。Z: 配置。02以降で使えます。
候補の順はK/B/F/U/.。既にいる奏者は交換、.は空席です。
Space: 01は読む列を一つ進める。04/05は試奏/停止。
P: 04/05で時計を止め、再度Pで小節頭から30frame数え直す。
Enter: 05の本番。X: 05の配置Undo。R: 時計と履歴を含む全初期化。
Esc: 終了。通常の操作は一キーずつ、全て離してから次へ。
新しいRは優先。試奏中はキーの解放待ちでも時計が進みます。

最短の成功確認: 05起動→右→下→Z→Enter。
K/F/B/./Uになり、モデル350frame後にWON。各キーを離すこと。
30frameカウントイン+80frame×4小節。30fps指定ですが現実時間は環境で変わります。
音は意図的に出ません。音符の時刻・音高・同時発音を図で学ぶ教材です。

重要な規則:
元譜の(time,pitch)へ隣席の位相を一回だけmod8で適用。連鎖・累積なし。
予約中もCURRENTの譜面を演奏し、上の席とTARGETは次小節の予測を示します。
小節末にphase=0へ戻った次のframeの先頭で予約を確定します。
Undoは配置だけを戻し、tick/phase/barsは巻き戻しません。Rなら全初期化。
本番/一時停止中は編集とUndoをロック。Spaceで本番を止めて編集できます。

困ったとき:
No module named pyxel: 起動に使う同じ仮想環境のpythonでrequirements.txtを導入。
画面が開かない: GUI/OpenGL対応環境を確認。headless成功は全OSのGUI保証ではありません。
音が出ない: この教材の仕様。実音の機能は原作の次に読む関数へ。
キーが効かない: 画面へフォーカスし、全操作キーを離してから一つ押す。
RELEASE ALL KEYS: 同時操作を拒否。Rも新しい押下で使います。
SAME: 元の配置と同じ。履歴は増えません。
LOCKED: 本番/一時停止中。Spaceで本番停止、Pで一時停止解除。
TOO_FEW: 本番には三人以上必要。自由試奏は何人でも可能。
予約がすぐ反映しない: 現在小節の終わりを待つ仕様。停止ならその場で確定。
位相が合わない: すぐ隣だけを数え、KとBの両方なら相殺。空席を飛び越えません。
WONにならない: Aの三人以上、0/4に音、7休符、同時二人以下を全て確認。
譜面の音高が移動後に違う: 時刻と音高の組を一緒にsortedしてください。

標準ライブラリ検査:
python -B test_stages.py
原作なしでも同梱fixtureの501配置を照合し、35成功+任意1件skip。PYXEL056_ORIGINALに原作フォルダ/model.pyを指定すると直接照合。
原作は読み取ってコピーを実行し、元ファイルへ書き込みません。
原作ありは36成功。501配置と04/05合計12,000操作、完走境界を比較します。
音声再生、全入力履歴、B/C、原作UI全体の等価性は対象外。

実Pyxel検査:
SDL_AUDIODRIVER=dummy python -B qa/render_check.py
初期5/到達点5/改名単一ファイル5の合計15描画。
例: python 04_reservations.py --headless-smoke --demo-checkpoint --screenshot check.png
QA専用--qa-framesは2〜600。デモより短い長さ、headlessなしのQA指定などは起動前に拒否。
画像やログの所在と限界はqa/REVIEW.md。凍結検査はpython -B qa/verify_freeze.py。

原作との違い:
Aのみ、全段階無音、ASCII表示。B/C、表紙、日本語glyph、合図なし比較、音声、保存/再生機能なし。
LICENSE.txtを原文のまま保存しLICENSEも同一内容。各段階.pyに全文を収録。
assetsの原作noticeを保存。Noto字形・外部録音・既存楽曲は教材に使っていません。
未確認: 音声の聴取、OSキー入力、Windows/macOS GUI、ブラウザー、人の理解度や遊び心地。
