救済タイマー付きガチャ（e.g. アークナイツ）における★6期待値とピックアップ的中確率

# 救済タイマー付きガチャとは
救済タイマーという言葉は、<a href="https://allabout.co.jp/gm/gc/463172/2/">この記事</a>から引っ張ってきました。いわゆる、<b>「徐々に最高レアリティが出る確率が上昇し、最終的には確定になる」</b>という方式ですね。最近のソーシャルゲームでこのガチャ方式を採用している中で一番有名なのはアークナイツだと思います。（他にもあるとは思いますが...)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112872/95739156-31df-3f51-8d15-d6cd9ede5018.png)

このようなガチャは、独立事象ではなく従属事象になるため、期待値の計算などが難しくなります。特に、徐々に最高レアリティが上昇していくところが厄介です。正直計算式立てて解くのが面倒なので、シミュレータを作ってモンテカルロシミュレーションをします。

# モンテカルロシミュレーションとは
https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%AB%E3%83%AB%E3%83%AD%E6%B3%95

詳細な説明はWikipediaにあります。簡単に言うと、<b>乱数を使ってたくさんシミュレーションをすれば求めたいものがわかる</b>って感じです。わかりやすい例ではWikipediaにも紹介されてますが、円周率の計算とかですかね。

自分が以前携わっていたお仕事では、半導体の歩留まりの見積もりとかで使われてました。専用のシミュレーションツールがあるぐらいにはメジャーな手法です。

# 最高レアリティの期待値の計算
アークナイツのガチャでは、最高レアリティである★6の基本排出率は2%です。しかし前述の画像の通り、常に2％ではありません。連続して50回出ないと排出率は上昇していき、★6を引いたら2％に戻るという仕様です。これをモンテカルロシミュレーションで求めてみます。

```matlab:ark_nigths_gacha_expect.m
% N
n = 100000000;
% ★6排出枚数
s6_cnt = 0;


% ★6がN連続出現していない回数
local_cnt = 0;    

% Monte-Carlo Sim.
for i = 1:n
    local_cnt = local_cnt + 1;
    
    % 現在の local_cnt に応じた★6排出率
    if local_cnt > 50
        s6_rate = 0.02 + (local_cnt-50)*0.02;
    else
        s6_rate = 0.02;
    end
    
    % ★6排出判定
    if rand < s6_rate
        s6_cnt = s6_cnt + 1;
        local_cnt = 0;
    end
end

disp(['Expected Value:', num2str(s6_cnt/n)])
```

```matlab
>> ark_nigths_gacha_expect
Expected Value:0.028916
```

試行回数Nを1億回に設定してシミュレーションした結果、2.89% となりました。3%よりは低いので、ソーシャルゲームの中では低めなほうだとは思います。

# 累積分布関数の計算
次に調べるのは、<b>どれだけ準備しておけばどれぐらいの確率でピックアップを引くことができるか</b>という確率です。つまり、出るまで回した場合に何回目のガチャで引けるか？というもの。累積分布関数（cumulative distribution function, CDF）でプロットします。

## 一般的なガチャ
まずは、ピックアップ確率0.7% の一般的なガチャで計算してみます。

```matlab
plot(geocdf([0:300], 0.007))
grid on
xlabel('試行回数 N')
ylabel('確率')
title('一般的なガチャ ピックアップ0.7%')
xlim([0 300])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112872/5bd95eb5-9b33-4929-849b-cef0d5b0f46f.png)

200連で約75%ですね。

## アークナイツのガチャ
新規キャラ追加時のスタンダードガチャを想定し、ベース★6排出率が2%、ピックアップ抽選率を50%に設定します。試行回数100万回で同様に累積分布関数をプロットします。

```matlab:ark_nigths_gacha_std.m
% N
n = 1000000;
% 結果格納用配列
res = zeros(1, n);
% ピックアップ抽選率
pick_rate = 0.5;

% Monte-Carlo Sim.
for i = 1:n
    pick_flg = false; % ピックアップが出たフラグ
    total_cnt = 0;    % 合計で回した回数
    local_cnt = 0;    % ★6がN連続出現していない回数
    
    % ピックアップが出るまで回す
    while ~pick_flg
        total_cnt = total_cnt + 1;
        local_cnt = local_cnt + 1;
        
        % 現在の local_cnt に応じた★6排出率
        if local_cnt > 50
            ssr_rate = 0.02 + (local_cnt-50)*0.02;
        else
            ssr_rate = 0.02;
        end
        
        % ★6排出判定
        if rand < ssr_rate
            % ピックアップが出たかどうか判定
            if rand < pick_rate
                pick_flg = true;
            end
            local_cnt = 0;
        end

    end
    
    % 結果配列へ格納
    res(i) = total_cnt;
end

% 累積分布関数のプロット
cdfplot(res);
xlabel('試行回数 N')
ylabel('確率')
title('アークナイツガチャ ベース2% / ピックアップ抽選率50%')
xlim([0 300])
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112872/90a5b3b9-d464-6fae-2733-e78f421aeaa4.png)

なかなか歪なグラフとなってて面白いですね。SSR排出率の上昇が始まる50連を過ぎた付近で確率が一気に上がってるのがわかります。救済タイマーの力ですね。92連で約75%、140連で約90%となります。

## 通常ガチャとアークナイツガチャを比較
さて、通常ガチャとアークナイツガチャを比較してみましょう。条件をある程度合わせるために、アークナイツのほうはリミテッドガチャを想定しピックアップ抽選率を35%に設定します。一般的なガチャの比較条件には、よくあるピックアップ確率の0.7%と、アークナイツガチャの★6期待値にピックアップ抽選率の35%を乗算した 1.04% を設定してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112872/bcc9de54-12ca-1a31-90eb-492fcd8aef84.png)

アークナイツガチャは、Nが小さいときはピックアップ確率0.7%と同じですが、ガチャ回数が多くなるにつれてピックアップ率1.04%に漸近していきます。なかなか面白いですね。120～130ぐらいまで回さないと、ピックアップ1.04%には漸近しないためそこらへんまでは貯蓄しておくのがよさそうです。


# まとめ
アークナイツのガチャはよくできています。最高レアリティの期待値は3%に満たないため排出率が高いわけではないのですが、60~70連ぐらいまで回せばほぼ確定で1枚でるという安心感があるので、そこまでは回してもいいかなと思える設計になってます。またピックアップ抽選率は★6排出率に比例して上昇するため、数字以上に高いです。最高レアリティのピックアップ排出率が1%超えているゲームって探すのが割と難しいと思います。

あと、MATLABの関数が便利すぎますね。cdfplotとかめちゃくちゃ便利でした。（Statistics and Machine Learning Toolboxが必要なんですけどね）

# 参考
https://qiita.com/massoumen/items/e84ded24a4f00860e215