『ゼルダの伝説 風のタクト』にて“運任せで極めて厄介”とされた海戦ゲームの仕組みは、どのように解かれたのか。執念が生み出した最適解

Pocket
reddit にシェア
LINEで送る

RNG。もともとはRandom Number Generator、つまりは乱数を発生させる仕組みそのものを指していたこの略語は、転じてゲーマーにとっては「運要素」そのものを指す言葉となっている。RNGはスピードランナー達にとって最大の敵でもある。そして「いかにして自分の走るルートからRNGを排除するか」に心血を注ぐスピードランナー達、その一人が『ゼルダ』シリーズの走者として知られるLinkus7氏である。彼が今回RNGの魔の手から解放したタイトルは『ゼルダの伝説 風のタクト』(以下、『風のタクト』)、特にそのゲーム中に登場する「海戦ゲーム」だ。Linkus7氏はその戦いの軌跡を解説動画としてアップロードし、大きな反響を呼んだ。本記事では「我々がいかにしてゼルダシリーズ最悪のミニゲームに決着をつけたか」というタイトルのその動画の内容の、日本語での解説を試みる。なお解析が成功されたのは2020年5月ということで、出来事そのものは昨年のことであることも留意いただきたい。


海戦ゲームとは?

まずそもそも「ゼルダシリーズ最悪のミニゲーム」とまで言われるこの海戦ゲームとは何なのだろうか?英語ではSploosh Kaboomと呼ばれるこの海戦ゲームは、タウラ島でドワルスキーに話しかけると遊べるミニゲームだ。ミニゲームの内容はいわゆる海戦ゲーム(バトルシップゲーム)まんまとなっており、8×8マスのフィールドに最大24発の爆弾を撃ち込み、隠れている3体のイカを沈めると勝ちとなっている。3体のイカにはそれぞれ4、3、2マスの長さがあり、イカを構成する全マスに爆弾を命中させなければ撃沈できない。非常にオーソドックスな海戦ゲームだ。


『風のタクト』RTAの100%カテゴリはハートのかけらや宝のマップも全コンプリートする必要があるカテゴリとなっているため、それらが手に入るこのミニゲームを避けて通ることはできない。これらの景品はまず24発以内での初クリアでハートのかけら、次のクリアで宝のマップが手に入る。そしてドワルスキーの自己ベストである20発を更新することで、もう一枚宝のマップが手に入る。よって、スピードランのためには「24発以内の初回クリア」と「19発以内の2回目クリア」の最低2回、このミニゲームをクリアしなければならないのだ。

しかしながらこのゲーム、完全なる運ゲーである。64マス中24マスしか撃ち込めず、その内9マスを的中させなければならない。19発以内でのクリアをしなければ先に進めないため、運が悪いと何十分もこのミニゲームをやり続けることになる。このミニゲームは100%ルートにおける開始30分地点付近にあり、即リセットをかけるのも躊躇われる絶妙に深い位置だ。100%はそこまでメジャーなカテゴリではないとはいえ、Linkus7氏にとってこのRNGは耐え難いものであったのだ。

『風のタクト』における乱数の仕組み

かくしてLinkus7氏を中心としてこの海戦ゲームからなんとかして運要素を排除せんとする試みが開始した。3体のイカの配置が特定のパターンからの抽選だったのなら話は早かったのだが、残念ながら完全なランダム配置となっている。「海戦ゲーム」を攻略するには、『風のタクト』の乱数システムから紐解く、リバースエンジニアリング的なアプローチが必要だった。

調査の結果、『風のタクト』の乱数にはWichman-Hillと呼ばれる疑似乱数生成器が利用されていることが判明した。これはいわゆる線形合同法を利用した乱数アルゴリズムであり、疑似コードは以下のようなものとなる。

double rng() {

    static int s1 = 100, s2 = 100, s3 = 100;

    s1 = (171 * s1) % 30269;

    s2 = (172 * s2) % 30307;

    s3 = (170 * s3) % 30323;

    return fmod(s1/30269.0 + s2/30307.0 + s3/30323.0, 1.0);


コードやアルゴリズムの詳細については省くが、ここで重要なのは、よくある実装では現在の時間などを参照して決められるはずの3つの初期シード値(s1~s3)が、『風のタクト』ではすべて起動時に100に固定され、リセットされることもないということだ。これはつまり、『風のタクト』が起動してからゲーム中で消費する乱数の値は(この疑似コードで計算するだけで)すべて予測が可能だということに他ならない。


ちなみに、『風のタクト』が与えられた乱数値からどのようなアルゴリズムで海戦ゲームのイカを配置しているかも、疑似コードとしてとっくに解析済であった。生成される乱数値が前述のようにすべて予測可能である以上、もう解決なのではないかという気がしてくるが、残念ながらそう簡単な話ではない。1フレームごとに消費される乱数値の個数がさまざまなゲーム内要素に影響を受けて絶えず変化しているせいで、「海戦ゲームのイカが配置される瞬間」にどの乱数が消費されるのかを予測するのが非常に困難なのである。

ゲームにおいて、乱数は絶えず猛烈な勢いで消費されていく。たとえばゲーム画面内に映っている、ルピーの輝きの処理に乱数は使われている。リンクがまばたきをするかどうかにも乱数は使われている。風に揺れる草の挙動にも乱数が使われる。敵モンスターがいるのならば、そのAIの挙動にも乱数は使われる。これらひとつひとつに使用される乱数は「消費」され、乱数生成コードが再び実行され、次の乱数が用意される。『風のタクト』を普通にプレイしていて、1フレームで消費される乱数の個数は10~1000にも及ぶ。ゲーム内のありとあらゆる要素が乱数を消費していくため、乱数の消費ペースを正確に予測することは非現実的だ。「ゲームを起動してから5万個目に消費される乱数の値」は予測可能。初期シードが固定な以上、件の疑似コードを5万回実行するだけでいい。しかし「ゲーム内におけるどのタイミングで5万個目の乱数が消費されるか」を正確に予測することは困難極まる、というわけだ。同じように、「今このタイミングで消費される乱数はゲームを起動してから何個目なのか」を正確に判断するのも、とてもではないが不可能だ。


つまりこれはプレイヤー側の操作精度で乱数を固定する方法も不可能であることを示している。仮にプレイヤーが非人間的な操作精度を持ち、ゲームを開始してから海戦ゲームにたどり着くまでが毎回ピッタリ同じフレームだったとしても、ルピーが画面に映っていた時間がほんの数フレーム長かったりするだけで乱数の消費個数はズレ、まったく違うイカの配置を引くことになる。いわゆる「Frame Perfect」も通用しないのだ。

ヒートマップと正規分布

イカを配置するのに使われる乱数を正確に特定することは非現実的ということが分かった。しかし、そもそも正確に特定する必要はない。「配置候補」がある程度まで絞り込めるのならば、イカが配置されている確率が高い所を示すヒートマップを生成し、1発撃ち込むごとに消去法で配置候補の中から実際の配置を特定することが可能のはずである。


配置候補が右の12種類であり、これらが等確率で出現する時、ヒートマップは上記画像のようになる。ここから58%のマスに撃ち込んでミスだった場合、そのマスにイカが配置されている7つの候補は消去され、新たなヒートマップを生成することができる。


この操作を繰り返すことで最小限の手数で配置を絞り込むことができるというわけだ。

この方法ならば、ある程度配置候補の絞り込みさえ出来れば19発以内にクリアというのは十分すぎるほど現実的だ。そして乱数の生成規則とイカの配置アルゴリズムも判明している以上、配置候補をピックアップすることもさほど難しくはないはずだ。仮に1フレームにつき平均乱数消費個数が3で、ゲーム起動から5フレーム目にイカの配置が行われるとする。この時、一番イカの配置に使われる可能性が高いのは当然15個目の乱数だ。しかしもちろんフレームごとに消費される乱数個数は大小する上に予測も困難なので、15を平均とした正規分布曲線を描き、それぞれの乱数値から生成される配置候補の加重平均を取ったヒートマップを生成すればいいだろう。


さて、実際のランにおいては海戦ゲームにたどり着くまでに大体30分ほどかかる。Linkus7氏レベルの熟達したプレイヤーが、100%ルートで海戦ゲームにたどり着いた時点でどれほどの乱数が消費されているかを検証すると、最初のボード生成(イカの配置)までに平均で550万ほどの乱数が消費されているという結果になった。これに現実的な分散の値を設定し正規分布曲線を描き、さきほどと同じように加重平均を取ったヒートマップを描くと以下のようになる。


候補が多すぎるためか、ほとんどノーヒントに近いヒートマップが生成されてしまった。残念ながらこれでは運に任せて撃ち込んでいるのと大差ないだろう。手法は良さそうだが、もうひと押しが必要だ。


1つめのボードを捨てる

与えられた乱数からイカが配置されるアルゴリズムが判明しているということは、逆にイカの配置から乱数候補を逆算することができるということだ。『風のタクト』の海戦ゲームでは、24発を撃ち切って失敗した時もそのときの正解のイカ配置を教えてくれる。この情報を利用すれば、最初のボードが生成された瞬間の乱数候補を絞り込むことが可能だ。

「海戦ゲーム」最初のボードは、ミニゲームをプレイできる部屋に入って画面が暗転した瞬間に生成される。プレイヤーは海戦ゲームをスタートし、24発を最速で適当に撃ち込む。ミニゲーム自体は十中八九失敗に終わるが、どちらにせよゲームは正解のイカの配置を教えてくれる。このイカの配置に対応する乱数値は限られている。画面が暗転し最初のボードが生成されるまでに平均550万の乱数が消費されていることを思い出せば、さきほど描いた正規分布曲線上にイカの配置から逆算した「乱数値候補」をプロットすることができる。


64マスにおける完全にランダムなイカの配置候補は60万以上あり、そのうちの1つを生成する乱数値候補は比較的限られている。550万を平均とする巨大な正規分布の中であっても、特定のイカ配置を生成し、現実的な確率で正規分布内に収まる乱数候補はそれほど多くない。

海戦ゲーム2回目のボード生成は、1回目のボードをAボタンで閉じた瞬間に行われる。そしてこの海戦ゲームのミニゲーム部屋の中は乱数を消費する要素が少ないため、平均して1フレームごとに8個の乱数が消費される。ミニゲーム部屋に入った瞬間の暗転(1つめのボード生成)から最初のミニゲームを閉じた瞬間(2つめのボード生成)までの時間が計測されていれば、その間に消費された乱数の個数も大体予測がつく。もちろん正確に予想することは困難だが、当初はプラマイ20万個レベルでヒートマップを生成しようとしていたのに比べれば雲泥の差だ。最初のイカ配置から得た「乱数候補」の地点から、初回と2回目のボード生成の間に消費されたと乱数の予想個数分右にずれた位置に、新たに正規分布曲線を描く。これは2回目のイカ配置に使われた可能性が高い乱数値をあらわした曲線となる。


ここまで絞り込めていれば、2つの正規分布曲線から生成されたヒートマップに沿って撃ち込んでいるだけで、あっという間に消去法でイカ配置を特定することができる。記事の最初で述べたようにこのミニゲームは合計2回クリアする必要があるが、2回目のイカ配置情報が手に入るとさらに乱数候補が絞り込まれ、3回目(1ゲーム目は捨てているので)のミニゲームではさらに正確なヒートマップを生成することができる。


かくして1回目のミニゲームを捨ててイカの配置情報を入力することで、高精度で2回目以降の配置を予測するツールが完成したのである。

Linkus7氏は動画の最後で「なぜスピードランにおいてこのツールの利用が認可されたのか」についても語っている。まずそもそもこのツールの利用を許可するかどうかについてコミュニティでは投票を行っており、許可が多数で勝利している。また、このツールは誰でも使えるように公開されていて、かつすべての操作は手動で行われている。Linkus7氏はこのミニゲーム中は片手でコントローラーを操作し、もう片方の手でこのツールに命中情報を入力しているとのこと。エミュレーターと連動してメモリを読んだり、なんなら画像認識で、自動で命中情報がアップデートされたりするようにツールを作ることも十分可能だったと思うのだが、あえて手動で入力する必要があるように作ったという。そのほうがコミュニティのツールに対する抵抗が少なく、許可される可能性が高いからだと思われる。一方、このミニゲームに対する憎しみが垣間見える執念とも見える。

ちなみにこのツールはWeb上で利用することも可能であり、『風のタクト』であれば無印やHD版問わず、あらゆる機種に対応している。また、繰り返すようだが本記事はLinkus7氏本人による解説動画を元にしたものであり、動画は実際のクリップやグラフのアニメーションも利用した非常にわかりやすいものとなっている。英語が得意な方は動画も見てみることをオススメする。また英語が苦手であっても動画には一見の価値があり、本記事がこのスピードランナーの執念が詰まったRNGとの戦いの記録を理解する一助となれることを願っている。

Pocket
reddit にシェア
LINEで送る