078 夜の花壇設計 / 5段階教材

必要条件
Python 3.11以上、Pyxel 2.9.9。各.pyは独立して動きます。
標準ライブラリ以外はPyxelだけ。画像・音・日本語フォントは不要。
説明は日本語、ウィンドウはPyxel内蔵ASCII文字です。音は使いません。
検証した実環境の版はQA.txtを参照。Python 3.11実機とWindows/macOS GUIは未確認。

導入と起動（このフォルダーへ移動して実行）
Windows PowerShell:
  py -3 --version
  py -3 -m venv .venv
  .\.venv\Scripts\python.exe -m pip install -r requirements.txt
  .\.venv\Scripts\python.exe 01_placement.py
  .\.venv\Scripts\python.exe 05_design_files.py
表示されたPythonが3.11未満なら、3.11以上を導入してからやり直します。

macOS Terminal / Linux:
  python3 --version
  python3 -m venv .venv
  .venv/bin/python -m pip install -r requirements.txt
  .venv/bin/python 01_placement.py
  .venv/bin/python 05_design_files.py
.venvの有効化は不要です。配布を開くときは.zipを先に展開してください。
空白を含む移動先は引用符で囲みます。例: cd "夜の花壇 教材"
GUIには表示環境が必要。LinuxのPyxel/SDL起動エラーは表示環境や不足ライブラリを確認。
この教材の制作中は既存の検証環境を使い、新しいパッケージはインストールしていません。

順番
01_placement.py: 昼の黄色1種で置く/抜く。最大6本、石5・6。
02_two_views.py: 昼夜、6色、同じ配列から二つの見え方。
03_connections.py: 咲く花だけの縦横連結。
04_editor.py: 原作Bの任意の依頼判定と継続編集、リセット/終了確認。
05_design_files.py: Undo、三枠の明示保存/読込、上書き確認、厳密な検証。
詳しい本文はLESSON.md、構造化した5授業はlessons.json。
隣の段階との実際のコード差分はdiffs/にあります。

操作
矢印: 選択。Z: 植える。Backspace: 抜く。
02以降: Tabは昼D/夜Nの筆、同種へZは色、Spaceは昼夜の強調。
04以降: Enterは提出。R/Escの確認はZ、取消はX/Esc。
05: XはUndo。S/L → 左右または1〜3で枠 → Z確定、X取消。
既存保存枠への上書きは、OVERWRITE?でもう一度Z。
必ず各キーの間で全キーを離します。長押しと同時押しは連続操作になりません。
01〜03のRとEscは即実行、04以降は確認付きです。

依頼は創作の必須条件ではありません
原作B「二つの小道」: 6本ちょうど、D3本で1まとまり、N3本で1まとまり。
縦横だけ。閉じた花も斜めも橋渡しにならず、空集合は0まとまり。
昼夜切替は時間経過ではなく、配置を変えません。成長も枯死もありません。
未達の自由な案も05で保存可能。成功後も編集を続けられます。
A/Cの依頼、日本語字形、表紙/説明、表示比較、録画、元ゲームの記録は省略。

保存と安全
05_design_files.pyの隣のtutorial_saves_078/に、design_1.json〜design_3.json。
作業中のカレントディレクトリは保存先に使いません。
Sから枠を確定するまでファイルもフォルダーも作りません。自動保存はありません。
再起動時は空から始め、Lで選んだときだけ読み込みます。
保存はUTF-8の一時ファイルを経由。確認前の既存枠の上書きを拒否します。
親ディレクトリを含むsymlinkと、保存ファイルのsymlinkは拒否します。
教材の保存形式は原作と非互換。原作savesへコピーしないでください。
Xは編集・提出・読込を戻します。ディスク上の保存を取り消す機能ではありません。
Rは現在の盤と履歴だけを消し、保存済みファイルを削除しません。
2048操作で編集を止めます。Sで保存→R確定→L読込で短い履歴から再開できます。
SpaceとUndoは上限でも利用可能。保存回数の上限ではありません。

FILE ERRORが出たら
- 読込: 枠が空でないか、JSONがUTF-8か、20000バイト以下かを確認。
- 不正な版、型、値、12枠の長さ、石への花、7本以上、改ざん判定は拒否。
- 保存: 展開先の書込権限、空き容量、同期サービスのロックを確認。
- symlinkの場所を避け、この教材を通常の書込可能なローカルフォルダーへコピー。
- 新規作成はハードリンクを使うため、非対応ファイルシステムでは安全側に失敗します。
  通常のローカルNTFS/APFS/ext4等への移動を試してください。対象OSでの実測は未確認。
失敗した読込は現在の状態を変更しません。X/Escで取消し、別枠や保存先を確認。
上書きに失敗しても既存ファイルを先に削除しません。未保存の編集を閉じないでください。
JSONを手修正したときは判定も再計算が必要なので、通常は画面から編集し直します。
復旧のために既存の大切なファイルを削除しないでください。

検査
  .venv/bin/python -B -m unittest -v test_stages.py
  .venv/bin/python -B run_qa.py
Windowsは先頭を .\.venv\Scripts\python.exe に置換。
通常テストはこの教材だけで動きます。任意の外部原作比較はスキップされます。
直接比較だけを追加する場合、PYXEL078_MODELに原作model.pyのパスを設定します。
例（POSIX）: PYXEL078_MODEL="/your/original/model.py" .venv/bin/python -B -m unittest -v test_stages.py
原作は読み取り専用でimportし、-Bでbytecodeを生成しません。
run_qa.pyはqaの画像/ログを再生成します。作成済みのfreezeは再検証してください。
保存のテストは一時ディレクトリ内だけ。通常の保存ファイルを検査に流用しません。

権利
LICENSEと各.py先頭は原作のMIT全文をそのまま保持しています。
その中の第三者例外の参照を保つためassets/NOTO-LICENSE.txtも同梱。
この教材はNoto由来の字形データを使用・同梱していません。
Pyxelはrequirements.txtで別途導入する依存ソフトです。
