# 機能設計書 38-TURN設定適用

## 概要

本ドキュメントは、K-Shoot MANIAのゲームプレイにおけるTURN設定適用機能の設計を記述する。MIRROR/RANDOM/S-RANDOM/H-RANDOMによるレーン並び替え機能である。

### 本機能の処理概要

**業務上の目的・背景**：プレイヤーが同じ譜面を異なるレーン配置でプレイすることで、練習効果の向上や新鮮なプレイ体験を得られるようにする。MIRROR（左右反転）、RANDOM（ランダム並び替え）の2種類のTURN設定をサポートする。

**機能の利用シーン**：選曲画面またはオプション設定画面でTURN設定（turn変数）を変更し、ゲームプレイ開始時にprepareTurnOptions関数が呼び出されて、レーンの並び替えパターンが決定される。

**主要な処理内容**：
1. turn=0（OFF）: 並び替えなし（pturnl=0, pturna=0）
2. turn=1（MIRROR）: BTレーン反転（pturnl=1）、アナログレーン反転（pturna=1）
3. turn=2（RANDOM）: BTレーン4列のランダムシャッフル（pturn配列に重複なし順列）、レーザーL/Rランダム入れ替え（pturnl=rnd(2)）、アナログ方向ランダム入れ替え（pturna=rnd(2)）

**関連システム・外部連携**：選曲画面（select.hsp）でのturn設定変更、オプション設定画面（option.hsp）での設定。

**権限による制御**：turn変数（0=OFF, 1=MIRROR, 2=RANDOM）で制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 5 | ゲームプレイ画面 | 主画面 | prepareTurnOptionsによるMIRROR/RANDOM/S-RANDOM/H-RANDOMレーン並び替え |
| 3 | 曲選択画面 | 補助画面 | turn設定の変更操作 |

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| turn | int | Yes | TURN設定（0=OFF, 1=MIRROR, 2=RANDOM） | 0, 1, 2のいずれか |

### 入力データソース

config.iniまたは選曲画面でのインラインオプション変更から設定されるturn変数。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| pturn | int[4] | BTレーン並び替えマップ（0-3の順列） |
| pturnl | int | レーザーL/R入れ替えフラグ（0=通常, 1=反転） |
| pturna | int | アナログ方向入れ替えフラグ（0=通常, 1=反転） |

### 出力先

- メモリ: 譜面読み込み処理（parseKSHChartBody）でのレーン並び替えに使用

## 処理フロー

### 処理シーケンス

```
1. randomize（乱数シード初期化）
2. pturnl=0, pturna=0（初期化）
3. turn値に応じた処理
   ├─ turn=1（MIRROR）: pturnl=1, pturna=1
   └─ turn=2（RANDOM）:
       ├─ pturn[0-3]に重複なしランダム順列を生成
       ├─ pturnl=rnd(2)（0 or 1のランダム）
       └─ pturna=rnd(2)（0 or 1のランダム）
```

### フローチャート

```mermaid
flowchart TD
    A[prepareTurnOptions] --> B[randomize]
    B --> C[pturnl=0, pturna=0]
    C --> D{turn?}
    D -->|0| E[並び替えなし]
    D -->|1| F[pturnl=1, pturna=1]
    D -->|2| G[RANDOM処理開始]
    G --> H[pturn配列に重複なし順列生成]
    H --> I["pturnl=rnd(2)"]
    I --> J["pturna=rnd(2)"]
    E --> K[完了]
    F --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-01 | MIRROR | BTレーンを左右反転（pturnl=1）、アナログも反転（pturna=1） | turn=1 |
| BR-38-02 | RANDOM BT | BT4列を重複なしのランダム順列で並び替え | turn=2 |
| BR-38-03 | RANDOM LASER | レーザーL/Rをランダムに入れ替え（50%確率） | turn=2 |
| BR-38-04 | RANDOM ANALOG | アナログ方向をランダムに入れ替え（50%確率） | turn=2 |
| BR-38-05 | 重複なし保証 | RANDOM時のBTレーン順列は全て異なる値（Fisher-Yates風アルゴリズム） | turn=2 |

### 計算ロジック

```
// MIRROR
if turn == 1:
    pturnl = 1  // レーザー反転
    pturna = 1  // アナログ反転

// RANDOM (重複なし順列生成)
if turn == 2:
    for i = 0 to 3:
        repeat:
            pturn[i] = rnd(4)
            if pturn[i]が既存値と重複しない: break
    pturnl = rnd(2)  // 0 or 1
    pturna = rnd(2)  // 0 or 1
```

## データベース操作仕様

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

特にエラーケースなし。

### リトライ仕様

リトライは不要。

## トランザクション仕様

トランザクション管理は不要。

## パフォーマンス要件

プレイ開始時に1回のみ実行。パフォーマンス上の懸念なし。

## セキュリティ考慮事項

特になし。

## 備考

- prepareTurnOptionsはstart_play関数（play_init.hsp）内で譜面読み込み前に呼び出される
- pturn配列はparseKSHChartBody内でノートのレーン番号を変換する際に参照される
- 機能一覧にはS-RANDOM/H-RANDOMの記載があるが、コード上はturn=2のRANDOMのみが実装されている

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: prepareTurnOptions関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | play_game_logic.hsp | `src/scene/play/play_game_logic.hsp` | prepareTurnOptions関数（64-93行目）の全体ロジック |

**主要処理フロー**:
- **65行目**: `randomize` - 乱数シード初期化
- **66-67行目**: `pturnl=0, pturna=0` - 初期化
- **68-71行目**: MIRROR処理（turn=1）
- **72-92行目**: RANDOM処理（turn=2）、重複なし順列生成アルゴリズム

**読解のコツ**: 72-88行目の2重ループは、Fisher-Yates風の重複排除ロジック。内側のrepeatで乱数を生成し、既存値と重複した場合（stat1=1）はやり直す。

#### Step 2: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | play_init.hsp | `src/scene/play/play_init.hsp` | start_play関数（44行目）: `prepareTurnOptions`呼び出し |

### プログラム呼び出し階層図

```
start_play (play_init.hsp)
    |
    +-- prepareTurnOptions (play_game_logic.hsp:64-93)
    |       +-- turn=0: 何もしない
    |       +-- turn=1: pturnl=1, pturna=1
    |       +-- turn=2: pturn[]ランダム生成, pturnl/pturnp=rnd(2)
    |
    +-- parseKSHChartBody
            +-- pturn配列でノートレーン変換
```

### データフロー図

```
[入力]                    [処理]                    [出力]

turn (設定値) ────> prepareTurnOptions       pturn[4]  ──> 譜面読み込み
                     ランダム順列生成        pturnl    ──> レーザー反転
                     MIRROR判定              pturna    ──> アナログ反転
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| play_game_logic.hsp | `src/scene/play/play_game_logic.hsp` | ソース | prepareTurnOptions関数の実装 |
| play_init.hsp | `src/scene/play/play_init.hsp` | ソース | prepareTurnOptionsの呼び出し |
| play_chart_load.hsp | `src/scene/play/play_chart_load.hsp` | ソース | pturn配列によるレーン並び替えの適用 |
| select.hsp | `src/scene/select.hsp` | ソース | turn変数の設定（インラインオプション） |
| option.hsp | `src/scene/option.hsp` | ソース | turn変数の設定（オプション画面） |
