OceanライブラリをPythonに移植した

Nintendo Switch

Oceanライブラリとは

初期シードから計算できる「イベント内容」「潮位」「湧き方向」「出現オオモノ」を計算するためのライブラリのこと。

具体的にはスプラトゥーンの乱数ライブラリ+サーモンラン用の計算ライブラリといった感じ。

スプラトゥーンの乱数生成アルゴリズムはものすごく単純(その変わり高速!)なので実装はものすごく楽です。

今までは面白そうなWAVEを探したりして遊んでいたのですが、結局のところ面白いWAVEを探していたのはぼくとコンテナさんだけだったので「誰でも探せるようにしよう」というのが今回の目論見です。C++に比べてPythonは初学者でもとっつきやすく、JavascriptのようにNodeJSで環境つくったりが要らないので導入も楽です。

Pythonの導入

まずPythonを導入する必要があるのですが、これはもうどう考えてもMicrosoft Storeからインストールしてくるのが楽なのでそうしましょう。

以下のリンクを踏めば上手いことインストールできるはずです。

VSCodeのダウンロード

VimとかEmacsとかどうでもいいのでまずはVSCodeを使いましょう。

ぼくはこれで完全にVimからVSCodeに移行したくらいなので。

Oceanライブラリのダウンロード

OceanライブラリはGitHubで公開しているので誰でも扱えます。

tkgstrator/StarlightSeedHack
SeedHack is the best way to fix waves for Salmon Run in the Shoal. - tkgstrator/StarlightSeedHack

この中のmain.pyだけを弄っていきます(他は絶対に触らないように!)

ライブラリの使い方

from library import Ocean

if __name__ == "__main__":
    mOcean = Ocean.Ocean(1)
    print(mOcean.mEvent, mOcean.mTide)
    mOcean.setWaveMgr()
    print(mOcean.mWaveMgr[0].mAppearIds, mOcean.mWaveMgr[0].mBossIds)
    print(mOcean.mWaveMgr[1].mAppearIds, mOcean.mWaveMgr[1].mBossIds)
    print(mOcean.mWaveMgr[2].mAppearIds, mOcean.mWaveMgr[2].mBossIds)

from library import Oceanでライブラリを読み込みます。

mOcean = Ocean.Ocean(1)は初期ゲームシード1の場合の情報を読み込むという意味です。ここの数字を変えることで様々なシード値からのWAVE内容の予測ができます。

ここまでを書いた時点でイベントと潮位について計算を自動で行ってくれます。計算結果を得るためには、mOcean.mEventmOcean.mTideを参照してください。

これらは長さが3の配列で、例えばWAVE1の潮位が知りたければmOcean.mTide[0]とすることで読み込むことができます。

WAVEの詳細を先読み

Oceanクラスは最初にイベントと潮位だけを計算し、湧き方向やオオモノの種類は計算してくれません。毎回無意味に湧き方向やオオモノの種類を計算していると処理がとても遅くなってしまうためです。

イベントや潮位を知った上で「更に細かいデータを知りたい」という場合にはmOcean.setWaveMgr()で更に細かいデータを計算することができます。

本当なら指定したWAVEだけ計算できればいいのですが、書くのがめんどくさかったのでこの関数を呼び出すと全てのWAVEをいっぺんに計算します、なのでちょっとだけ重いかもしれません。

setWaveMgr()が計算可能なのは湧き方向とオオモノの種類だけで、キンシャケ探しのアタリ位置は対応していません。何故なら、書くのがめんどくさかったからです。

キンシャケ探しやラッシュであれば湧き方向とかオオモノ種類は必要ないのですが、一応計算してくれます。なんでそんな仕様なのかというと、分岐させるのがめんどくさかったからです。

計算後はmWaveMgrという要素数が3の配列にアクセスすることができます。mOcean.mWaveMgr[0]であれば「WAVE1の詳細情報」を意味しているわけです。

mWaveMgrクラスが持っているのは湧き方向とオオモノの種類で、これは以下のメンバ変数にアクセスすることで得られます。

mOcean.mWaveMgr[0].mAppearIds
mOcean.mWaveMgr[0].mBossIds

例えば、WAVE1の最初に出現するオオモノを知りたければmOcean.mWaveMgr[0].mBossIds[0]とすればよいわけです。

PythonはC++に比べて配列の標準ライブラリが豊富なので、いろいろ条件をつけて調べることができるはずです。

今後の展望

PythonはC++に比べてかなり柔軟にコードを書くことができ、実装も一時間程度で終わらせることができた。

ただ、全通り検索するとなるとPythonはかなり非力なのであらかじめ候補を絞っておいた(多くても1000万くらいでないと厳しい)シードに対して「より細かく調査する」という使い方が正しいような気がします。

PythonでWAVEの詳細データを計算できるようになったので、C++は単にWAVEのイベントと潮位を先読みしてそれらをリスト化してしまえばよいわけです。

全満潮昼や全干潮昼のWAVEであれば全部で160万通りくらいしかないので、テキストファイルにしてもたかが知れているので配布は可能でしょう。

ただ「三つのWAVEのどれかが満潮キンシャケ探し」「WAVE3が通常昼」のような候補がものすごく多くなるような条件だと、普通に1億通りを超えてしまうのでシード表の配布は不可能です。

ある程度条件をつけて数を減らさないと厳しいでしょう。

現状はファイル読み込み機能がついていないので、いろいろシードを出力して対応できるようにしてみようと思います。

記事は以上。

コメント

タイトルとURLをコピーしました