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 は引き続き動かす。新しい
UnifiedTokenPolicyValueNet は
src/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 で検証する。
移行は次の順で進める。
- Unified model の smoke training を行い、1 batch forward/backward と checkpoint 保存・ロードを確認する。
- 同じ小規模データで legacy と unified の forward 時間、token 数、loss の動きを比較する。
- Unified checkpoint で self-play 1〜数 game を回し、合法手選択と ISMCTS の探索ログが壊れていないことを確認する。
- 問題がなければ 500 game 単位の収集・学習サイクルに入れ、legacy checkpoint と online ISMCTS 評価で比較する。
- 十分に良ければ本線 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。
→ 戦略含意:
- belief / opponent modeling はおまけではなく差別化軸そのもの。Phase 3 のメインタスク。
- デッキ多様性への汎化 が必須 (カードプール約 2,000 枚)。固定デッキでの過学習は競技で必ず罰される。マルチデッキ自己対戦を Phase 3 までに着手。
- 純ルールベース禁忌、純 NN も不十分。MCTS + NN + Search API ヒューリスティクスの ハイブリッド が最有力。
- オンライン適応 (試合中に相手のデッキを推定して belief を更新) は順位を上げる強力なレバー。Phase 4 〜 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 のerrorType1〜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 との対話単位) が変わっても作業が引き継げるように、以下を全フェーズで守る:
- セッション開始時: 必ず
docs/PLAN.mdとdocs/journal/の最新 1〜3 ファイルを読み、現在の進捗と直前の意思決定を把握してから作業に入る。 - セッション終了時:
docs/journal/YYYY-MM-DD.md(同日複数回なら-01,-02の suffix) に以下を最低限残す: - 今日やったこと (箇条書き、ファイル名・関数名・コミットハッシュレベルで具体的に)
- 学んだこと / 観察したこと (API の挙動、論文の知見、実験結果など — Strategy レポートの素材)
- 次にやること (TODO リスト、開いたままの問い、検証保留の仮説)
- 行き詰まり / 未解決 (失敗した実験、わからないこと、要確認の API 仕様)
- 重要な設計判断をしたとき: その場で
docs/decisions/NNNN-title.md(例:0001-use-determinized-uct-first.md) に「状況 / 検討した選択肢 / 採用した案 / 理由 / 想定されるリスク」を 1 枚で書く。フォーマットは ADR (Architecture Decision Record) を踏襲。 - 調査・研究を読んだとき:
docs/exploration/に「何を調べたか / 何を学んだか / プランへの影響」を短くまとめる。論文 1 本につき 1 ファイルが目安。 - 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()の中身: 攻撃のコスト・基礎ダメージ・追加効果がどう表現されているか。Observationをprintして全フィールドを確認。logs / current / selectの各属性を子も含めて表示。SelectContextとOptionTypeの組み合わせを実際に観察 (たね選択 / メイン / 攻撃選択 / 切り替え / 特殊状態の回復選択など)。
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 ではなく、option を print して 自分が手で選んだ index を battle_select
に渡す 形で 1〜2 試合プレイする。
- たね選択 → 先攻決定 → メイン1ターン目 → 攻撃 → 相手ターン → ... の流れを実際に追う。
- 特性発動・サポート使用・進化・ベンチ展開・コイントス・特殊状態回復・サイド取得・賞選び の
各局面で
obs.select.contextとoptionがどうなるか を記録。 - ログ (
obs.logs) に何が記録されるか、HP_CHANGE/POISONED/DRAW/RESULTなどのイベントを実観察。 - 試合終了時 (
current.result) の意味を確認。
0-F. Search API 実験¶
- 同一局面から
search_begin→search_step→search_endを実行し、ロールアウトの挙動を確認。 opponent_deck/opponent_handをダミー (Snorlax のみ・基本エネルギーのみ) で埋めた時、攻撃計算や特性発動の結果がどう変わるかを観察。サンプルの「相手 = Snorlax 固定」がどれだけ嘘になっているか を体感する。search_step1回の 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.tomlにtorch,numpyを追加してuv sync。torch.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)¶
ポケカ特有の知識を、自己対戦学習だけに頼らず明示的に組み込む。
- デッキ研究 (
src/pca/decks.py): Phase 0-D で集めたカード辞書をもとに、Phase 0-A で確認したカードプール内の環境上位デッキを複数定義。サンプルデッキを置き換える。 - マルチデッキ自己対戦: 自己対戦で複数デッキをローテーション、汎化を狙う。提出時はトーナメントで最強デッキを選ぶ。
- Search API による短絡 policy (
src/pca/decision/heuristics.py): - 「相手 active を一撃で倒せる攻撃」を
search_stepで先読み → 強い prior を加算 - 「ドロー枚数の多いサポートを優先」
- 「ベンチが空の自分のターンに、たねポケモンの play は強い prior」
- 「サイドリーサル (相手の残りサイドぶんの KO を作れる手) の検出」
- 「先攻 1 ターン目はサポート禁止 → option に出ないことを Phase 0 で確認済の前提で処理」ヒューリスティック bonus を NN policy の prior に加算する形にする (完全 override ではなく)。
- 負け筋ログ: 自己対戦で負けたゲームの直前 N 手を priority sample として再学習に混ぜる。
Phase 5: モデル拡大・斬新手法の導入・推論最適化 (S5)¶
belief とドメイン知識で土台ができた後にようやくモデルを大きくする。Strategy Category 用の差別化要素もここで仕込む。
- モデル拡大:
d_model 128→256、layers 1→4、heads 2→4。Phase 3 で見える化したログで、拡大ステップごとに ELO 改善を確認。 - アクション表現の見直し: 現
decoder_bag(EmbeddingBag) はアクション同士の関係を捨てている。(option_id, context, area, target)を順序付きトークン列として TransformerEncoder に通す表現に置き換えるか試す。 - 特徴量の追加: Phase 0 で気づいた未活用情報 (例: 自分の deck 残りで引ける確率の高いカード、対戦序盤と終盤の区別、特殊エネルギーの場の枚数など) を encoder に足す。
- Oracle Guiding (Suphx 流): 自己対戦学習時のみ完全情報 (相手 hand を含む) で教師を作る auxiliary head を加える。提出時は推論しないが、学習中の policy/value head の質を底上げできる。Suphx で実証されたテクニック。
- オンライン opponent modeling: 相手の初手数手から デッキタイプ分類器 (NN
or 簡易 logreg) を学習し、
belief.pyの事前分布として使う。試合中に相手のデッキ識別が進むにつれて determinization の精度が上がる仕掛け。 - 推論最適化: 提出時は
torch.jit.script/torch.compile、int8量子化、eval_nnのバッチ化。提出環境が CPU ならEmbeddingBagを numpy で再実装も検討。 - ロールアウト並列化: 同時に複数 child を NN にバッチ推論。
SEARCH_COUNTの有効値を引き上げる。
(4)(5) は Strategy Category レポートで「novel methods」として強く打ち出せる候補。
Phase 6: 最終調整 (S6)¶
- ハイパラスイープ (探索定数 c, determinization 数 N, 温度, λ)
- 直前世代×トーナメントで提出モデル選定
- 複数提出枠を別系統 (NN 強め / ルール強め / 別デッキ) で埋めてリスク分散
重要ファイル (作成・参照)¶
- 既存サンプル: notebooks/reinforcement-learning-and-mcts-sample-code.ipynb
- 既存設定: pyproject.toml
- 計画書・記録: PLAN.md, journal/, exploration/, decisions/, references.md
- Phase 0 探索ノート案:
notebooks/00_api_exploration.ipynb,notebooks/01_card_dictionary.ipynb,notebooks/02_one_game_trace.ipynb。現在は notebooks/selfplay_collect.ipynb などに統合している。 - Phase 3 以降のモジュール: src/pca/features/encoder.py, src/pca/models/belief.py, src/pca/models/policy_value.py, src/pca/search/determinized.py, src/pca/search/belief.py, src/pca/search/ismcts/, src/pca/training/targets.py, src/pca/training/selfplay/, src/pca/training/train.py, src/pca/evaluation/tournament/
- 提出物: src/pca/submission/main.py,
src/pca/submission/build_bundle.py,
decks/ - スクリプト: scripts/collect_selfplay_docker.sh, scripts/evaluate_docker.sh, scripts/render_match_replay_docker.sh, scripts/build_notebook_bundle.py
既存資産の再利用 (Phase 3-A)¶
MyModel→src/pca/models/policy_value.pyに移植SparseVector,get_encoder_input,get_decoder_input→src/pca/features/encoder.pyNode,Child,create_node,mcts_agent→src/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 レポートの「斬新な手法」議論のベンチマーク。
コンペ自体の情報¶
- Pokemon TCG AI Battle Challenge Simulation Kaggle Overview
- Pokemon TCG AI Battle Challenge Strategy Category
- CABT Engine docs
- PokeBeach: 公式発表記事 — 賞金構造・スケジュールの二次情報
リスクと対処¶
- 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時間枠を週末バッチで併用。