この記事について
10月17日に、こはねがSlay the Spire 2を自動で遊ぶ配信をした(前回の記事)。 そのときは1章のボスを倒し、2章の第25層で負けた。
今回はアイアンクラッドのアセンション0(いちばんやさしい難易度)で、最後の3章のボスまで倒すことを目標にした。 11月2日と3日の2日間で、配信をしないテストのランを十数回くり返し、負けるたびに原因を調べて直した。 11月3日の夜には、直している途中のプログラムで2回目の配信もした。 この記事では何をどの順に直していったかを書く。 作業は前回と同じく、ほとんどClaude Code(開発用のAIエージェント)にしてもらい、私は記録や画面を見て気づいたことを伝えた。
- アーカイブ: 11月3日の配信
直し方
1回のランが終わるたびに、次の順で進めた。
- ゲームループの記録(1手ごとの選択肢と、選んだ理由)から、負けた戦闘と、その前の判断を読む。
- 原因を1つ決め、直す前に落ちるテストを書いてから直す。
- 決めたことと試してやめたことを、その日のうちにADR(決めたことを1件ずつ残す記録)に書く。
- ループを起動し直して、次のランを始める。
ADRは2本になり、ランが終わるたびに、何で負けたかと何を直したかを書き足していった。
攻略の知識を持たせる
前回の仕組みは選択肢を判断役のAI「Jev」に選ばせるだけで、ゲームの攻略の知識を持っていなかった。 最初に、Claude Codeにアイアンクラッドの攻略を調べさせた。 調べたのは、カードとその組み合わせ、レリック、定石、各章のボス、雑魚敵とエリートの行動と倒す順番だ。 Slay the Spire 1の情報が混ざりやすいので、2の情報を優先させた。
調べた結果はゲームの中のIDで引ける1つのJSONファイルにした。 敵108、ボス12、エリート12、カード110、レリック78、ポーション47、イベント44の項目がある。 この知識はほとんどを決め打ちのルールにせず、選択肢の説明に短い注記として足している。 たとえば、マップでエリートの部屋を選ぶときは、今のHPと、2部屋以内に休憩所かショップがあるかを書き足す。
あわせて、Slay the Spireを遊ぶAIの論文も、alphaXivで調べてもらった。 SpireBenchでは、LLMは休憩所で休みすぎ、エリートを避けすぎると報告されている。 攻略本やRedditの文章をそのままプロンプトに貼ると、かえって少し悪くなったという。 DemoEvolveでは人のプレイの要約を貼っても効かず、コードのルールにしたら効いたと報告されている。 攻略の文章を長く貼らずに、短い注記とルールにする今の形は、この結果に合わせたものだ。
戦闘は手順探索で決める
次に、戦闘の1ターンを計算で決める「手順探索」を作った。 手札とエネルギーで出せるカードの順番と狙う敵をすべて試し、与えるダメージと、次の敵のターンに受けるダメージを計算する。 点数は、この戦闘でこれから失うHPの見積もりが少ないほど高い。
最初は、手順探索の答えは参考としてJevに見せ、決めるのはJevにしていた。 ところが、手順探索が攻撃を勧めているのにJevが3回とも防御を選び、毎ターン強くなる敵を削りきれずに負けた。 それからは、戦闘のカードは手順探索の最初の1枚を必ず出し、Jevはポーションやカードの選択など、手順探索が扱わないことだけを決めるようにした。
手順探索には負けるたびに読めていなかった効果を足していった。 負けたときに見つかった読み落としは、次のとおりだ。
- 手札に残すとHPを失う「誘い」を、使うと損なカードと読んでいた。抱えたまま、最後の2ターンで24失って負けた。
- パワー(ジャガーノートなど)の価値を0と見ていて、何ターンも出さなかった。
- 自分のターンの最初に深紅の衣でHPを1失うのを数えず、HPが1残ると見た手で死んだ。
- 倒した滝の巨人が次のターンの終わりに撃つ45ダメージを、攻撃と数えていなかった。
- プレイできない「衰微」を手札に残すと受ける9ダメージ×2を数えず、3章のボスの残りHP 17で負けた。
- 2章のボス(知識の悪魔)が付ける「崩壊」(ターンの終わりに13ダメージ)を数えず、毎ターン守らなかった。
- 外骨格蟲の「不死身」(1回に9ダメージまでしか受けない)を数えず、HP 28の相手に42ダメージの脳天割り+を「倒せる」と見て使った。
ポーションの使いどころ
負けたランの多くは、ポーションを持ったまま終わっていた。 一方で、使いどころを間違えることもあった。
- 雑魚戦でHPに余裕があるうちに飲んだ。はじめは雑魚戦でHPが半分以上なら選択肢に出さないようにし、ラストランの途中からは、そのターンの被弾でHPが3割を切るときだけ出すようにした。
- 筋力や敏捷のポーションを、攻撃や防御のカードを出し終えてから考えていた。ボスとエリートでは、先に飲むようにした。
- 敵の残りHPが6で次のターンに勝てるのに、2つ飲んだ。勝ちが決まった場面では出さないようにした。
- 受けるダメージが残りのHP以上になるターンでも、飲まずにターンを終えていた。この場面では、ブロックか回復のポーションから先に飲むようにした。
ラストランでは、私が画面を見て気づいた使い方も直した。
- 手札のコストを0にするポーションを、安いカードしか残っていないターンの終わりに飲んでいた。ボスとエリートでは、コスト2以上のカードが手札にあれば、ターンの最初に飲むようにした。
- カードを3枚引くポーションをエネルギーを使い切ってから飲み、引いたカードを出せなかった。エネルギーが残っているうちに飲むようにした。
- 毎ターンブロックを得るポーション(鉄の心臓)を、HPの多い雑魚と長く戦う場面で使わなかった。敵のHPの合計が100以上なら、雑魚戦でも1〜2ターン目に飲むようにした。
カード報酬やマップの選択
カード報酬、マップ、ショップ、イベント、休憩所のように、ラン全体を見て決める画面は、Jevの代わりにClaude Sonnetが選ぶようにした。 論文のAgenticSTSでも、こうした判断には強いモデルを使っている。
Sonnetには今のデッキで目指す形(脆弱、筋力、廃棄、自傷のどれか)も渡している。 デッキのカードの特徴の数から1つを決め、何を集めるかと一緒に伝える。 この形は戦闘でも使い、目指す形のパワーを少し高く数え、廃棄するカードを選ぶ画面では形の要のカードを残す。
13回目のランでは、廃棄するカードを選ぶ画面で、Jevが「先に廃棄する」と注記した防御を外し、32ダメージの脳天割りを廃棄していた。 そこで廃棄の選択も状態異常と呪い、防御、ストライクの順に選ぶルールにした。
配信で直したこと
11月3日の21時から、2回目の配信をした。 1回目のランは1章のボスで、2回目は第5層で負け、44分ほどで締めた。
配信の記録を見返して、大きな不具合が見つかった。 自分のコードで例外が出たあと、復旧の処理が「ターン終了」を押していて、戦闘のターンの約半分を何もせずに捨てていた。 例外のあとは、画面を見たHaikuに手を選ばせるように直した。
視聴者の投票も配信のあとに考え直した。 前回はカード報酬や休憩所などの分かれ道をすべて投票にしていた。 答えがはっきりしている場面まで聞くと時間がかかり、配信では、HP 45%で休むべきボス前の休憩所が投票で鍛冶になった。 今は、こはねが迷っている場面だけを聞く。 Sonnetに答えの確信を0〜100で書かせ、65以上なら投票せずに理由をひとこと言って進む。 迷っているときは、迷っている2〜3個の候補だけを出して、「◯◯と◯◯で迷ってるんだ。どっちがいいと思う?」と聞く。 選ぶ価値のない選択肢まで並べると、変な選択がされやすいからだ。 目安は半分くらいを自分で決めることで、13回目のランでは43%を自分で決めた。
戦闘中のコメントにも応えるようにした。 「◯◯ポーションを使ったほうがいいよ」のようなコメントが来たら、今使うのが理にかなっているかをSonnetに聞く。 理にかなっていれば使ってお礼を言い、そうでなければ取っておく理由を言う。
ラストラン
14回目のランを、この一連のテストのラストランにした。 1章のボスの滝の巨人を倒し、2章のボスの貪りの獣も倒して、3章に入った。 3章の第36層と第37層で HP を80から28まで減らし、第38層の雑魚戦(カエルの騎士、HP 191)で負けた。 分かれ道の12場面のうち、こはねが自分で決めたのは4場面(33%)だった。
このランを見ながら、さらに2つの読み落としに気づいた。
- 貪りの獣の「蟻地獄」は、数が尽きるとプレイヤーが食われて即死する。数を1増やす「決死の逃亡」を出すかはJevに任せたままで、廃棄のルールは状態異常としてこのカードを捨てていた。蟻地獄が2以下なら決死の逃亡を最初に出し、廃棄では選ばないようにした。
- レリックの鮮やかなスカーフは各ターン5枚目に出すカードをコスト0にする。4枚出すと手札が全部コスト0と表示されるが、タダになるのは1枚だけだ。手順探索はこれを知らず、負けた戦闘でもコスト2のパーフェクトストライク+ではなく、コスト1のストライクをタダの5枚目に出していた。どの1枚をタダにするかも探索で選ぶようにした。
どこまで進んだか
| 日 | ラン | 負けた場所 |
|---|---|---|
| 11月2日 | 1 | 第23層(2章の雑魚戦) |
| 11月2日 | 2 | 1章のボス(ソウルフィッシュ) |
| 11月2日 | 3 | 2章のボス(知識の悪魔) |
| 11月3日 | 4 | 1章のボス(滝の巨人) |
| 11月3日 | 5 | 1章のボス(滝の巨人) |
| 11月3日 | 6 | 第23層(2章の雑魚戦) |
| 11月3日 | 7 | 第14層(1章の雑魚戦) |
| 11月3日 | 8 | 3章のボス(永劫の砂時計、残りHP 17) |
| 11月3日(配信) | 9 | 1章のボス(ソウルフィッシュ) |
| 11月3日(配信) | 10 | 第5層 |
| 11月3日 | 11 | 2章のボス(知識の悪魔) |
| 11月3日 | 12 | 第23層(外骨格蟲) |
| 11月3日 | 13 | 1章のボス(滝の巨人) |
| 11月3日 | 14 | 第38層(3章の雑魚戦、カエルの騎士) |
いちばん進んだのは8回目で、3章のボスの残りHP 17まで削った。 直したあとのランが毎回それより先へ進んだわけではない。 3章のボスを倒すところまでは届かなかった。
AIにゲームを遊ばせて分かったこと
- 負けたら、記録から原因を1つずつ読む。Claude Codeは一度、記録の数字1つから「ボスのあとはHPが回復しない」と決めて、正しかった知識を書き換えた。
- 計算で決まることはプログラムに任せる。前回の記事に書いたとおり、Jevは数を数えるのが苦手だ。
- AIの役割を分ける。戦闘のカードは手順探索、ポーションなど戦闘中のそのほかの判断はJev、ラン全体を見る判断はSonnetにした。
- 視聴者には、こはねが迷っているときだけ聞く。答えがはっきりしている場面まで投票にすると、時間がかかり、弱い選択も選ばれやすい。