【ルーレットの還元率】理論値通りになるかPythonで百万回シミュレーションしてみた

Photo by Nejc Soklič on Unsplash

前回の記事フレンチルーレットのアンプリゾン方式をPythonでシミュレーションしてみたで書いたように、ルーレットにはアメリカンルーレットヨーロピアンルーレットフレンチルーレット3種類があります。

更に赤・黒ベットや偶数・奇数ベットなどのイーブンベットの場合、フレンチルーレットにはアンプリゾン方式ラパルタージュ方式2種類の特殊ルールがあります。

前回の記事では、それぞれの還元率の理論値を計算しました。

今回はその理論値が正しいかどうかを、1,000,000回シミュレーションして確かめてみました。

 

◆仕事や勉強の息抜きに。。。

還元率とは?

まずは還元率の定義を確認しておきましょう。

還元率とはプレイヤーの賭金に対して、獲得する可能性がある金額の割合を表した値です。

例えば還元率が90%ということは、100ドルを賭けたとすると90ドルを獲得できる可能性があるということです。

 

なんだ、100ドル賭けて90ドルしか戻ってくる可能性がないのなら、そんな賭け誰もやらないよ

 

と思うかもしれませんが、これは平均の話しであって、200ドル戻ってくることもあれば全然戻ってこないこともあります。

平均で90ドル戻ってくる可能性があるということです。

 

今回はシミュレーションにより1,000,000回の賭けを行って、戻ってくるお金の平均が還元率の理論値通りになるかどうかを確かめましょうというわけです。

 

理論値の計算方法

前回の記事で還元率の計算式を示しましたが、なぜそのように求められるかを解説します。

 

アメリカンルーレットの還元率

アメリカンルーレットには1から36までの数字の他に000があります。

合計で38の数字があります。

赤・黒ベットでは、1から36までの36個の数字の内訳は赤が18、黒も18です。

従ってプレーヤーが赤に賭けて当たる確率は

18÷3847.4%

です。

当たると賭金の2がご褒美としてもらえます。

外れると賭金が没収されます。

 

同様に黒に賭けて当たる確率も47.4%で、当たれば賭金の2倍がもらえ、外れると賭金は没収です。

 

従ってプレーヤーが赤に100ドルを賭けた場合には、次の金額が戻ってくることが期待できます。

20047.4%047.4%94.7

これは黒に賭けた場合でも同じ金額です。

 

このように赤・黒どちらに賭けても100ドル賭けたら94.7ドル戻ってくることが期待できるので、還元率は94.7%です。

 

以上の求め方は期待値を計算していますが、もっと簡単に求めることもできます。

還元率は控除率の裏返しです。

控除率とは賭け事において、賭けを主催する胴元の懐に入る割合のことです。

カジノでいうと、賭金のうちカジノが運営費として徴収する分のことです。

 

還元率とは控除率の裏返しで、賭金のうちプレーヤーが受け取れる分のことです。

玉が000に入るとプレーヤーはどうやったって勝てないので、プレーヤーが勝てる確率は

36÷3894.7

になり、これが還元率ということもできます。

 

ヨーロピアンルーレットの還元率

ヨーロピアンルーレットには00はなく全部で37個の数字しかないため、還元率は

36÷3797.3

で計算できます。

 

フレンチルーレット(アンプリゾン方式)の還元率

フレンチルーレットでもヨーロピアンルーレットと同様に01つしかなく合計で37個の数字しかありませんが、アンプリゾン方式が適用される場合は、0に玉が入ったら一旦賭金は同じ色に保留されます。

そして、次の玉が同じ色に入ったら、賭金は戻ってきます。(違う色、もしくは0に入ったら、賭金は没収です)

玉が0に入る確率は1÷37で、次に同じ色に入る確率は18÷37なので、これらが続けて起きる確率はこれらの積となり1÷37(18÷37)です。(同時確率という)

 

従って還元率は

36÷371÷37(18÷37)98.61

で計算できます。

 

フレンチルーレット(ラパルタージュ方式)の還元率

ラパルタージュ方式では玉が0に入ったら、賭金の半分が戻ってきます。

従って玉がゼロに入る確率1÷37に、戻される金額の半分を掛けた値が0に入った場合の期待値になるため、還元率は

36÷371÷37÷298.65

で計算できます。

 

アンプリゾン方式では保留された賭金が戻ってくる確率が50%よりも少し低いため、確率が50%であるラパルタージュ方式の方が還元率が僅かに高くなります。

 

Pythonでコーディング

どの方式で遊ぶかかを最初に入力した上で、100ドルを賭けて戻ってくるお金を記録することを1,000,000回行って平均を求めます。

import random

# ルーレット種類の入力
def kind_of_roulette():
    global kind, weight, rule
    print('ルーレットの種類を入力して下さい(A:アメリカン, E:ヨーロピアン, F:フレンチ) :')
    kind = input('>')
    if kind == 'A':
        print('アメリカンルーレットが選択されました')
        weight = [18, 18, 2] #確率ウェイト(赤:18箇所、黒:18箇所、ゼロ:2箇所)
    elif kind == 'E':
        print('ヨーロピアンルーレットが選択されました')
        weight = [18, 18, 1] #確率ウェイト(赤:18箇所、黒:18箇所、ゼロ:1箇所)
    else:
        print('フレンチルーレットが選択されました')
        weight = [18, 18, 1] #確率ウェイト(赤:18箇所、黒:18箇所、ゼロ:1箇所)
        print('アンプリゾン方式(E) or ラパルタージュ方式(L) ?:')
        rule = input('>')

# 投入資金額の設定
def fund():
    global onhand
    onhand = 100 #投入資金
    place()

# 賭金の設定
def place():
    global placement
    placement = 100 #賭金
    choice()

# ランダムに色を選択
def choice():
    global answer, placement, hold
    p_color = ['R', 'B'] #赤、黒
    p_weight = [1, 1] #確率ウェイト(赤:1、黒:1)
    answer = random.choices(p_color, k = 1, weights = p_weight) #確率ウェイトに基づき赤、黒を生成
    hold = 0 #保留で1を立てるようにフラグを用意
    settlement(placement)

# 精算
def settlement(money):
    global result, weight, onhand, hold, rule, answer
    color = ['R', 'B', 'G'] #赤、黒、ゼロ
    result = random.choices(color, k = 1, weights = weight) #確率ウェイトに基づき赤、黒、ゼロを生成
    if result[0] == 'R' and answer[0] == 'R': #赤で当たりの場合
        onhand += money
        return onhand
    elif result[0] == 'B' and answer[0] == 'B': #黒で当たりの場合
        onhand += money
        return onhand
    elif result[0] == 'G' and kind == 'F': #フレンチでゼロが出た場合
        if hold == 1: #保留中にゼロが出た場合
            return onhand
        else: #最初にゼロが出た場合
            if rule == 'E': #アンプリゾン方式の場合
                onhand = onhand - money #賭金を拘留
                hold = 1
                settlement(money) #保留金額で再チャレンジ
            else: #ラパルタージュ方式の場合
                onhand = onhand - money + money/2 #半額戻し
                return onhand
    else: #違う色が出た場合
        if hold == 0: #保留中でなければ賭金を引く(保留中は引かない)
            onhand -= money
        return onhand

kind_of_roulette()
results = []
for i in range(1000000): # 1回の賭け後の手持ち金を1,000,000回計算
    fund()
    results.append(onhand)
sum(results)/(len(results)*100) # 1,000,000回の平均を計算

 

シミュレーション結果

下記のように、理論値とほぼ同じになりました。

 

アメリカンルーレット

ルーレットの種類を入力して下さい(A:アメリカン, E:ヨーロピアン, F:フレンチ) :
>A
アメリカンルーレットが選択されました
0.946682

 

ヨーロピアンルーレット

ルーレットの種類を入力して下さい(A:アメリカン, E:ヨーロピアン, F:フレンチ) :
>E
ヨーロピアンルーレットが選択されました
0.97342

 

フレンチルーレット(アンプリゾン方式)

ルーレットの種類を入力して下さい(A:アメリカン, E:ヨーロピアン, F:フレンチ) :
>F
フレンチルーレットが選択されました
アンプリゾン方式(E) or ラパルタージュ方式(L) ?:
>E
0.986082

 

フレンチルーレット(ラパルタージュ方式)

ルーレットの種類を入力して下さい(A:アメリカン, E:ヨーロピアン, F:フレンチ) :
>F
フレンチルーレットが選択されました
アンプリゾン方式(E) or ラパルタージュ方式(L) ?:
>L
0.986546