# 機能設計書 15-スコア・メダル表示

## 概要

本ドキュメントは、K-Shoot MANIA の選曲画面における「スコア・メダル表示」機能の設計を記述する。プレイカウント・クリア数・フルコンボ・パーフェクト・グレード・メダルを選曲画面上に表示する機能である。

### 本機能の処理概要

本機能は、`*reloadscore`サブルーチンでプレイヤー別スコアファイル(.ksc)を読み込み、`*refreshscore`サブルーチンで表示用データ(sc/gr/md/pc配列)を生成し、選曲画面の各楽曲エントリにスコア・グレード・メダル・プレイカウントを表示する。

**業務上の目的・背景**：プレイヤーが各楽曲のプレイ履歴を選曲画面上で一覧確認できるようにし、未プレイ曲やスコア更新余地のある曲を容易に把握できるようにする。メダル表示により、クリア状況・フルコンボ達成状況が視覚的に分かる。

**機能の利用シーン**：選曲画面で楽曲リストを表示している間、常に各楽曲のスコア・グレード・メダル・プレイカウントが表示される。難易度変更・プレイヤー切替・ゲージタイプ変更時に再読み込みされる。

**主要な処理内容**：
1. `*reloadscore`: 全楽曲のスコアファイル(.ksc)を読み込み、mscore配列に展開
2. `*refreshscore`: 表示範囲(selnow前後8曲)のスコア・グレード・メダル・プレイカウントをsc/gr/md/pc配列に設定
3. メダル判定: easy/normal/hardゲージの各クリア状態を統合してメダルランクを算出
4. スコア・グレード・メダル画像の描画(`*refreshsonginfo`内)

**関連システム・外部連携**：ファイルシステム(score/ディレクトリ)。

**権限による制御**：プレイヤー別にスコアデータが分離されている。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | 曲選択画面 | 主画面 | refreshscoreサブルーチンによる既存スコア・メダル・グレードの読み込みと選曲画面上への表示 |

## 機能種別

データ読み込み / 表示処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| players.cplayer | string | Yes | 現在のプレイヤー名 | - |
| effratetype | int | Yes | ゲージタイプ(-1:easy, 0:normal, 1:hard) | -1, 0, 1 |
| turn | int | Yes | TURN設定(0:normal, 1:mirror, 2:random...) | 0-4 |
| shortmode/longmode/analogmode | int | Yes | 各ノートモード(0:on, 1:off, 2:auto, 3:hide) | 0-3 |

### 入力データソース

- ファイルシステム: `score/[プレイヤー名]/[パッケージ]/[ファイル名].ksc`
- ファイルシステム: `courses/score/[プレイヤー名]/[ファイル名].ksc`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| mscore | int[SONG_MAX][4][9] | 全曲のスコアデータ(スコア/メダル/グレード/プレイカウント等) |
| sc | int[8] | 表示用スコア配列(selnow前後8曲分) |
| gr | int[8] | 表示用グレード配列 |
| md | int[8] | 表示用メダル配列 |
| pc | int[8] | 表示用プレイカウント配列 |

### 出力先

- 画面表示: 各楽曲エントリのスコア数値、グレード画像、メダル画像、プレイカウント

## 処理フロー

### 処理シーケンス

```
1. *reloadscore: mscore配列の初期化と全曲スコア読み込み
   a. 現在のゲージタイプ/TURN/ノートモードに基づくスコアキー文字列生成
      └─ 例: "normal,mirror,normal,on,on,on"
   b. 全曲(mnum)×全難易度(4)をループ
      ├─ スコアファイルパス決定(score/ or courses/score/)
      ├─ .kscファイル読み込み(noteload)
      └─ キー一致行からスコア値をパース(split "=", split ",")
   c. メダルランク算出(easy/normal/hardの各クリア状態を統合)
2. *refreshscore: 表示用配列への転写
   a. selnow前後8曲分のmscore値をsc/gr/md/pc配列にコピー
   b. ソートタイプ(sorttype)に応じた難易度選択
```

### フローチャート

```mermaid
flowchart TD
    A[*reloadscore開始] --> B[スコアキー文字列生成]
    B --> C[全曲×全難易度ループ]
    C --> D{.kscファイル存在?}
    D -->|Yes| E[noteload読み込み]
    E --> F[キー一致行検索]
    F --> G[スコア値パース mscore配列に設定]
    G --> H[メダルランク算出]
    D -->|No| I[mscore=-1のまま]
    H --> J[*refreshscore開始]
    I --> J
    J --> K[selnow前後8曲分を抽出]
    K --> L[sc/gr/md/pc配列に転写]
    L --> M[画面描画で使用]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-15-1 | スコアキー | `ゲージ,TURN,normal,BTモード,FXモード,レーザーモード`の6要素でスコアを一意に識別 | 常時 |
| BR-15-2 | メダルランク | 0:未プレイ, 1:easy失敗, 2:easyクリア, 3:easy完全, 4:normalクリア, 5:hardクリア, 6:FC, 7:パーフェクト | 常時 |
| BR-15-3 | スコア値 | mscore.*.*.0: スコア(0-10,000,000), mscore.*.*.1: メダル, mscore.*.*.2: グレード | 常時 |
| BR-15-4 | ゲージタイプ統合 | effratetype=-1(easy)の場合はeasyのみ参照、それ以外はnormal/hardの最高値を採用 | *reloadscore内 |
| BR-15-5 | プレイカウント | mscore.*.*.5以降にプレイ回数・クリア回数・FC回数・パーフェクト回数を格納 | 常時 |

### 計算ロジック

スコアキー文字列の生成:
```
stat8 = "{ゲージ},{TURN},normal,{BTモード},{FXモード},{レーザーモード}"
例: "normal,mirror,normal,on,on,on"
```

メダルランク算出ロジック:
```
if easy >= 1: medal = 1   (easyクリア)
if easy >= 2: medal = 2
if easy >= 3: medal = 3
if (easy<=1 or ゲージ!=easy):
    if normal >= 1: medal = 4 (normalクリア)
    if hard >= 1: medal = 5   (hardクリア)
if (easy<=2 or ゲージ!=easy):
    if normal >= 2: medal = 6
    if hard >= 2: medal = 6
if normal >= 3: medal = 7     (パーフェクト)
if hard >= 3: medal = 7
```

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

### 操作別データベース影響一覧

本機能ではデータベース操作は行わない。ファイルシステムの読み取りのみ。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 読み込み | score/[プレイヤー]/[パッケージ]/[ファイル名].ksc | SELECT相当 | スコアデータの読み込み |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | スコア未登録 | .kscファイルが存在しない場合 | mscore=-1(未プレイ)として扱う |
| - | キー不一致 | 現在の設定と一致するスコアキーが存在しない場合 | mscore=-1のまま |

### リトライ仕様

なし。

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

トランザクション管理は不要。読み取り操作のみ。

## パフォーマンス要件

- 全曲×全難易度のスコアファイル読み込みは選曲画面初期化時に一括実行される
- 楽曲数が多い場合(数百曲以上)、初期化に数秒かかる可能性がある
- *refreshscoreは表示範囲(8曲分)のみを処理するため高速

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

特になし。ローカルファイルシステムの読み取り操作のみ。

## 備考

- .kscファイルのフォーマット: `キー=スコア,メダル,グレード,プレイ回数,...` (改行区切り)
- スコアキーは設定変更のたびに変わるため、異なる設定でのスコアは別々に管理される
- *reloadscoreは設定変更時・プレイヤー切替時に再実行される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | select.hsp | `src/scene/select.hsp` | mscore配列[SONG_MAX][4][9]: [曲][難易度][0:スコア/1:メダル/2:グレード/3:プレイ回数/5-8:詳細カウント] |
| 1-2 | select.hsp | `src/scene/select.hsp` | sc/gr/md/pc配列[8]: 表示用(selnow前後8曲分) |

**読解のコツ**: .kscファイルの各行は「キー=値」形式。キーは設定の組み合わせ文字列、値はカンマ区切りの数値列。

#### Step 2: *reloadscore を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | select.hsp | `src/scene/select.hsp` | 4841-4956行目の*reloadscoreサブルーチン |

**主要処理フロー**:
1. **4842行目**: mscore配列初期化
2. **4843-4867行目**: スコアキー文字列の生成(stat5〜stat8)
3. **4876-4934行目**: 全曲×全難易度ループでのスコア読み込み
4. **4888-4893行目**: スコアファイルパスの決定(コース用/通常)
5. **4897-4934行目**: .kscファイル読み込みとキー一致行のパース
6. **4937-4953行目**: メダルランク算出

#### Step 3: *refreshscore を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | select.hsp | `src/scene/select.hsp` | 4958-4988行目の*refreshscoreサブルーチン |

**主要処理フロー**:
- **4959-4961行目**: sc/gr/md/pc配列初期化
- **4963-4987行目**: selnow前後8曲のmscore値を各配列に転写

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

```
*reloadscore (4841行目)
    |
    +-- mscore配列初期化 (4842行目)
    +-- スコアキー文字列生成 (4843-4867行目)
    +-- 全曲ループ (4876行目)
    |       +-- スコアファイルパス決定 (4888-4895行目)
    |       +-- .kscファイル読み込み (4897-4900行目)
    |       +-- キー一致行パース (4901-4934行目)
    |       +-- メダルランク算出 (4937-4953行目)
    |
*refreshscore (4958行目)
    |
    +-- 表示用配列初期化
    +-- selnow前後8曲の転写 (4963-4987行目)
```

### データフロー図

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

score/[player]/[pkg]/[file].ksc --> noteload読み込み --> mscore配列
                                         |
effratetype/turn/mode変数 ---------> スコアキー生成 --> stat5-stat8
                                         |
                                    キー一致検索・パース
                                         |
                                    メダルランク算出
                                         |
                                    *refreshscore ---------> sc/gr/md/pc配列
                                         |
                                    *refreshsonginfo ------> 画面描画
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| select.hsp | `src/scene/select.hsp` | ソース | *reloadscore/*refreshscoreサブルーチンによるスコア読み込み・表示データ生成 |
| *.ksc | `score/[プレイヤー]/[パッケージ]/[ファイル名].ksc` | データ | プレイヤー別スコアファイル |
| *.ksc | `courses/score/[プレイヤー]/[ファイル名].ksc` | データ | コーススコアファイル |
