# 試合の前後:舞台裏のインテリジェンス
> [!abstract] **コンセプト:情報戦で優位に立つ**
> コート上の技術だけでなく、対戦前後の「データ分析」もゲームの楽しみ。
---
## 🔍 試合前のテクニック:Yボタンの重要性
マッチングが完了し、キャラクターが表示された瞬間に勝負は始まっている。ここで `Yボタン` を押し、相手のプロフィールを確認することが生存戦略の第一歩となる。

<span class="mxt-caption"> ▲ ゲロエグ トップランカー(勝率90%)の例</span>
### 重点チェック項目
- **今シーズン W-L & ランキング:** 相手の現在の勢いと、どのランク帯の住人かを確認。
- **トータル W-L:** プレイヤーとしての熟練度。数千勝している猛者は、プレイスタイルごとの対策を熟知している。
- **能力値:** プレイスタイルと、弱点をつくならどこになるかのヒントを得る。
これらを把握することで、「相手が格上ならリスクを承知で攻める」「格下ならミスを待つ」といった試合全体のプランニングを、開始前の数十秒で行うことが可能になる。スマホで写真を撮って、すぐ見れるようにもしている。実際には試合中になかなか見られないのだけれど。
---
## 🤖 試合後のテクニック:Geminiによる統計ログ化
試合前には「Player Info(能力値)」、試合後には「Match Statistics(試合後スタッツ)」のスクリーンショットを撮影する。これを **Gemini** に放り込み、Obsidian管理用のYAMLデータへ変換する。
### ログ化のフロー
1. **撮影:** 試合結果の画面を撮影。
2. **解析:** 専用プロンプトを適用したGeminiに画像を渡す。
3. **正規化:** 左右の配置に関わらず、必ず `[opp, me]` の順序でデータを抽出。
4. **蓄積:** ObsidianにYAMLとして貼り付けておき、区切りのいいところでLLMに渡してスタッツ分析(1stサーブ成功率や、特定のスキルを持つ相手への勝率など)をする。
---
## 🛠 秘伝:Gemini ログ化アシスタント(プロンプト)
私が実際に使用している、情報の欠落や構造の崩れを防ぐための「壊れにくいYAML固定フォーマット版」プロンプト。
### Gemini への指示書(Gem)
> [!info]- 🤖 Gemini プロンプト全文を表示</summary>
>
> ~~~
>
> ## TopSpin 2K25 試合ログ化アシスタント(壊れにくいYAML固定フォーマット版)
>
> あなたは「TopSpin 2K25の試合ログ化アシスタント」です。
> 添付画像(複数可)には、能力値・スキル・試合後スタッツ・スコア・会場・試合時間・相手情報が表示されています。
> 画像から情報を正確に抽出し、指定のYAMLフォーマットで出力してください。
>
> ### 🚨 【最重要】ファイル名の抽出手順
> 1. **画像を見る前にテキストを読む**: ユーザー入力は `fileName: "IMG_XXXX.jpg"` というテキストと、その下の画像で構成されています。
> 2. **テキストからのコピー**: `img` 配列の値は、画像データから生成せず、必ず**ユーザー入力テキストにある `fileName:` の値**をコピーペーストしてください。
> 3. **システム名の禁止**: `image_0.png`、`image_1.png`、`captured_file.jpg` はシステム内部名であり、これを出力することは**禁止**です。必ず `IMG_` 等で始まるオリジナルの名前を使用してください。
>
> ### 入力画像の前提
> - 原則として「画像2枚=1試合」
> - 1枚: 能力値とスキル(相手のランキングや勝敗数も載ることが多い)
> - 1枚: MATCH STATISTICS(試合後スタッツ)
> - ただし同一試合の別画面だと判断できる場合のみ、同一試合として統合してよい
> - 複数試合の写真(4枚以上)のこともある
> - 対戦相手の名前から、いくつの試合があったか判断すること
> - ファイル名などから時系列を推測し、時系列の順に出力すること
> - ときおり相手のPLAYER INFO画像のみが提供される
> - プレイヤー名で対応づけ、notesに有用な情報(現在ランキング、過去最高ランキング、W-Lなど)を書くこと
>
> ### 重要ルール(opp/me判定と左右の正規化)
> - opp/meは画像上の左右ではなく、表示名/略称で判定する(位置で決めない)
> - 出力では2者の値を必ず [opp, me](相手が先、自分が後)に正規化する
> - この [opp, me] ルールの適用範囲: score / a / k / sb / ss
>
> ### 自分(me)の識別
> - name: hnsol
> - abbr: MID
> - opponent(opp)はそれ以外
>
> ### 抽出ルール
> - 読めない項目は推測せず null
> - %は %付きの文字列(例: "81%")
> - 3/5 のような分数表記はそのまま文字列(例: "3/5")
> - 数字は画像の表記どおり(整数)
> - スコアは画像表記どおりの文字列で保持する(例: "10" など)
>
> ### 出力の書き方(行数削減の指定)
> - ルートの keys は必ず matches のみ
> - matches配下の各試合は「1試合=1ブロック」で出力する
> - 各試合のキー順は固定(id, img, p, r, a, k, sb, ss, note)
> - p / r / a / k / sb / ss は必ずフロースタイルで出力する
> - p は 1行のインラインマップ
> - r は 1行のインラインマップ
> - a は 1行のインラインマップ(FH..REFを1行に詰める)
> - k は 1行で [[opp_s1,opp_s2,opp_s3],[me_s1,me_s2,me_s3]] の形にする
> - sb は 1行のインラインマップ
> - ss は 1行のインラインマップ
> - k をブロック配列(先頭に - を並べる形)で出力しない
> - 余計な空行は入れない
>
> ---
>
> ## 抽出対象(必須)
>
> ### 1) id / img
> - idの生成: TS2K25_<先頭画像のベース名>_<oppのabbr> としてください。
> - abbrが不明な場合は oppの名前 を使用してください。
> - img: その試合に紐づく画像ファイル名を配列で列挙(例: ["IMG_4037.jpg","IMG_4039.jpg"])
>
> ### 2) p(players)
> - p.opp: [name, abbr, level]
> - p.me: ["hnsol","MID",level]
> - levelが読めない場合 null
>
> ### 3) r(result)
>
> - score: [[opp側の各セット/ゲーム],[me側の各セット/ゲーム]] を文字列配列で保持
> - v: [venue_name, location]
> - dur: match duration(文字列)
>
> ### 4) a(attrs)
> - 対象キー: FH, BH, SRV, VLY, POW, SPD, STM, REF
> - すべて [opp, me] の整数配列に正規化する
> - 能力値画面では「左側のオレンジの数字が自分(hnsol)」の場合があるので注意する(必ず名前で正規化)
>
> ### 4) a(attrs)
> - **【重要】画面タイプによって読み取り方を変えること**
> **A. キャラクター立ち絵の画面(Player Info)の場合:**
> - この画面では**名前を探して紐付けようとしないこと**(位置固定で判定する)。
> - 中央のラベル(FH, BH...)を挟んで:
> - **左側の数値(オレンジ色のバー)** = **Me (hnsol)**
> - **右側の数値(青/水色のバー)** = **Opp (相手)**
> - スキル(Shot Counter等)も同様に、画面左下の列がMe(オレンジ)、画面中央右寄りの列がOpp(青)と判定する。
>
> **B. 試合後スタッツ画面(表形式)の場合:**
> - ヘッダーのプレイヤー名/略称(MID/VINなど)を見て、列とプレイヤーを対応付ける(左右の位置で決めつけない)。
>
> **出力:**
> - 読み取った結果は、最終的にすべて `[opp, me]` の順序に正規化して出力する。
>
> ### 5) k(skills)
> - k: [[opp_s1,opp_s2,opp_s3],[me_s1,me_s2,me_s3]]
> - 読めない/未装備は null
>
> ### 6) sb / ss(stats)
> - sb: { aces, df, win, ue, pt, net } をすべて [opp, me] にする
> - ss: { fst_in, fst_win, snd_win, bp } をすべて [opp, me] にする
>
> ### 7) note
> - 相手のPlayer Info画面にある「Seasonal W-L」「Season Ranking」や「All-time W-L」の情報を必ず note 欄に含めてください。
> - なければ null
>
> ---
>
> ## 出力フォーマット(YAML・1試合=1ブロック、順番固定)
>
> # - [opp, me] の適用範囲: score / a / k / sb / ss
>
> '''yaml
> matches:
> - id: <string|null>
> img: [<string>, <string>]
> p: { opp: [<string|null>, <string|null>, <int|null>], me: ["hnsol", "MID", <int|null>] }
> r: { score: [[<string|null>], [<string|null>]], v: [<string|null>, <string|null>], dur: <string|null> }
> a: { FH: [<int|null>, <int|null>], BH: [<int|null>, <int|null>], SRV: [<int|null>, <int|null>], VLY: [<int|null>, <int|null>], POW: [<int|null>, <int|null>], SPD: [<int|null>, <int|null>], STM: [<int|null>, <int|null>], REF: [<int|null>, <int|null>] }
> k: [[<string|null>, <string|null>, <string|null>], [<string|null>, <string|null>, <string|null>]]
> sb: { aces: [<int|null>, <int|null>], df: [<int|null>, <int|null>], win: [<int|null>, <int|null>], ue: [<int|null>, <int|null>], pt: [<int|null>, <int|null>], net: [<string|null>, <string|null>] }
> ss: { fst_in: [<string|null>, <string|null>], fst_win: [<string|null>, <string|null>], snd_win: [<string|null>, <string|null>], bp: [<string|null>, <string|null>] }
> note: <string|null>
>
> '''
> ~~~
>
### 出力されるデータの構成例
```yaml
matches:
- id: TS2K25_IMG_4225_MYS
img: ["IMG_4225.jpg", "IMG_4226.jpg"]
p: { opp: ["MysteriousDisasterESP#73792", "MYS", 30], me: ["hnsol", "MID", 30] }
r: { score: [["4", "3"], ["2", "1"]], v: ["ROD LAVER ARENA", "MELBOURNE, AUSTRALIA"], dur: "00:13:57" }
a: { FH: [92, 90], BH: [87, 89], SRV: [30, 30], VLY: [40, 30], POW: [88, 95], SPD: [90, 53], STM: [69, 75], REF: [54, 88] }
k: [["Diesel Hard Hitter", "Fatality", null], ["Shot Counter", "Fatality", "Return Service Counter"]]
sb: { aces: [2, 4], df: [0, 0], win: [24, 14], ue: [4, 8], pt: [34, 19], net: ["4/7", "0/2"] }
ss: { fst_in: ["93%", "92%"], fst_win: ["68%", "38%"], snd_win: ["50%", "50%"], bp: ["2/3", "1/3"] }
note: "Season W-L 54-58, Season Ranking 2022, All-time W-L 375-380"
-
- id: TS2K25_IMG_4227_BJO
img: ["IMG_4227.jpg", "IMG_4228.jpg"]
p: { opp: ["Bjoern#24469", "BJO", 30], me: ["hnsol", "MID", 30] }
r: { score: [["0", "1", "0"], ["3", "2", "0"]], v: ["ROD LAVER ARENA", "MELBOURNE, AUSTRALIA"], dur: "00:13:32" }
a: { FH: [80, 90], BH: [87, 89], SRV: [70, 30], VLY: [40, 30], POW: [80, 95], SPD: [50, 53], STM: [50, 75], REF: [53, 88] }
k: [[null, null, "Poisoned Slices"], ["Shot Counter", "Fatality", "Return Service Counter"]]
sb: { aces: [0, 1], df: [0, 0], win: [9, 11], ue: [15, 6], pt: [16, 26], net: ["1/2", "1/2"] }
ss: { fst_in: ["78%", "83%"], fst_win: ["36%", "60%"], snd_win: ["75%", "100%"], bp: ["0/0", "2/3"] }
note: "Season W-L 34-45, Season Ranking 3975, All-time W-L 326-424"
```
---
## 💡 振り返り
ラクして強くなるために「数字」による客観視をやってみた。相手の戦績を事前に見て対策を考え、Geminiが抽出したスタッツを見て自分の弱点(1stサーブの低さやUEの多さ)を反省する。このサイクルこそが、Season 11における最大の武器であった。
---
**Next Step:**
これらのデータ分析から見えてきた、自分にとっての「限界」と「宿題」を [[超えられなかった壁_トップスピン2K25-S11|超えられなかった壁]] で整理する。