続・玩式草子 ―戯れせんとや生まれけん―

第27回 ガチャと確率とPython[その1]

この記事を読むのに必要な時間:およそ 3.5 分

新年早々,新型コロナウィルスの緊急事態宣言が11都府県に再発令されるなど,2021年も前途多難な年になりそうです。

そういうご時世にもかかわらず(だからこそ⁠⁠,この連載では今年もソフトウェアもてあそぶ⁠⁠,浮世離れした話題をまったりと綴っていくつもりなので,興味ある人はお付き合いをよろしくお願いします。

さて今回は,昨今しばしば問題となる,ソシャゲのガチャの確率をソフトウェア的に考えてみました。

ガチャと提供確率

ソシャゲのガチャに大金を投じてしまう「廃課金」者の存在は,しばらく前から社会問題化しています。その結果,ガチャの際にはキャラの提供確率を表示することが義務化され,最近のガチャ画面には「★5キャラの提供割合は○○%」などと明示されるようになりました。

さて,それでは,提供割合が「1%」の場合,何回くらいガチャを回せば目的のキャラが手に入るのでしょうか?

カプセルトイを排出する物理的な「ガチャガチャ」のように,100のクジの中に1つだけ「当たり」があって,⁠外れ」クジは引くごとに除外されていくのであれば,1回目に当たる確率は1/100だけど2回目だと1/993回目だと1/98…… となって,最悪でも100回引けば当たりは得られるはずです。

それに対し,ソシャゲのガチャのように,何回引いても各回の当選確率が1/100の場合,必ずしも100回引けば当たりが得られるわけではありません。

もっとも,物理的な「ガチャガチャ」の場合,景品自体は見えないので,そもそも狙っている景品が筐体の中に入っているのか,という問題もありそうですが。(笑

高校数学の「確率」で取り上げるように,この手の問題は「外れ」の側から攻めると簡単です。すなわち,当選確率1%のガチャを引く場合,1回目が外れる確率は99/100,2回目に外れる確率も99/100,3回目に外れる確率も99/100……なので,このガチャを100回引いて全て外れる確率は (99/100)^100 = 0.99^100 = 0.366 となり,この値を1から引いた0.634が,このガチャを100回引いた際に少なくとも1回は当たる確率となります。逆に言うと,当選確率1%のガチャでは4割弱(36.6%)の人は100回引いても当たらないということです。

一方,期待値的に見ると「1%の当選確率」100人引けば1人は当たることを意味します。多少バラつきがあるので100人では当選者が出なくても,1000人引けば10人前後,10000人引けば100人前後の人は初回で当たりを得られるはずです。

このあたり,確率と期待値的にはそうなると頭では分かっているものの,⁠楽に当たる人がいる一方,なぜ自分は当たらないのか」を感覚的に理解するのはなかなか難しいので,だいたい何回くらい引けば当たりうるのかを考えてみたくなりました。こういう際にはコンピュータを使った「シミュレーション」が便利です。

この手の試行錯誤的な作業は,対話的に処理を進められるPythonが得意です。まずは当選確率をrate参加者数をplayer当たるまで何回かかったかを記録するリストをcounter[]として,当選確率1%のガチャに1000人が挑戦し,当たりを得るまで各自が何回くらい引かないといけないかを計算してみました。

$ python
Python 3.7.7 (default, Nov 20 2020, 21:28:25) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> rate = 0.01
>>> player = 1000
>>> counter = []
>>> for i in range(player) :
...     c = 1
...     while random.random() > rate :
...         c += 1
...     counter.append(c)
... 
>>>

random.random() は0から1の間の一様乱数を返す関数で,この結果がrate(=0.01)を下回った場合が「当たり」となります。counter[]には当たりを引くまでにかかった回数が記録されます。まずはcounter[]の中身を見てみましょう。

>>> print(counter)
[1, 27, 202, 64, 160, 327, 7, 17, 38, 2, 33, 7, 135, 327,
19, 18, 39, 80, 1, 36, 37, 138, 83, 20, 106, 196, 22, 5,
....
245, 7, 50, 169, 24, 81, 69, 41, 18, 21, 138, 167]

ざっと見,初回で当たりを引けた幸運な人もいるものの,200回,300回かかった人も散見されます。何人くらいが初回で当たりを引けたかを確認するために,counter[]をソートしてみます。

>>> print(sorted(counter))
[1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
...
442, 445, 451, 451, 458, 466, 498, 532, 581, 595, 650, 671, 785]

今回の例では,1000人のうち1度目に引けた幸運な人は4人で,2度目に引けたのは8人,3度目も8人,4度目は9人,という結果になりました。一方,引くまでに100回以上かかった人も362人ほどいました。

>>> [x for x in counter if x > 100 ]
[532, 198, 170, 157, 198, 118, 151, 581, 357, 426, 164, 129,
 231, 327, 203, 207, 151, 205, 220, 111, 297, 107, 118, 263,
 ...
 113, 595, 187, 203, 187, 333, 177, 167, 116, 140]
>>> len([x for x in counter if x > 100 ])
362

先に「当選確率1%のガチャでは,4割弱(36.6%)の人は100回引いても当たらない」と述べました。その結論はシミュレーション結果からも裏付けられるようです。

著者プロフィール

こじまみつひろ

Plamo Linuxとりまとめ役。もともとは人類学的にハッカー文化を研究しようとしていたものの,いつの間にかミイラ取りがミイラになってOSSの世界にどっぷりと漬かってしまいました。最近は田舎に隠棲して半農半自営な生活をしながらソフトウェアと戯れています。

URLhttp://www.linet.gr.jp/~kojima/Plamo/index.html