疾走ドーンから研究所へ――シャドバを題材にカードゲームAIシミュレーターをゼロから作る方法・考え方・理論

題材:『Shadowverse: Worlds Beyond』

カードゲームのシミュレーターを作ろう、と聞くと、最初に巨大なゲーム画面を想像しがちだ。

読書機能の使い方

聴く:本文を読み上げます。速読:語句を順に表示し、速さを調整できます。語学練習:別の言語版と対訳を読み比べます。保存:このブラウザーにブックマークし、プレイヤーの保存済み一覧から開けます。

この記事をシェア
広告
広告

先に読むと分かりやすい: AIで40%時短したのに、なぜ67%仕事を詰めるのか――仕事が無限クエスト化する罠道端に最強アイテムが落ちている世界はなぜ面白いのか

1. 最初に決める――ゲームを作るのか、「勝つ研究所」を作るのか

カードゲームのシミュレーターを作ろう、と聞くと、最初に巨大なゲーム画面を想像しがちだ。

カード画像。アニメーション。ボイス。ドラッグ操作。キラキラした進化演出。

でも「どのデッキが強いか」「この手とあの手、どちらが勝ちやすいか」を調べたいだけなら、その大半はいらない。

研究用シミュレーターの中心はこれだけだ。

現在の状態
↓
合法な行動を出す
↓
どれかを選ぶ
↓
ルール通り状態を更新する
↓
次の状態

これを勝敗が決まるまで繰り返す。

つまり作りたいのはゲームの見た目ではなく、カードゲームの世界を数字だけで動かせる実験室だ。

もし信頼できる既存エンジンがあるなら、それを借りて研究層だけ作るのが最速。なければ、最小ルールから自分で作る。

「ゼロから作る」とは、全部を手作業で再発明することではない。

目的に必要な部品をゼロから組み合わせて、再現可能な研究システムを作ることだ。

2. 完成形を先に決める――入力と出力を書けば設計が見える

コードを書く前に、「何を入れたら、何が返ってくる装置か」を決める。

入力の例はこう。

  • カードDB
  • 40枚デッキ
  • 対戦相手のデッキ
  • 先攻・後攻
  • 乱数seed
  • プレイ方策
  • 環境情報
  • 試合数

出力の例はこう。

  • 勝敗
  • ターン数
  • 先攻・後攻別勝率
  • 対面勝率
  • 平均勝率
  • 最悪対面
  • 手札事故率
  • キーカードを引けなかった時の低下
  • よく起きるミス
  • どのカードを入れ替えると改善したか

ここを先に決めないと、「カードを動かせるようになったけど、何を調べるソフトなの?」という巨大なおもちゃが完成する。

シミュレーターは、先に質問を決める。

コードはその質問に答えるために書く。

3. カードDBを作る――カード一覧とルール実装は別物

最初の大仕事はカードデータだ。

最低限、カードごとに次のような情報を持たせる。

id
name
class
cost
type
attack
defense
rarity
set
text
evolved_stats
related_cards
tags

ここはJSONやSQLiteなどで構造化する。

重要なのは、カードの文章を集めたことと、そのカードが正しく動くことは別という点。

「ファンファーレ:4ダメージ」とDBに書いてあっても、誰を対象にできるか、対象がいない時どうなるか、ダメージ軽減がある時どうなるか、破壊時効果が動くか、同時発動の順番はどうなるかまで処理できなければ、まだカードカタログでしかない。

カードDB部門は「説明書を集める部署」。

ルールエンジン部門は「説明書どおり世界を動かす部署」。

名簿ができても社員はまだ働かない。

4. ゲーム状態を数字にする――画面ではなく「状態」を保存する

次に、対戦中のすべてをデータとして表現する。

turn
active_player
leader_hp
max_pp
current_pp
hand
deck
board
graveyard
evolution_points
super_evolution_points
crests
amulets
counters
temporary_effects

ここで大切なのは、画面の見た目ではなく「ルール判断に必要な情報」を持つこと。

カードが右から2番目に見えているかは研究にはどうでもいい。しかし、そのフォロワーは今ターン攻撃できるか、守護を持っているか、進化済みか、一時バフはいつ切れるかは絶対に必要だ。

良い状態モデルは、ゲーム画面をスクリーンショットで保存するのではなく、世界の意味を保存する。

5. ルールエンジンを作る――ゲームは「状態A→行動→状態B」

ルールエンジンの仕事は、ある行動を受け取って、次の状態を正しく作ることだ。

状態A:
自分PP 3
手札に3コストフォロワー
盤面空き1

行動:
そのフォロワーをプレイ

結果:
PP 0
手札 -1
盤面 +1
ファンファーレ処理

カードを出す、攻撃する、進化する、超進化する、アクトする、対象を選ぶ、ターン終了、ドロー、PP回復、勝敗判定を全部この考え方で処理する。

エンジンは「賢くプレイする」必要はない。

まず必要なのは、バカでも合法な行動をすれば、世界が正しく動くこと。

AIの頭脳とゲームの物理法則を混ぜると、バグの原因が分からなくなる。

6. カード効果は「共通ルール+例外」で実装する

数百枚を全部1枚ずつカード名ifで書くと地獄になる。

だから共通効果は一般化する。

deal_damage
heal
draw
buff
summon
destroy
banish
gain_ward
gain_storm

カードの文章をこうした共通部品へ落とす。

ただしカードゲームには必ず変なカードがいる。そういうものは個別overrideで処理する。

そして必ず「未対応カード数」「partial対応」「runtime gap」を数える。

分からないカードを適当に動かすより、未対応として止める方が研究では正しい。

7. 合法手生成を作る――AIは「選択肢にない正解」を選べない

次は、今の状態で可能な行動を全部出す。これをcandidate generation、候補手生成という。

どのカードを出せるか、どこへ出せるか、どの相手を攻撃できるか、何を対象にできるか、進化できるか、ターン終了できるかを列挙する。

ここが意外と超重要。

評価AIがどれだけ賢くても、「カードを使わず温存する」、「自分の弱いフォロワーを消して盤面を空ける」、**「先にドローする」**という正解が候補に存在しなければ、絶対に選べない。

「AIがアホ」だと思ったら、まず正解候補そのものが生成されているかを見る。

8. seed・replay・hash――同じ実験をもう一度できるようにする

カードゲームにはランダムがある。ドロー順、ランダム対象、生成カードなど。

そこでseedを固定する。

さらに、

engine commit
card DB hash
deck hash
policy hash
environment hash
schedule hash
seed hash

を記録する。

同じエンジン、DB、デッキ、方策、seed、先攻後攻なら、同じ試合を再現できるようにする。

これがないと「前より勝率上がった!」と言っても、DBやAIやデッキや運が変わっただけかもしれない。

研究で一番怖いのはバグより、何を比較したのか後から分からなくなることだ。

9. 最初のAIは賢くなくていい――まず基準方策を作る

いきなりAlphaGo級を目指す必要はない。

リーサルがある → 勝つ
死にそう → 守る
低コストを出せる → 出す
盤面有利 → 顔を詰める
盤面不利 → トレードする

これをreference policy、基準方策にする。

重要なのは「強いAI」より、比較の基準になる固定AIを持つこと。

あとで人間知識を入れたAIや探索AIを作った時、「本当に改善したのか?」を測れる。

10. 人間ノウハウは「絶対命令」ではなくpriorにする

攻略記事や上位プレイヤーの知識には価値がある。マリガン、温存、EP/SEP予約、コンボ準備、相手の強い返し、盤面枠、手札上限、2〜3ターン後のリーサルなど。

しかし、そのまま絶対ルールにすると「このカードは温存」→今使わないと死ぬ→それでも温存して死亡になる。

だから人間知識は、

hold_value +20
future_combo +30
survival +50
premature_spend -40

のような「考えるクセ」にする。

人間の攻略本は答えではない。探索AIへ渡す地図だ。

11. 木探索・ビーム探索・ノード予算――数ターン先を読む

AIを一段賢くするなら、未来を見る。

毎回10候補なら、

1手先 10
2手先 100
3手先 1,000
4手先 10,000

と爆発する。

そこでdepth、beam width、node budget、pruningを使う。

ただし「今は弱いが2ターン後に超強い」コンボ線を切ると弱くなる。

だから評価関数には、immediate_value、future_value、survival_value、setup_value、lethal_value、resource_valueを分けて持たせる。

探索AIの難しさは、未来をたくさん読むことではない。

どの未来を捨てないかだ。

12. 相手の手札は見せない――belief・POMDP・モンテカルロ

相手の隠し手札をAIへ直接渡したらチートになる。

そこで公開情報だけから、

AoEを持っているかも 30%
守護を持っているかも 20%
何もないかも 50%

のような「あり得る世界」を作る。これがbelief、信念状態の考え方。

相手手札など一部が見えないので、数学的にはPOMDP、部分観測マルコフ決定過程に近い。

実装では厳密なPOMDP solverを作らなくてもいい。複数の仮想手札をsampleして、その未来を何度も試す。これはモンテカルロ法の考え方。

これで「全体除去を持っているかもしれない。でも全部をケアしていたら攻められない」という人間らしい不確実性を作る。

13. 大量対戦はA/B実験として設計する――試合数だけ増やすな

AIを変えたら、同じ問題で比較する。

同じデッキ、同じ相手、同じ先後、同じseedで、

旧AI 1戦
新AI 1戦

を走らせる。これがpaired A/B、対応あり比較。

先に小さいquick testを行い、明らかな退行がないかを見る。通った候補だけ、本番のholdoutへ進める。そしてholdoutのseedは開発中に使わない。

学校でいうなら、練習問題→quick、模試→development、初見の期末試験→holdout。

大量対戦の目的は「数字を大きくする」ことではない。比較条件を揃えて、偶然を減らすことだ。

14. 勝率以外も測る――統計とロバスト評価

平均勝率だけ見ると危ない。

デッキAが平均60%でも1対面だけ20%、デッキBが平均57%で最悪でも52%なら、環境が少し変わった時にBの方が生き残るかもしれない。

だから平均勝率、メタ加重勝率、最悪対面、下位2対面平均、対面分散、先攻後攻差、brick率、キーカード未取得時の低下、平均ターン、信頼区間を見る。

CVaR的に「悪い方の成績」を見るのも有効。

A/BならMcNemar検定やbootstrapで差が偶然っぽいか調べる。

平均点だけ高い生徒ではなく、苦手科目で赤点を取らない生徒を探す。

15. デッキ最適化――40枚総当たりは無理なので、賢く候補を減らす

カードが数百枚あるゲームで40枚の全組み合わせを総当たりするのは無理。

まず大会デッキや人気デッキをseedにして、1枚入れ替え、2枚入れ替え、3枚入れ替え、同じ役割カードへの置換、苦手対面用techを試す。

Double Oracleは現在の戦略集に強い新しい対抗策を追加する。

PSROは「デッキ40枚」だけでなく「デッキ+プレイ方策」を1つの戦略として扱う。

No-Regret Learningは長期で「別の戦略を選べばよかった」という後悔を小さくする。

Robust Optimizationで平均だけでなく最悪対面も守る。

最強デッキ探索は、全部探す仕事ではなく、良い候補だけ残す工場だ。

16. AIが負けた理由を取る――action trace・ablation・反実仮想

「新AI、勝率下がりました」だけでは次に進めない。

毎ターン、候補、各候補の点数、選択、objective、EP/SEP予約、コンボ札の早切り、missed lethal、hand burn、board lockをaction traceとして残す。

原因候補を1個ずつ切るのがablation。

同じ盤面から実際に選んだAと、選ばなかったBを両方シミュレーションするのがcounterfactual、反実仮想。

「Aを選んだ試合は負けやすかった」だけでは相関。同じ状態からBへ変えたら本当に勝率が上がるなら、因果に近づく。

17. 新弾対応――環境をsnapshot化し、変わった部分だけ再計算する

新弾、能力変更、禁止・制限、人気デッキの変化に対して、

environment_id
date
format
legal_sets
engine_hash
card_db_hash
policy_hash
deck_corpus_hash
meta_hash

を固定する。

新しいカードDBが来たらdiffを取り、新カード、修正カード、関連カード、影響するデッキ、影響する対面を出す。

カードが1枚変わっただけなら、全試合をゼロから回さず、その周辺だけ再計算する。メタ比率だけ変わったなら、試合を再利用して重みだけ再集計できる。

新弾のたびに研究所を建て直すのではなく、差分だけ夜勤させる。

18. ソフトウェア構成――CLI中心の小さい研究所にする

src/
  upstream/
  deck/
  policy/
  simulation/
  diagnosis/
  statistics/

config/
data/
reports/
docs/
tests/

CLIはstatus、doctor、db check、env validate、simulate、experiment run、experiment analyze、optimize、diagnose、context buildのように分ける。

巨大な生traceやエンジン本体はGitへ入れず、cacheへ置く。

Gitに残すのはlock、config、manifest、hash、集計結果、再現コマンド、小さいfixture。

GitHubはコード置き場だけでなく、研究所の外部記憶になる。

19. ゼロイチ実装順――いきなり最強AIを作らない

1 カードDBを読める
2 最小ルールで1試合完走
3 合法手生成と対象選択
4 seed固定・replay・hash
5 単純AIで100戦
6 coverage監査と全カード対応
7 大会デッキで対面表
8 人間prior
9 木探索・belief
10 paired A/B・holdout
11 デッキ最適化
12 行動診断・新弾差分更新

最初から1万戦、MCTS、強化学習、最強40枚を全部やると、何が壊れたのか分からない。

まず1試合を正しく。次に100試合。その後に1万試合。

1万回高速で間違える機械を作るな。

20. 結論――カードゲームシミュレーターは「ゲーム」より「研究工程」を作るもの

本当に難しいのはカードを表示することではない。

世界を正しく数字にする、ルールを正しく動かす、正解候補を落とさない、見えない情報をチートせず扱う、AI同士を公平に比較する、勝率以外の弱点も見る、失敗理由を観測する、新弾が来ても再利用できる――ここが本体だ。

カードDBは記憶。ルールエンジンは物理法則。方策は頭脳。探索は先読み。統計は成績表。行動traceは監視カメラ。Gitは研究ノート。AIエージェントは研究員。

そして人間は、「その数字、本当に信用していい?」を聞く所長である。

最初は「疾走ドーンしたい」だけだった。

気づけばカードゲームAI研究所、開設。

まあ最後にやることは同じだ。

守護どける。進化する。

疾走ドーン。


PRこの記事の作品を探す

  • 『Shadowverse: Worlds Beyond』

    この記事で扱った『Shadowverse: Worlds Beyond』の検索結果です。

この記事には広告(アフィリエイトリンク)が含まれます。 広告について

今日これ読んで

この記事を読んだ人の次の疑問に、それぞれ答える記事です。

すべての記事から探す「カード・ボードゲーム」の記事をもっと見る

広告

他の記事を探す

すべての記事

めんどいちゃん

このサイトの運営者

めんどいちゃん

仕事や日常の「めんどい」を構造化して、次に動きやすくする記事を書いています。

広告

新着記事

  1. 1一度動くと担当になる職場――思いつき、追加業務、責任範囲をどう切るか
  2. 2能力不足を責める前に業務を設計せよ――解雇論が示すマネジメントの基本
  3. 3休んでいるつもりなのに休めないのはなぜか:脳の検索窓が閉じていない日の話
  4. 4男子トイレの床はなぜ濡れるのか
  5. 5税・社保サブスク、払ったなら使い倒せ――GPIF約318兆円、資格最大80%、UR「4ナイ」まで合法テイカー入門

あわせて読みたい

広告