pythonでstarsの統計みたいなことをやる

※読者がpythonの知識を持っているものとします。

SpireStarsは素晴らしいサイトですが、勝率を公開したくない場合や、Starsよりも詳しい統計を知りたい場合があるかもしれません。そのため、実際に私が使っている手法を記載しようと思います。

2023年7月時点のStarsではわからない情報の例を挙げると、同じ敵の2層前半と後半での被害の違いや、戦闘ターン数の平均以上のターン数の情報、特定の敵との戦闘時間4ターン以下と5ターン以上だった時の被害の比較など、でしょう。すべてこの手法でカバーできます。

ここでは例として、2層前半のスレイバー戦(前半後半を分けるのは2層真ん中の宝箱)でのかかったターン数を調べるコードを見てみます。pythonの知識があればコピペして、自由にカスタマイズできると思います。

import glob, re, collections, statistics, math

#runファイルへのpath 人によって異なる可能性がある。また、おそらく一番上のセーブデータのアイクラについて調べている
path = R"C:\Program Files (x86)\Steam\steamapps\common\SlayTheSpire\runs\IRONCLAD"
path_list = glob.glob(path + R"\*")
path_list.reverse()


#今回はターン数が入る
ans_list = []
dic = collections.defaultdict(int)

#タスクマスター戦の数をカウントする
count = 0

for p in path_list:
    #dataにrunファイル全体を入れる
    f = open(p, 'r')
    data = f.read()

    #A20かつシード値指定やカスタムモードを除外
    #おそらくrun_history_plusやslay_the_relicがあると記述が変化するので、2種類のa20の表現がある
    if ("Ascension (20)" in data) or ('"ascension_level":20' in data) and '"chose_seed":fal' in data:

        #スレイバーズ戦のデータに注目する
        tmp2 = re.findall('"damage":\d+\.?0?,"enemies":"Slavers","floor":\d+\.?0?,"turns":\d+\.?0?', data)

        #年月日
        lastday = str(re.findall('202\d..........', data))
        lastday = lastday[4:6] + "年" + lastday[6:8] + "月"

        #1つのrunファイルに複数スレイバー戦があるかもしれないのでfor文
        for t in tmp2:

            #階層
            floornum = int(re.findall('"floor":\d+', t)[0][-2:])
            #26階が2層真ん中の宝箱
            if floornum < 26:
                #その戦闘での被害量
                #今回は使用しない
                damage = int(re.findall('[0-9][0-9]*', t)[0])

                #turnにturn数を入れる
                #この部分が整数の場合と少数の場合がある(25と25.0のように)ので正規表現
                a = re.search("[0-9]+\.?0?", t[-5:])
                turn = int(float(a.group()))

                #ターン数を保存し、カウント追加
                ans_list.append(turn)
                dic[turn] += 1
                count += 1
    
    #望む量のデータが集まったら結果を出力する
    if count >= 50:
        print("2層前半で%d回スレイバーズと戦闘した際の平均ターン数は%.2fで、%sまでの記録を含みます"% (count, statistics.mean(ans_list), lastday))
        print("平均ターンの95%信頼区間は%.2f~%.2fでした"%(statistics.mean(ans_list) - statistics.pstdev(ans_list)/math.sqrt(count), statistics.mean(ans_list) + statistics.pstdev(ans_list)/math.sqrt(count)))
        for k, v in zip(dic.keys(), dic.values()):
            print("%dtかかった回数は%d"%(k, v))
        exit()

〜

このコードを編集すれば結構いろいろとできます。少し複雑かもしれませんが、お役に立てればうれしいです。