この記事について

10月17日に、こはねがSlay the Spire 2を自動で遊ぶ配信をした(前回の記事)。 そのときは1章のボスを倒し、2章の第25層で負けた。

今回はアイアンクラッドのアセンション0(いちばんやさしい難易度)で、最後の3章のボスまで倒すことを目標にした。 11月2日と3日の2日間で、配信をしないテストのランを十数回くり返し、負けるたびに原因を調べて直した。 11月3日の夜には、直している途中のプログラムで2回目の配信もした。 この記事では何をどの順に直していったかを書く。 作業は前回と同じく、ほとんどClaude Code(開発用のAIエージェント)にしてもらい、私は記録や画面を見て気づいたことを伝えた。

直し方

1回のランが終わるたびに、次の順で進めた。

  1. ゲームループの記録(1手ごとの選択肢と、選んだ理由)から、負けた戦闘と、その前の判断を読む。
  2. 原因を1つ決め、直す前に落ちるテストを書いてから直す。
  3. 決めたことと試してやめたことを、その日のうちにADR(決めたことを1件ずつ残す記録)に書く。
  4. ループを起動し直して、次のランを始める。

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日21章のボス(ソウルフィッシュ)
11月2日32章のボス(知識の悪魔)
11月3日41章のボス(滝の巨人)
11月3日51章のボス(滝の巨人)
11月3日6第23層(2章の雑魚戦)
11月3日7第14層(1章の雑魚戦)
11月3日83章のボス(永劫の砂時計、残りHP 17)
11月3日(配信)91章のボス(ソウルフィッシュ)
11月3日(配信)10第5層
11月3日112章のボス(知識の悪魔)
11月3日12第23層(外骨格蟲)
11月3日131章のボス(滝の巨人)
11月3日14第38層(3章の雑魚戦、カエルの騎士)

いちばん進んだのは8回目で、3章のボスの残りHP 17まで削った。 直したあとのランが毎回それより先へ進んだわけではない。 3章のボスを倒すところまでは届かなかった。

AIにゲームを遊ばせて分かったこと

  • 負けたら、記録から原因を1つずつ読む。Claude Codeは一度、記録の数字1つから「ボスのあとはHPが回復しない」と決めて、正しかった知識を書き換えた。
  • 計算で決まることはプログラムに任せる。前回の記事に書いたとおり、Jevは数を数えるのが苦手だ。
  • AIの役割を分ける。戦闘のカードは手順探索、ポーションなど戦闘中のそのほかの判断はJev、ラン全体を見る判断はSonnetにした。
  • 視聴者には、こはねが迷っているときだけ聞く。答えがはっきりしている場面まで投票にすると、時間がかかり、弱い選択も選ばれやすい。