t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

Python・数学・Bing AIでそれぞれSatisfactoryの代替レシピガチャの確率を求めてみた。

今回は私が遊んでいるゲーム Satisfactoryのなかのガチャ要素で狙ったものを引きあてる確率を求めてみた。

Satisfactoryは異星に工場を発展させていく生産シミュレーション系のゲームである。
詳しくは以下の記事で紹介しているので気になる方はチェックしてみて欲しい。
thom.hateblo.jp
ただし面白すぎて生活に支障が出ても責任は負いかねるのであしからず。

さて、このゲームでは部品を組み合わせて製品を作っていくのだが、通常のレシピとは別に代替レシピというものが存在する。

代替レシピはこの世界に転がっている墜落した降下ポッドから入手できるハードドライブというアイテムを分析器にかけることで手に入る。

このように3つの代替レシピが提示され、そのうち1つを選択して入手する形である。

ハードドライブの分析結果は87通り存在し、うち85種類がレシピ、のこり2つはインベントリスロットの増加(要するにキャラ強化)であるが、プログラムを書く上では便宜上レシピ87個としておこう。

つまり87個のうち、3個がランダムで提示されるので、そのうち狙った1点を引き当てる確率がどれくらいかという話になる。
そこでまずはPythonのrandomモジュールを使ってこのガチャをひたすら回すシミュレーションを書いてみた。
ゲームの仕様上、入手済みレシピは提示されなくなるため未開放レシピ数に応じた確率も調べてみた。

from random import randint

for z in range(87,2,-5):
    lookfor = randint(0, z-1)
    number_of_trial = []
    for y in range(10000):
        n=0
        hit = False
        while not hit:
            n+=1
            recipes = list(range(z))
            hit = False
            for x in range(3):
                item = recipes.pop(randint(0,len(recipes)-1))
                if item == lookfor:
                   hit = True
        number_of_trial.append(n)
    
    print("未開放レシピ:" + str(z) + "個",end=" ")
    print("最大:" + str(max(number_of_trial))+"回",end=" ")
    print("平均:" + str(sum(number_of_trial)/len(number_of_trial))  + "回")

実行結果は次のとおり。
例えば87個の未開放レシピが残っている状態で狙った1点を入手するためにリセマラ※した場合、最大270回、平均28.7882回やり直しが必要ということ。
※リセットマラソン=思い通りの結果になるまで挑戦前のセーブデータを読み直す行為。

未開放レシピ:87個 最大:270回 平均:28.7882回
未開放レシピ:82個 最大:311回 平均:27.4874回
未開放レシピ:77個 最大:253回 平均:25.6612回
未開放レシピ:72個 最大:203回 平均:23.8749回
未開放レシピ:67個 最大:219回 平均:22.5432回
未開放レシピ:62個 最大:206回 平均:20.6362回
未開放レシピ:57個 最大:186回 平均:18.7125回
未開放レシピ:52個 最大:179回 平均:16.9635回
未開放レシピ:47個 最大:138回 平均:15.4295回
未開放レシピ:42個 最大:141回 平均:13.8436回
未開放レシピ:37個 最大:105回 平均:12.2546回
未開放レシピ:32個 最大:121回 平均:10.7985回
未開放レシピ:27個 最大:93回 平均:9.0674回
未開放レシピ:22個 最大:87回 平均:7.3508回
未開放レシピ:17個 最大:44回 平均:5.616回
未開放レシピ:12個 最大:30回 平均:3.9715回
未開放レシピ:7個 最大:18回 平均:2.3499回

ハードドライブ1個につき分析に10分かかるので平均して5時間近くかかる見込み。
で、5時間あれば世界中駆け回ってハードドライブ87個集まるので、このゲームでは特にリセマラする意味はないということが分かった。


ちなみにリセマラ回数ではなくて1発で引き当てる確率を求める場合はこのようなコードになる。

from random import randint
lookfor = randint(0, 86)
n=0
for y in range(1000000):
    recipes = list(range(87))
    for x in range(3):
        item = recipes.pop(randint(0,len(recipes)-1))
        if item == lookfor:
            n+=1
print(n/1000000)

3回実行したところ、いずれも3.4%となった。

0.034789
0.034437
0.034695

ちなみに数学的にはこういう式になる。
\displaystyle \frac{_{86}C_2 \times _1C_1}{_{87}C_3}

計算してみると、こちらも3.4%と出た。

>>> (((86*85)/(1*2))*(1/1))/((87*86*85)/(1*2*3))
0.034482758620689655

このようにプログラムによるシミュレーションでも十分な回数を繰り返せば数学的に求めた理論値に近似するので私のように数学が苦手な方はプログラミング力を磨いておくと何かと便利だと思う。

数学・プログラミングどちらも苦手という場合、これからの時代はAIによるサポートを受けることができる。
このように直接聞けば色々教えてくれる。
Powered by Bing

ただ問題を一般化して言語で表現することでこのように計算根拠まで確認することができるのでより的確な語彙を選択できる方が有利だとは思う。

Bingが出した式をPythonで計算してみるとBingが出した答えとちょっと違うのでそこらへんは鵜呑みには出来なさそうだけど。

>>> 1 - (86/87)**3
0.03408792366929225

てことで数学・ブログラミングが苦手なら国語力を鍛えるのがおススメ。

全部苦手って方は。。
うん、大丈夫。デキる友達に飯をごちそうすれば万事解決だ。

以上

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。