# 機能設計書 107-選択操作

## 概要

本ドキュメントは、K-Shoot Editor(譜面エディタ)における全選択/選択解除/選択反転/ランダム化/レーザー色反転の各選択操作機能の設計を記述する。

### 本機能の処理概要

本機能は、譜面エディタ上のオブジェクト選択に関する5つの操作コマンドを提供する。全選択(CMD_EDIT_SELALL)、選択解除(CMD_EDIT_CLEARSEL)、選択ノート左右反転(CMD_EDIT_SELFLIP)、選択ノートランダム化(CMD_EDIT_SELRANDOMIZE)、選択中レーザー色反転(CMD_EDIT_LASER_COLOR_SELFLIP)の各コマンドで構成される。

**業務上の目的・背景**: 譜面編集において、オブジェクトの一括選択、選択パターンの反転(ミラー)、ランダム配置生成は、効率的な譜面作成を支援する重要な機能である。

**機能の利用シーン**: 編集メニューから実行する。全選択(Ctrl+A)、選択解除(Ctrl+D)、選択反転(Ctrl+R)、ランダム化(Ctrl+Shift+R)のキーボードショートカットが設定されている。

**主要な処理内容**:
1. CMD_EDIT_SELALL: 全ノート、全アナログ、全スピン、全STOPを選択状態にする
2. CMD_EDIT_CLEARSEL: `*selinit`で全選択をクリア
3. CMD_EDIT_SELFLIP: 選択ノートのレーン番号を左右反転(0⇔3, 1⇔2, 4⇔5)、アナログのL/R反転(0⇔1)とX位置反転(50-x)、スピン方向反転
4. CMD_EDIT_SELRANDOMIZE: 選択ノートのレーン配置をランダムに並び替え(4レーンのランダム置換)
5. CMD_EDIT_LASER_COLOR_SELFLIP: 選択中アナログの色(L/R)のみを反転(位置は変更しない)

**関連システム・外部連携**: なし。

**権限による制御**: なし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 譜面エディタ | 主画面 | 編集メニュー > 全選択/選択解除/選択反転/ランダム化/レーザー色反転 |

## 機能種別

データ操作(選択状態管理・データ変換)

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cmd | 整数 | Yes | コマンドID | 有効なコマンド値 |
| selnote/selanalog/selspin/selstp | 整数配列 | 条件付 | 選択中オブジェクトのインデックス | SELFLIP/SELRANDOMIZE/LASER_COLOR_SELFLIP時に必要 |

### 入力データソース

メモリ上の選択状態配列と譜面データ配列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| selnote等 | 整数配列 | 更新された選択状態 |
| note.xxx.0 | 整数 | レーン番号(SELFLIP/SELRANDOMIZE時に変更) |
| analog.xxx.0 | 整数 | L/R種別(SELFLIP/LASER_COLOR_SELFLIP時に変更) |
| analog.xxx.3/4 | 整数 | アナログX位置(SELFLIP時に50-xで反転) |

### 出力先

メモリ上の譜面データ配列

## 処理フロー

### 処理シーケンス

```
1. CMD_EDIT_SELALL (全選択)
   ├─ *selinit で選択状態初期化
   ├─ selnotenum=notenum (全ノート選択)
   ├─ selanalognum=analognum (全アナログ選択)
   ├─ selspinnum=spinnum (全スピン選択)
   └─ selstpnum=stpnum (全STOP選択)

2. CMD_EDIT_CLEARSEL (選択解除)
   └─ *selinit (全選択をクリア)

3. CMD_EDIT_SELFLIP (選択反転)
   ├─ *undokakuho でUndo保存
   ├─ 選択ノートのレーン反転: 0⇔3, 1⇔2, 4⇔5
   ├─ 選択アナログの反転: L/R(0⇔1), X位置(50-x)
   └─ 選択スピンの方向反転

4. CMD_EDIT_SELRANDOMIZE (ランダム化)
   ├─ *undokakuho でUndo保存
   ├─ 4レーンのランダム置換テーブル(pturn)を生成
   ├─ 選択ノートのレーン番号を置換テーブルで変換
   └─ FXノート(4,5)はpturnlによるL/R入れ替え

5. CMD_EDIT_LASER_COLOR_SELFLIP (レーザー色反転)
   ├─ *undokakuho でUndo保存
   └─ 選択アナログの色(L/R)のみ反転: analog.xxx.0 = 1 - analog.xxx.0
```

### フローチャート

```mermaid
flowchart TD
    A[コマンド受信] --> B{コマンド種別?}
    B -->|SELALL| C[全オブジェクト選択]
    B -->|CLEARSEL| D[*selinit]
    B -->|SELFLIP| E[Undo保存]
    E --> F[レーン反転 0⇔3, 1⇔2]
    F --> G[アナログL/R・位置反転]
    G --> H[スピン方向反転]
    B -->|SELRANDOMIZE| I[Undo保存]
    I --> J[ランダム置換テーブル生成]
    J --> K[レーン番号置換]
    B -->|LASER_COLOR| L[Undo保存]
    L --> M[アナログ色反転のみ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-107-01 | レーン反転マッピング | BT: 0⇔3, 1⇔2、FX: 4⇔5 | CMD_EDIT_SELFLIP |
| BR-107-02 | アナログ位置反転 | X位置を50-xで計算(始点・終点の両方を反転) | CMD_EDIT_SELFLIP |
| BR-107-03 | ランダム重複排除 | ランダム置換テーブルは4レーンの完全な置換(重複なし) | CMD_EDIT_SELRANDOMIZE |
| BR-107-04 | 色のみ反転 | LASER_COLOR_SELFLIPはアナログの色(L/R)のみ反転し、位置は変更しない | CMD_EDIT_LASER_COLOR_SELFLIP |

### 計算ロジック

レーン反転(SELFLIP):
- BT: `switch note.0: case 0→3, case 1→2, case 2→1, case 3→0`
- FX: `case 4→5, default→4`
- アナログ: `analog.0 = 1 - analog.0`, `analog.3 = 50 - analog.3`, `analog.4 = 50 - analog.4`
- スピン: `spin.0 = spin.0/2*2 + 1 - (spin.0\2)` (方向ビットの反転)

ランダム化(SELRANDOMIZE):
- 4レーンの置換テーブル `pturn[4]` を重複なしで生成
- BTノート: `note.0 = pturn(note.0)` (レーン0-3)
- FXノート: `note.0 = 4 + ((note.0-4) ^ pturnl)` (pturnlは0か1のランダム)

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無操作 | SELFLIP/SELRANDOMIZE/LASER_COLOR時に選択なし | 何もせず続行 |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

特になし。

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

特になし。

## 備考

- SELFLIP(反転)はゲーム本体のMIRROR設定に相当する操作をエディタ上で行うものである
- SELRANDOMIZE(ランダム化)はゲーム本体のRANDOM設定に相当する操作である
- ランダム化は `randomize` 命令でシードを初期化してから実行される

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kshooteditor.hsp | `kshooteditor.hsp` | 450-454行目: 選択状態配列(selnote, selanalog, selspin, selstp)の宣言 |
| 1-2 | kshooteditor.hsp | `kshooteditor.hsp` | 47行目: `selnum` マクロ(selnotenum+selanalognum+selspinnum+selstpnum) |

#### Step 2: 各コマンドの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | kshooteditor.hsp | `kshooteditor.hsp` | 5610-5628行目: CMD_EDIT_SELALL |
| 2-2 | kshooteditor.hsp | `kshooteditor.hsp` | 5629-5631行目: CMD_EDIT_CLEARSEL |
| 2-3 | kshooteditor.hsp | `kshooteditor.hsp` | 5632-5674行目: CMD_EDIT_SELFLIP |
| 2-4 | kshooteditor.hsp | `kshooteditor.hsp` | 5675-5709行目: CMD_EDIT_SELRANDOMIZE |
| 2-5 | kshooteditor.hsp | `kshooteditor.hsp` | 5710-5721行目: CMD_EDIT_LASER_COLOR_SELFLIP |

**主要処理フロー(CMD_EDIT_SELFLIP)**:
- **5636-5657行目**: switch文によるノートレーン反転(0⇔3, 1⇔2, 4⇔5)
- **5660-5665行目**: アナログのL/R反転と位置反転(0→1, 50-x)
- **5667-5670行目**: スピン方向反転

**主要処理フロー(CMD_EDIT_SELRANDOMIZE)**:
- **5679行目**: `randomize` でランダムシード初期化
- **5681-5696行目**: 4レーンの重複なしランダム置換テーブル生成
- **5698-5706行目**: ノートレーン番号の置換

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

```
*OnCommand
    │
    ├─ CMD_EDIT_SELALL
    │   ├─ *selinit
    │   └─ 全オブジェクトインデックスを選択配列に設定
    │
    ├─ CMD_EDIT_CLEARSEL
    │   └─ *selinit
    │
    ├─ CMD_EDIT_SELFLIP
    │   ├─ *undokakuho
    │   ├─ ノートレーン反転(switch文)
    │   ├─ アナログL/R・位置反転
    │   └─ スピン方向反転
    │
    ├─ CMD_EDIT_SELRANDOMIZE
    │   ├─ *undokakuho
    │   ├─ randomize (シード初期化)
    │   ├─ pturn[4] 生成(重複なし置換)
    │   └─ ノートレーン置換
    │
    └─ CMD_EDIT_LASER_COLOR_SELFLIP
        ├─ *undokakuho
        └─ analog.0 = 1 - analog.0
```

### データフロー図

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

選択オブジェクト      ──────▶  SELFLIP/SELRANDOMIZE/     ───▶  変更された譜面データ
(selnote等)                   LASER_COLOR_SELFLIP              (note/analog/spin配列)
                              (レーン変換・位置反転)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kshooteditor.hsp | `kshooteditor.hsp` | ソース | 選択操作コマンド処理(5610-5721行目) |
