コンテンツにスキップ

Pokemon TCG AI Battle — 参戦方針プラン

状態(2026-07-24): この計画書は初期ロードマップとして履歴保存している。現在の実施順と段階 gate は roadmap.md、実装済みの仕様は architecture/current-method.md を優先する。現在は NN-only ではなく、Policy/Value Net と Belief-Guided ISMCTS を実戦でも組み合わせる。rollout は本線に入れず、leaf で NN value + progress value を使う AlphaGo Zero 寄せの設計に更新している。v13 では旧 ActionConditionedPolicyValueNet を legacy path として残しつつ、UnifiedTokenPolicyValueNet を別パッケージに追加し、カード静的特徴・盤面動的状態・位置情報を 1 つの object token にまとめる入力層を比較する。さらに aux prize heads と integrated belief heads を追加し、1 checkpoint から policy / value / サイド取得補助 / hidden-state belief を出せるようにしている。

v13 移行方針

v13 の目的は、既存 checkpoint を壊さずに入力層を改善することである。ActionConditionedPolicyValueNet はそのまま維持し、旧 self-play / eval / submission は引き続き動かす。新しい UnifiedTokenPolicyValueNetsrc/pca/models/policy_value_unified/ に分け、checkpoint の model_class で loader が旧新を振り分ける。

2026-07-02 時点の追加方針:

  • aux prize targets は SelfPlayRecord.aux として JSONL に保存する。既存 JSONL は aux 無しなら mask 0。
  • integrated belief heads は v13 unified checkpoint に統合する。standalone BeliefNet は互換用に残す。
  • --belief-source auto|separate|policy で hidden-state prior の出所を切り替える。
  • Phase 1 では aux/belief を学習・診断に使い、ISMCTS leaf value への aux 混入は Phase 2 で検証する。

移行は次の順で進める。

  1. Unified model の smoke training を行い、1 batch forward/backward と checkpoint 保存・ロードを確認する。
  2. 同じ小規模データで legacy と unified の forward 時間、token 数、loss の動きを比較する。
  3. Unified checkpoint で self-play 1〜数 game を回し、合法手選択と ISMCTS の探索ログが壊れていないことを確認する。
  4. 問題がなければ 500 game 単位の収集・学習サイクルに入れ、legacy checkpoint と online ISMCTS 評価で比較する。
  5. 十分に良ければ本線 config を v13 unified に寄せる。悪ければ legacy path を維持したまま、text embedding や action token 強化を個別に検証する。

v13 の詳細設計は architecture/unified-token-policy-value.md にまとめる。

2026-07-04 の実装・実験ログは journal/2026-07-04.md にまとめた。v13 unified model、aux / belief heads、rule bootstrap 10k、ISMCTS batching / cache、model-vs-rule self-play、step loop 調査の詳細はそちらを参照する。

背景

Kaggle の「Pokemon TCG AI Battle Challenge」(松尾研 CABT エンジン使用) に 上位入賞 を目標に参加する。リポジトリ直下にある reinforcement-learning-and-mcts-sample-code.ipynb の MCTS + Transformer (AlphaZero風) サンプルを 将来的に拡張 する方針 (サンプル拡張型) だが、最初は SDK / シミュレータの調査と実験を徹底し、ポケカの諸要素が API のどこにどう現れるかを完全に把握してから モデル開発に移る。

開発環境は M1 Max (PyTorch MPS) をメイン、必要なら Kaggle Notebook の無料 GPU/TPU を併用。uv でセットアップ済みのリポジトリ (pyproject.toml) を出発点に、提出用エージェントの完成までを段階的に積み上げる。

コンペ公式からのメッセージ (要約)

Kaggle Overview より、この設計判断の前提:

  • ポケカ自体が戦略ゲーム。相手の戦略・デッキ・手札を踏まえた意思決定が必要。
  • 数千種類のカードの組み合わせを扱う。ドロー / コイントスというランダム要素もある。
  • 相手の手札が見えない ことが AI にとって最大の課題と明示されている。
  • 主催者は「斬新な手法 (novel methods) の探求」を推奨。
  • SDK は Kaggle 環境と同じロジックで、ローカルでのデバッグ・強化学習に適する。
  • ルールベース単独では上位は取れない と明示。先見性・リアルタイム適応力・最適意思決定が必要。

コンペの構造 (二次情報・Phase 0 で必ず公式確認)

外部報道 (PokeBeach 等) によれば下記の構造らしい。Phase 0 で公式ルールページから必ず再確認 すること。

  • 2 部門制:
  • Simulation Category: AI training agent を提出、Kaggle 上で自動対戦。上位 8 チームが第 2 ラウンドへ進出。
  • Strategy Category: 戦略レポート (学習方法・設計判断・洞察) を提出して評価される独立カテゴリ。賞金対象。
  • 賞金: 第 1 ラウンド上位 8 チーム各 $30,000、第 2 ラウンドのグランプリ $50,000、総額 $300,000+ (要公式確認)。
  • タイムライン: 第 1 ラウンドは 2026年6月〜8月、最終締切 2026年9月14日と報道。
  • カードプール: スタンダードフォーマットの約 2,000 枚
  • 協力: 松尾研 (CABT engine), HEROZ, Google, NVIDIA, Kaggle。

→ 戦略含意:

  1. belief / opponent modeling はおまけではなく差別化軸そのもの。Phase 3 のメインタスク。
  2. デッキ多様性への汎化 が必須 (カードプール約 2,000 枚)。固定デッキでの過学習は競技で必ず罰される。マルチデッキ自己対戦を Phase 3 までに着手。
  3. 純ルールベース禁忌、純 NN も不十分。MCTS + NN + Search API ヒューリスティクスの ハイブリッド が最有力。
  4. オンライン適応 (試合中に相手のデッキを推定して belief を更新) は順位を上げる強力なレバー。Phase 4 〜 5 で必ず触れる。
  5. Strategy Category 用のレポート素材を Phase 0 から記録するdocs/decisions/docs/exploration/ の蓄積はそのまま提出レポートの章立てになる。設計判断のたびに「なぜそうしたか・代替案と比較しての利点」を 1 段落書いて残す習慣をつける。

ポケモンカードゲームというドメインの難しさ

汎用ボードゲーム (将棋・囲碁) と違い、以下の要素が同時に効く:

  • 複合アクション / 1ターン多手番: 1ターンに「ドロー → 特性発動 → エネルギー添付 (1回) → サポート使用 (1回) → グッズ複数枚 → 進化 → ベンチ展開 → 攻撃宣言」と複数の選択が並ぶ。1手 = 1 battle_select ではなく、複数の選択ステップが連続する。
  • 長期計画: 進化ライン (たね → 1進化 → 2進化)、エネルギーを数ターンかけて貯める、サイド残数の管理。1手の勝ち負けではなく数ターン先の盤面構築 が勝敗を分ける。
  • 隠し情報の多様性: 相手の手札、相手のデッキ順、相手の賞 (サイド)、自分のデッキ順、自分の賞。さらに「相手のデッキ構成自体」は本来はリスト公開なし (デッキレシピが事前公開かはルール要確認)。
  • ランダム性: コイントス、ねむり判定、シャッフル要素 (サンダー、博士の研究後)、サーチ後のシャッフルなど。MCTS のロールアウトで chance node の扱い が必要。
  • 特性 (Ability): 受動的なものから能動的 (1ターン1回) まで多種。発動順や発動有無の選択もアクションになる。
  • 特殊状態: どく・やけど・ねむり・まひ・こんらん。状態に応じた option 列挙やコイントス処理が走る。
  • トレーナーズ: グッズ (1ターン何枚でも) / サポート (1ターン1枚) / スタジアム (場に1枚) / ポケモンの道具 (各ポケモン1枚) で制約が違う。サポートは先攻1ターン目使えない など細則あり。
  • デッキ構築: 60枚、同名4枚まで (基本エネルギー除く)、Ace Spec 1枚まで。サンプル battle_start がエラーコードで返してくる仕様 (notebook の errorType 1〜4) からも、デッキ構築自体がコンペの一部であることがうかがえる。
  • 逆転要素: 賞の引き運、サイド差からのリーサル、終盤の手札枯渇。早期勝ちと安定勝ちのトレードオフ がある。

これらは「belief 表現」「特徴量設計」「アクション表現」「報酬設計 (途中報酬の有無)」のすべてに影響する。事前調査 (Phase 0) で API がどの要素をどう表現しているかを把握しないと、特徴量設計を間違える

ゴール設定 (順に達成)

Stage 目標 完了基準
S0 SDK / シミュレータの完全把握 Phase 0 のチェックリスト (後述) を満たすメモが揃っている
S1 ローカルでサンプルが動く M1 Max でサンプル ipynb 同等のループが完走
S2 提出パイプライン確立 Kaggle に notebook 同等の暫定エージェントを提出してスコア取得
S3 belief 改善 + 学習 target 修正 サンプル版と同条件で過去世代相手 ELO +10pt 以上
S4 ドメイン知識投入 (デッキ・shortcut) 強デッキ複数 + Search API による短絡 policy で ELO 単調改善
S5 モデル拡大 & 推論最適化 提出時間制約内で SEARCH_COUNT 最大化、拡大版が拡大前に対し連続勝ち越し
S6 最終調整・提出 暫定リーダーボード上位

アーキテクチャ (推奨)

pokemon-card-ai/
├─ pyproject.toml              # torch, numpy 等を Phase 1 で追加
├─ src/pca/
│  ├─ features/encoder.py      # 観測 → token / tensor
│  ├─ models/                  # Transformer policy/value / belief
│  ├─ search/                  # MCTS / determinized / ISMCTS
│  ├─ training/selfplay/       # 自己対戦・サンプル収集
│  ├─ training/train.py        # 学習ループ + 評価 + ckpt
│  ├─ evaluation/tournament/   # 世代間・デッキ間評価
│  ├─ decks.py                 # 候補デッキ群
│  └─ submission/
│     ├─ agent.py              # 提出用エージェント (推論専用)
│     └─ deck.csv              # 提出デッキ
├─ checkpoints/                # .pth 保存先
├─ notebooks/
│  ├─ 00_api_exploration.ipynb # Phase 0 の探索ノート (新規)
│  ├─ 01_card_dictionary.ipynb # Phase 0: 全カード/全攻撃を眺める (新規)
│  ├─ 02_one_game_trace.ipynb  # Phase 0: 1試合を手動で進めてログ取る (新規)
│  └─ reinforcement-learning-and-mcts-sample-code.ipynb  # 既存
└─ scripts/
   ├─ probe_api.py             # API 呼び出しの単発確認用 (Phase 0)
   ├─ train_local.py           # M1 Max 向け長時間学習 (Phase 1〜)
   ├─ eval_tournament.py       # 世代間総当たり (Phase 3〜)
   └─ bench_agent.py           # 1手レイテンシ計測 (Phase 0/5)

理由: サンプルは 1 ファイル約 500 行で、ハイパラ・モデル・MCTS・学習ループが混ざっている。S3 以降の belief 改善・モデル差し替え・推論専用ビルドのために層分割が必要。notebooks/00_* は Phase 0 の 探索 (=理解) のための作業場、src/pca/*実装 のための場、と役割を明確に分ける。

実装ステップ

Phase 0: SDK / シミュレータの調査と実験 (S0) — 最優先・モデル開発に移る前にここを完了

ユーザ要望に従い、まずは CABT が提供する API を体に染み込ませる ことを優先する。モデル設計やコード分割はこの段階ではしない。手と頭を使って API を確かめる。

0-0. リポジトリ docs/ への計画書配置と作業記録ルール (Phase 0 開始時の最初の作業)

  • 本計画 (/Users/ryo/.claude/plans/https-www-kaggle-com-competitions-pokemo-staged-fiddle.md) を docs/PLAN.md としてリポジトリにコピーする。以後、計画の改訂はリポジトリ側の docs/PLAN.md を主とし、コミット履歴で改訂を追えるようにする。
  • docs/ 配下を以下の構成とする:
  • docs/PLAN.md — 本計画 (本ファイルのコピー、以後リポジトリ側を更新)
  • docs/journal/日次 (またはセッション単位) の作業ログ (YYYY-MM-DD.md 命名)。次セッションが「前回どこまでやったか」を 1 ファイル読めば把握できる粒度で書く。
  • docs/exploration/ — 調査結果・研究のサマリ (API スキーマ要約、ポケカ要素 ⇔ API マッピング表、Search API レイテンシ計測結果、Kaggle 提出形式メモ、論文要約 など)
  • docs/decisions/ — 重要な設計判断のログ (ADR 風: 状況・選択・代替案・理由)。Strategy Category レポートの素材を兼ねる。
  • docs/references.md — 参考文献リスト (本計画末尾の「参考文献・先行研究」をコピー、追加で見つけたものを追記)
  • ノートブック (notebooks/00_* 等) は探索の作業場、docs/exploration/*.mdそこから取り出した恒久的な知識 という分担にする。
セッション間連続性のための作業記録ルール (重要)

セッション (Claude Code との対話単位) が変わっても作業が引き継げるように、以下を全フェーズで守る:

  1. セッション開始時: 必ず docs/PLAN.mddocs/journal/ の最新 1〜3 ファイルを読み、現在の進捗と直前の意思決定を把握してから作業に入る。
  2. セッション終了時: docs/journal/YYYY-MM-DD.md (同日複数回なら -01, -02 の suffix) に以下を最低限残す:
  3. 今日やったこと (箇条書き、ファイル名・関数名・コミットハッシュレベルで具体的に)
  4. 学んだこと / 観察したこと (API の挙動、論文の知見、実験結果など — Strategy レポートの素材)
  5. 次にやること (TODO リスト、開いたままの問い、検証保留の仮説)
  6. 行き詰まり / 未解決 (失敗した実験、わからないこと、要確認の API 仕様)
  7. 重要な設計判断をしたとき: その場で docs/decisions/NNNN-title.md (例: 0001-use-determinized-uct-first.md) に「状況 / 検討した選択肢 / 採用した案 / 理由 / 想定されるリスク」を 1 枚で書く。フォーマットは ADR (Architecture Decision Record) を踏襲。
  8. 調査・研究を読んだとき: docs/exploration/ に「何を調べたか / 何を学んだか / プランへの影響」を短くまとめる。論文 1 本につき 1 ファイルが目安。
  9. commit メッセージ: その日 journal に書いたサマリと整合する内容にする。後で git log と journal を突き合わせれば全体の流れが追える状態にする。

これは Strategy Category 提出レポートの素材集めとしても直接効く (Phase 5 になってから「何を考えてどう決めたか」を思い出すのは不可能なので、その都度書く)。

0-A. ドキュメントとカードプールの読破

  • https://matsuoinstitute.github.io/cabt/ のドキュメント全ページを通読し、観測スキーマ・選択スキーマ・LogType・各 enum・Search API/Battle API の関数シグネチャを把握する。
  • Kaggle コンペページ (Overview / Data / Rules / Code / Discussion) を読み、提出形式 (関数か bundle か)・1手の制限時間・同梱可能アセット容量・カードプール (使用可能カード)・デッキ構築制約・コンペの評価方法 (Swiss / 総当たり / Elo 等) を確認。
  • Overview の「novel methods 推奨」「ルールベース単独不可」「相手手札不明が最大の課題」の3つを念頭に置き、自分のソリューションがこれら3点にどう答えるかを Phase 0 完了時に1段落で書ける状態にする。
  • 「カードプールはレギュレーション (例: F/G/H レギュ) で絞られるのか、それともすべて使えるのか」を明確化。これが Phase 4 のデッキ研究に直結する。
  • Discussion を最低 1 回ざっと眺め、主催者からのアナウンス・既知バグ・他参加者の発見を把握。

0-B. cg-lib 入手とローカル動作確認

  • Kaggle Notebook 上でサンプル ipynb をそのまま実行し、cg-lib のインストールパスや配布形態を確認 (/kaggle/input/**/cg-lib)。
  • ローカル開発するためにパッケージとしてコピーできるか試す。難しければ Kaggle Notebook 内で全部やる前提に切り替える。

0-C. API 観察ノート (notebooks/00_api_exploration.ipynb)

実際に battle_start などを叩いて返り値を表示し、構造を目で確かめる。

  • all_card_data() の中身: カードオブジェクトのフィールド (HP, type, evolution stage, abilities, attacks の cost / damage / effect 等) を列挙。進化・特性・道具・特殊効果 がどのフィールドにどう乗っているか整理。
  • all_attack() の中身: 攻撃のコスト・基礎ダメージ・追加効果がどう表現されているか。
  • Observationprint して全フィールドを確認。logs / current / select の各属性を子も含めて表示。
  • SelectContextOptionType の組み合わせを実際に観察 (たね選択 / メイン / 攻撃選択 / 切り替え / 特殊状態の回復選択など)。

0-D. 全カード辞書ノート (notebooks/01_card_dictionary.ipynb)

  • all_card_data() を一覧して、カードタイプ別の枚数 (たねポケモン / 1進化 / 2進化 / グッズ / サポート / スタジアム / 道具 / 基本エネ / 特殊エネ) を集計。
  • 主要カードの ID をいくつかメモ (リザードンex、ピジョットex、博士の研究、ナンジャモ、ナタヤ系統など — Phase 0 段階でメタゲームを把握)。
  • これにより Phase 4 のデッキ構築候補が現実的になる。

0-E. 1試合手動トレース (notebooks/02_one_game_trace.ipynb)

random_agent ではなく、optionprint して 自分が手で選んだ index を battle_select に渡す 形で 1〜2 試合プレイする。

  • たね選択 → 先攻決定 → メイン1ターン目 → 攻撃 → 相手ターン → ... の流れを実際に追う。
  • 特性発動・サポート使用・進化・ベンチ展開・コイントス・特殊状態回復・サイド取得・賞選び の 各局面で obs.select.contextoption がどうなるか を記録。
  • ログ (obs.logs) に何が記録されるか、HP_CHANGE / POISONED / DRAW / RESULT などのイベントを実観察。
  • 試合終了時 (current.result) の意味を確認。

0-F. Search API 実験

  • 同一局面から search_beginsearch_stepsearch_end を実行し、ロールアウトの挙動を確認。
  • opponent_deck / opponent_hand をダミー (Snorlax のみ・基本エネルギーのみ) で埋めた時、攻撃計算や特性発動の結果がどう変わるかを観察。サンプルの「相手 = Snorlax 固定」がどれだけ嘘になっているか を体感する。
  • search_step 1回の wall-clock を time.perf_counter で測定。Phase 5 でのレイテンシ予算逆算に使う。
  • search_release の挙動も確認。

0-G. ポケカ要素と API のマッピング表 (成果物)

notebooks/00_api_exploration.ipynb の末尾に下表を埋めることを Phase 0 完了の必要条件とする。

ポケカ要素 API での表現 観察済か
進化ライン Pokemon.id の進化前後の対応 / OptionType.EVOLVE
エネルギー添付 (1ターン1回) OptionType.ATTACH / Card.energyCards
特性 (起動) OptionType.ABILITY
サポート (1ターン1枚) OptionType.PLAY + サポートカードの ID
グッズ (制限なし) OptionType.PLAY + グッズカードの ID
ポケモンの道具 Card.tools / OptionType.TOOL_CARD
攻撃宣言 OptionType.ATTACK + attackId
攻撃の効果 (追加効果) Attack の effect フィールド / obs.logs
コイントス ログ or select に出る?
特殊状態 PlayerState.poisoned/burned/asleep/paralyzed/confused
状態回復選択 SelectContext.RECOVER_SPECIAL_CONDITION
ベンチへ展開 OptionType.PLAY のたねポケモン
バトル場の入れ替え OptionType.RETREAT
賞 (サイド) PlayerState.prize
山札サーチ Observation.select.deck / SelectContext.SEARCH_DECK
先攻のサポート禁止 option に出ない (検証)
Ace Spec 制限 デッキエラー errorType=4

Phase 0 完了基準

  • 上記マッピング表が埋まっている
  • Search API の 1ステップ平均レイテンシを数値で把握している
  • Kaggle 提出形式 / 制限時間 / カードプール / アセット容量上限を把握している
  • cg-lib をローカルで動かす方針 (or Kaggle Notebook 専業) を決めている
  • ノートブック 3 本がコミットされている

ここまで終わってから Phase 1 に進む。Phase 0 が終わるまではモデルもパッケージ化もしない

Phase 1: サンプルをローカルで動かす (S1)

  • pyproject.tomltorch, numpy を追加して uv synctorch.backends.mps.is_available() を確認。
  • EmbeddingBag が MPS で動くかを Phase 1 冒頭で必ず試す (動かなければ CPU フォールバック方針を確定)。
  • サンプル ipynb をローカルで 1 イテレーションだけ回し、notebook と同じ勝率推移が出ることを確認。

Phase 2: 提出パイプラインの確立 (S2)

  • サンプルそのままで Kaggle に1回提出してパイプラインを疎通。スコア計算ロジックを実体験する目的。
  • このタイミングではコードはまだサンプル ipynb 寄りで OK。

Phase 3: サンプルのモジュール化 + belief 改善 + 学習 target 修正 (S3) — 最大のレバレッジ

挙動を変えない移植 → 重要な改善 2 点、の順で進める。

3-A. モジュール化 (挙動不変)

  • ノートブックを src/pca/ 配下に分割。MyModel, SparseVector, get_encoder_input/decoder_input, Node/Child/create_node/mcts_agent, 学習ループをそれぞれ移植。
  • scripts/train_local.py から呼べる形にする。

3-B. 学習 target を AlphaZero 標準に修正 (最優先)

現サンプルは policy target を child.total/child.visit - root value で作っており、展開された child しか教師信号がない上、その値は直前の NN policy 出力に強く依存する。これを以下に置換:

  • policy target = root の visit 分布の正規化 (child.visit / sum(child.visit)、未展開 child は 0)
  • value target は対戦結果 (Phase 0 で確認した current.result) と root value のブートストラップ
  • policy head の loss を HuberLoss から cross-entropy / KL に変更

mcts_agent 末尾の sample.policy[i] = ... の塊を差し替える。

3-C. belief 改善 (Determinized → IS-MCTS のロードマップ)

現サンプルは search_begin を 1 回しか呼ばず、自分 deck も random.sample、相手 deck/hand/prize はダミー固定 (Snorlax / Basic Energy)。Phase 0 でこの「ダミー前提がどれだけ嘘か」を体感した上で、以下を 段階的に 進める。

段階 1 (Phase 3 必達): Determinized UCT (= 複数 determinization の root visit 合算)

  • 1 手選択ごとに N (= 8〜32) 通りの隠し情報サンプルで search_begin → 別々の MCTS tree を作り、root の visit を合算してから行動選択。
  • 観測ベースの絞り込み (src/pca/search/belief.py): obs.logs から相手が「discard したカード」「draw した枚数」「サーチで持ってきたカード (公開した場合)」を抽出し、相手 hand/deck 候補から既知矛盾を除く。ポケカ特有として「相手が場に出したたねポケモンは相手 deck から除く」「discard pile の内容は完全公開」「進化系統が場にいるなら相手 deck/hand にその進化系統がある」などを反映。

段階 2 (Phase 4-5 で進化): Single Tree IS-MCTS への移行

  • 研究文献によれば、Determinized UCT は strategy fusion (同じ情報集合の異なる world で別の最適手を選んでしまう問題) に弱く、IS-MCTS の方が一貫して品質が高い ことが確認されている (Cowling, Powley, Whitehouse 2012)。
  • Phase 3 終了後、Node を「情報集合単位」に変え、search 木 1 本を世代をまたいで共有する SO-ISMCTS 実装に進化させる。MO-ISMCTS (各プレイヤー別ツリー) はその後の検討。

これにより、Phase 3 では実装容易な Determinized UCT で勝率を底上げし、後半で品質の高い IS-MCTS に乗り換える、というロードマップになる。

3-D. 評価ループ

  • checkpoints/iter_N.pth を相手にする評価を追加、ELO 風スコア算出。
  • チェックポイントローテーション (過去 K 世代を相手に混ぜる、policy collapse 防止)。
  • 勝率・loss・visit 分布エントロピーを CSV / TensorBoard。

Phase 3 ではモデル拡大はしないSEARCH_COUNT も Phase 0 で測ったレイテンシ予算の半分以下に留め、(3-B)(3-C) の純粋効果を測る。

Phase 4: ドメイン知識の投入 (S4)

ポケカ特有の知識を、自己対戦学習だけに頼らず明示的に組み込む。

  1. デッキ研究 (src/pca/decks.py): Phase 0-D で集めたカード辞書をもとに、Phase 0-A で確認したカードプール内の環境上位デッキを複数定義。サンプルデッキを置き換える。
  2. マルチデッキ自己対戦: 自己対戦で複数デッキをローテーション、汎化を狙う。提出時はトーナメントで最強デッキを選ぶ。
  3. Search API による短絡 policy (src/pca/decision/heuristics.py):
  4. 「相手 active を一撃で倒せる攻撃」を search_step で先読み → 強い prior を加算
  5. 「ドロー枚数の多いサポートを優先」
  6. 「ベンチが空の自分のターンに、たねポケモンの play は強い prior」
  7. 「サイドリーサル (相手の残りサイドぶんの KO を作れる手) の検出」
  8. 「先攻 1 ターン目はサポート禁止 → option に出ないことを Phase 0 で確認済の前提で処理」ヒューリスティック bonus を NN policy の prior に加算する形にする (完全 override ではなく)。
  9. 負け筋ログ: 自己対戦で負けたゲームの直前 N 手を priority sample として再学習に混ぜる。

Phase 5: モデル拡大・斬新手法の導入・推論最適化 (S5)

belief とドメイン知識で土台ができた後にようやくモデルを大きくする。Strategy Category 用の差別化要素もここで仕込む

  1. モデル拡大: d_model 128→256layers 1→4heads 2→4。Phase 3 で見える化したログで、拡大ステップごとに ELO 改善を確認。
  2. アクション表現の見直し: 現 decoder_bag (EmbeddingBag) はアクション同士の関係を捨てている。(option_id, context, area, target) を順序付きトークン列として TransformerEncoder に通す表現に置き換えるか試す。
  3. 特徴量の追加: Phase 0 で気づいた未活用情報 (例: 自分の deck 残りで引ける確率の高いカード、対戦序盤と終盤の区別、特殊エネルギーの場の枚数など) を encoder に足す。
  4. Oracle Guiding (Suphx 流): 自己対戦学習時のみ完全情報 (相手 hand を含む) で教師を作る auxiliary head を加える。提出時は推論しないが、学習中の policy/value head の質を底上げできる。Suphx で実証されたテクニック。
  5. オンライン opponent modeling: 相手の初手数手から デッキタイプ分類器 (NN or 簡易 logreg) を学習し、belief.py の事前分布として使う。試合中に相手のデッキ識別が進むにつれて determinization の精度が上がる仕掛け。
  6. 推論最適化: 提出時は torch.jit.script / torch.compileint8 量子化、eval_nn のバッチ化。提出環境が CPU なら EmbeddingBag を numpy で再実装も検討。
  7. ロールアウト並列化: 同時に複数 child を NN にバッチ推論。SEARCH_COUNT の有効値を引き上げる。

(4)(5) は Strategy Category レポートで「novel methods」として強く打ち出せる候補。

Phase 6: 最終調整 (S6)

  • ハイパラスイープ (探索定数 c, determinization 数 N, 温度, λ)
  • 直前世代×トーナメントで提出モデル選定
  • 複数提出枠を別系統 (NN 強め / ルール強め / 別デッキ) で埋めてリスク分散

重要ファイル (作成・参照)

既存資産の再利用 (Phase 3-A)

  • MyModelsrc/pca/models/policy_value.py に移植
  • SparseVector, get_encoder_input, get_decoder_inputsrc/pca/features/encoder.py
  • Node, Child, create_node, mcts_agentsrc/pca/search/determinized.py から始め、後に ISMCTS 実装へ分離
  • 学習ループ → src/pca/training/train.py

Phase 3-A では 挙動を変えない移植 を徹底し、Phase 3-B 以降で機能追加する。

検証方法

段階 検証
S0 Phase 0-G のマッピング表が埋まっている / Search API レイテンシ数値が出ている / 提出形式メモがある
S1 uv run python scripts/train_local.py --iters 1 がノートブックと同じ勝率推移 (random 相手 20%前後)
S2 Kaggle 提出 → スコア取得 (notebook 同等)
S3 (a) visit 分布 target に変更後の baseline, (b) IS-MCTS 化後 — それぞれサンプル版と同 SEARCH_COUNT・同 iteration で過去世代相手 ELO +10pt 以上
S4 複数デッキ評価 (--deck X --deck Y) で勝率60%超、Search API shortcut の ablation 計測
S5 1手レイテンシ (scripts/bench_agent.py) が制約内、モデル拡大版が拡大前に対し ELO 単調改善
S6 最終提出を Kaggle 暫定 LB で確認

参考文献・先行研究

Phase ごとに参照すべき論文・実装。docs/references.md にもコピーして、Strategy Category レポートの参考文献欄の素材として育てる

不完全情報ゲームの探索 (Phase 3 中心)

  • Cowling, Powley, Whitehouse (2012) "Information Set Monte Carlo Tree Search" (PDF, IEEE) — IS-MCTS 原論文。SO-ISMCTS / MO-ISMCTS / Multi-Observer ISMCTS の 3 アルゴリズムを定義。Phase 3-C のロードマップの根拠。
  • Whitehouse, Powley, Cowling "Determinization and Information Set Monte Carlo Tree Search for Dou Di Zhu" (IEEE) — 中国カードゲーム Dou Di Zhu で Determinized UCT vs IS-MCTS を実測比較した先行例。ポケカに最も近い設定の 1 つ。
  • Cowling et al. (2015) "Information capture and reuse strategies in MCTS, with applications to games of hidden information" (ScienceDirect) — 情報集合間の情報共有・再利用の手法。Phase 5 で SO-ISMCTS を作る際の最適化アイデア。
  • Powley, Cowling, Whitehouse (2013) "Reducing the burden of knowledge: Simulation-based methods in imperfect information games" (AI Factory) — 一般読者向けまとめ。Strategy レポートの背景説明に引用しやすい。
  • Schmid et al. (2021) "Student of Games: A unified learning algorithm for both perfect and imperfect information games" (arXiv 2112.03178) — AlphaZero と DeepStack の統合系。Phase 5 で「斬新な手法」として参照する価値あり。

自己対戦・AlphaZero 系 (Phase 1〜5 全般)

  • Silver et al. (2018) "AlphaZero" — original。policy/value head の loss 設計 (visit 分布 cross-entropy + value MSE) は Phase 3-B の修正の根拠。
  • Schrittwieser et al. (2020) "MuZero" — モデル学習を含めた拡張。CABT エンジンが提供されているため MuZero 化のメリットは限定的だが、特性発動のような効果推論を NN に任せる余地はある。
  • MiniZero (2023) (arXiv 2310.11305) — AlphaZero/MuZero の公平な比較。ハイパラ調整の指針として。
  • Survey on Self-play Methods (2024) (arXiv 2408.01072) — Phase 3-D のチェックポイントローテーション設計の参照。

ポーカー系 (Phase 5 の belief 更新の理論的支柱)

  • Moravčík et al. (2017) "DeepStack: Expert-Level AI in Heads-Up No-Limit Poker" (arXiv 1701.01724) — continual re-solving と Bayes 範囲更新。ポケカの相手 hand belief 更新のアイデアの源。
  • DouZero+ (2022) "Improving DouDizhu AI by Opponent Modeling and Coach-guided Learning" (arXiv 2204.02558) — カードゲームでの explicit opponent modeling。Phase 5-5 (デッキタイプ分類器) の参照。
  • Heinrich, Silver (2016) "Deep RL from Self-Play in Imperfect-Information Games" (NFSP) — 平均戦略学習。policy collapse 対策の理論。
  • He et al. (2016) "Opponent Modeling in Deep Reinforcement Learning" (arXiv 1609.05559) — implicit/explicit opponent modeling の整理。

Mahjong (隠し情報・特性多数のゲームの先例 = ポケカに最も類似)

  • Microsoft Suphx (2020) "Mastering Mahjong with Deep Reinforcement Learning" (arXiv 2003.13590) — global reward prediction, oracle guiding (訓練時のみ完全情報), runtime policy adaptation。Phase 5-4 の根拠。
  • Tjong (2024) "Transformer-based Mahjong AI" (Wiley) — 階層的意思決定と fan backward。ポケカの「メイン選択 → 詳細選択」の階層を扱う参照。

TCG / CCG (ポケカに最も近いジャンル)

  • Świechowski et al. (2018) "Improving Hearthstone AI by Combining MCTS and Supervised Learning" (arXiv 1808.04794) — Hearthstone での MCTS + 教師あり学習併用。
  • Vieira, Tavares, Chaimowicz (2020〜2023) Legends of Code and Magic 系列 (arXiv 2407.05879, arXiv 2009.00655) — CCG での deck-building と drafting の RL。
  • Hoover et al. (2024) "A Taxonomy of Collectible Card Games from a Game-Playing AI Perspective" (arXiv 2410.06299) — CCG AI の分類。Strategy レポート背景章に有用。

Pokemon 関連 (別ゲームだが概念は流用可)

  • taylorhansen/pokemonshowdown-ai (GitHub) — Showdown 上の Pokemon バトルの RL 実装。
  • poke-env (Docs) — Showdown 用 Python interface。
  • Wang (2024) MIT MEng thesis "Winning at Pokémon Random Battles Using RL" (dspace) — PPO 自己対戦 1677→PPO+MCTS lookahead 1756 (Glicko-1) の改善。Phase 4 の MCTS 併用が効くことの数値的裏付け
  • (2025) "Human-Level Competitive Pokémon via Scalable Offline RL with Transformers" (arXiv 2504.04395) — Transformer + offline RL の最新研究。Strategy レポートの「斬新な手法」議論のベンチマーク。

コンペ自体の情報

リスクと対処

  • Phase 0 で時間を使いすぎる: 完璧主義に陥らないように、マッピング表の各行は「1分以内に説明できる」程度まで埋まれば次へ。深掘りは Phase 3 で必要になった時。
  • MPS 非対応 op (EmbeddingBag 等): Phase 1 冒頭で判明させ、CPU フォールバック方針を確定。
  • 提出形式が想定と違う: Phase 0 で必ず先に確認。ハマったら Kaggle Discussion を見る。
  • IS-MCTS の実装コストが見積より大きい: まずは「複数 determinization の root visit 合算」のみ実装、single tree over information sets への完全進化は Phase 5 以降。
  • 学習 target 変更で逆に勝率が落ちる: visit 分布 target は冷えやすい。Dirichlet noise を root に足す / iteration 初期は温度を高めにする。
  • ポケカ ルールの細則漏れ: Phase 0-E の手動トレースでサポート禁止・たね選択・スタジアム上書きなどの細則を必ず1回は通る局面で確認。漏れがあると Phase 4 のヒューリスティクスが間違える。
  • 計算時間: M1 Max でも収束に数日かかる可能性。Kaggle Notebook の GPU 9時間枠を週末バッチで併用。