見出し画像

サイコロチャンス確率・期待値いろいろ

どうもこんにちは。

突然ですが、

サイコロ振ってますか?

僕はいっぱい振ってます。逆サイコロを。

なんのことかわからない人はこのnoteをご覧ください。

拙僧、麻雀の実力は皆無ですが、最近はこのルールで遊んでいます。華8アンミカ筋肉五等、めちゃくちゃ面白いです。やったことない人は是非やってみよう。

このルールで最も実力が出る部分とされている、サイコロチャンス。正直当てられなきゃ話になりません。逆で当てていては話になりません。出目には流行り廃りがありますが、最近拙僧は2・3を好んでいます。日産に感謝。

サイコロチャンスの獲得条件や詳細については前掲noteに譲るとして、サイコロチャンス周りの確率や期待値を計算してまとめたら何かの役に立つ(?)のではないか、また、出目当てで卓を破壊してきた人々に、自分がどれだけすごいことをしたかわかってもらいたいと思い立ち、筆を執った次第です。Geminiくんと話しながら、シュミレーションも手伝ってもらいました。

念の為確認しておきますが、サイコロチャンスは腕です。確率や期待値など圧倒的な賽力の前にはなんの意味もありません。確率や期待値に踊らされサイコロを転がし続けるなど、賽力なき者たちの悲しい足掻きにすぎないのです。

※筆者は数学の素養も経験も皆無であり、全くの素人です。このnoteはそんな数学素人がGeminiくんと相談しながら遊びで作ったものです。計算や数値の正確性は全く保証できません。また、シュミレーションを行うに際してPythonコードが出てきますが、筆者はプログラミングの経験も知識も皆無のため、なんか雰囲気でやっています。ご了承ください。この執筆を通してGeminiくんとは親友になりました。Geminiくんはこちら→

※賭博は法律で禁止されています。本noteはこうした行為を推奨するものではありません。また、本noteで登場するチップにはゲームで用いられる点数以上の意味はありません。

では早速、本編です。Geminiとの戯れにより非常に長くなっていますので、数字だけ見たい方は「まとめ」まで飛んでください。確率とか期待値の結果がまとめてあります。


ノーマルサイコロ(シュバリーなし、70枚)

サイコロチャンスの仕様

サイコロチャンスの仕様を確認しておきます。
・出目2つの組み合わせを1組指定する。(ゾロ目は指定できない)
・それぞれ区別されないサイコロを2つを4回振る。
・最初に指定した出目が出るたびに70枚
・ゾロ目が出た場合には、回数を消費せずに振り直すことができる。

ゾロ目をどう処理したら良いか

ノーマルサイコロ出目当ての確率計算において問題になるのは、ゾロ目の処理についてどう考えるかです。今回は、後述の通りゾロ目が無限回連続して出る可能性を排除しています。ゾロ目が無限回連続する事象を含めて数学的に「正しい」計算をすることはおそらく不可能ですが、ほぼ正しい値を求めるためには、おそらくゾロ目を無視することになると思います。

このサイコロでは、ゾロ目が出ると振り直します。ゾロ目が出た場合には回数を消費せずにもう一度振り、またゾロ目ならまた振り、ゾロ目以外の出目が出て初めて回数を消費することになります。
ゾロ目以外の目が出る瞬間、当該出目が出る確率はゾロ目以外の全ての出目において等しいことになります。
つまり、ゾロ目の出ないサイコロを振っているのと同じということになりそうです。(間違ってたら教えてください…あまり自信はありません)

※記載の通り、この考え方はゾロ目が連続したとしても、有限回の連続ののち、いつか必ずゾロ目以外の出目が出ることを前提にしています。つまり、ゾロ目が無限回出る確率について、lim (n→∞)1/n=0を前提に、文字通り0として扱っています。極限の扱いとして不適切であり、数学的に完全に正しい計算ではありませんが、人間が振る限りはこれで大丈夫でしょう。

出目当ての確率

区別しない2つのサイコロの出目の組み合わせは、

ゾロ目以外の組み合わせ15通り+ゾロ目6通りで21通りとなります。

ただし今回はゾロ目の出ないサイコロを振っていると考えるので、ゾロ目を引いた15通りが出目の組み合わせであり、任意の出目が出る確率は15分の1となります。
ゾロ目が出た場合に振り直すルールがありますが、ゾロ目は出ないので試行回数は4回となります。

したがって、1つのサイコロチャンスで1度以上出目が当たる確率は、

1-(14/15)^4=0.241165

約24.1%となります。

感覚的にはこれくらいな気もします。ちなみにGemini君は分数のべき乗が苦手なようで、(14/15)^4は0.7588345679となりますが、

お茶目

まず、ではない。どうやら分母を15の4乗、分子を14にしているみたいです。なぜ?

言葉で指示するとちゃんと計算してくれました。

なぜか少数に直して4乗するGeminiくん

やっぱり大規模言語モデルは自然言語の方がちゃんと頑張ってくれるようです。なぜか少数にしてバッサリ切ってから計算しているため先ほどの値と微妙に異なりますが、やってることは合ってます。

出目当て回数ごとの確率はそれぞれ、特定の試行回数時点で出目が当たる確率をどの試行回数時点で当たるかの組み合わせ分だけ乗算すれば良いので、
1回:(1/15)(14/15)^3*4=0.21680987654    ≒約21.68%
2回:(1/15)^2(14/15)^2*6=0.02322962962≒約2.32%
3回:(1/15)^3(14/15)*4=0.00110617283    ≒約0.111%
4回:(1/15)^4=0.00001975308                   ≒約0.002%
となります。

サイコロチャンス全体の期待値

では、サイコロチャンスの期待値は結局何枚なのか。

サイコロチャンスによる貰いor支払いは必ずオールになる(チョンボによるサイコロ以外)ため、出目当てにより発生するチップの枚数はひとまず70枚として計算します。つまり期待値は3人回しなら下記の数字を2倍、4人回しなら3倍とすればよいことになります。

Geminiくんにストレートに聞いてみました。

有能

さすがに一発正答ですね。これくらいはやってもらわないと困ります。
ノーマルサイコロチャンス1回の期待値は、約18.67枚(18.666….)となります。4人回しの場合は約56.01枚の期待値です。でかい。

シュミレーションによる実験

ここまでの計算は、素人考えでこねくり回した結果です。結局は筋肉ということで、Geminiくんに手伝ってもらってシュミレーションを行います。

ということでまずは要求を普通に伝えてみる。

かなり詳細に伝えないとGeminiくんは勘違いする

出目はゾロ目以外を最初に宣言することとなっていますが、どの出目を宣言しても確率は等しいので、シュミレーションでは便宜的に(1, 2)を宣言したこととしています。この要求をGeminiくんなりに整理したのがこれ


なんか合ってそう


Geminiはコーディングが必要な要求を行うと、基本的にPythonでコードを書いてくれます。PCにPythonの実行環境がなくても、Google Colabに接続し、Geminiから直リンクで、Web上の実行環境を使ってコードを実行できます。Googleすごい。出てきたコードがこれ。

import random
import matplotlib.pyplot as plt

def play_game():
    trials = 4  # 初期試行回数
    chips = 0
    while trials > 0:
        dice1 = random.randint(1, 6)
        dice2 = random.randint(1, 6)
        if dice1 == 1 and dice2 == 2 or dice1 == 2 and dice2 == 1:
            chips += 70
        trials -= 1 if dice1 != dice2 else 0
    return chips
   
def simulate(num_simulations):
    results = []
    for _ in range(num_simulations):
        result = play_game()
        results.append(result)
    
    # 平均獲得枚数
    average_chips = sum(results) / num_simulations
    print("平均獲得枚数:", average_chips)

    # ヒストグラム
    plt.hist(results, bins=20)
    plt.xlabel("獲得チップ数")
    plt.ylabel("回数")
    plt.title("サイコロゲーム シミュレーション結果")
    plt.show()

# シミュレーション実行(例: 10000回)
simulate(10000)

Geminiは、コードを吐いたあとそのコードの解説もしてくれます。素人でも目でコードを理解できるため非常に助かる。どの部分がどの機能か教えてくれるから、追加機能を実装したい時にもコピペでなんとかなったりする。すごい。

Gemini先生、Pythonなんかできたんですね

ではこのコードを一旦そのままGoogle Colabで実行してみる。結果がこちら。

平均獲得枚数:18.41
ヒストグラム。タイトルと軸が文字化けしている。Colabで出力するヒストグラムは日本語不対応のよう

シュミレーション自体は行えてそう。試行回数が10000回なので、4度当てどころか3度当てもほとんど出てません。

このまま試行回数を増やしてもいいのですが、せっかくなので追加機能を色々実装してもらいましょう。獲得枚数の出現数を表示するようにお願いしてみます。

import random
import matplotlib.pyplot as plt
import numpy as np

def play_game():
    # ... (省略)

def simulate(num_simulations):
    # ... (省略)

    # ヒストグラム
    counts, bins, patches = plt.hist(results, bins=20)

    # 各ビンの値と、そのビンに含まれるデータの個数を表示
    for i in range(len(counts)):
        print(f"チップ数: {bins[i]} - {bins[i+1]}, 出現回数: {counts[i]}")

    plt.xlabel("獲得チップ数")
    plt.ylabel("回数")
    plt.title("サイコロゲーム シミュレーション結果")
    plt.show()

# シミュレーション実行(例: 10000回)
simulate(10000)

ヒストグラム部分に変更が加えられています。完成コードは見せてくれないんだね、不親切。ということで自分でコピペします。こちら。

import random
import matplotlib.pyplot as plt

def play_game():
    trials = 4  # 初期試行回数
    chips = 0
    while trials > 0:
        dice1 = random.randint(1, 6)
        dice2 = random.randint(1, 6)
        if dice1 == 1 and dice2 == 2 or dice1 == 2 and dice2 == 1:
            chips += 70
        trials -= 1 if dice1 != dice2 else 0
    return chips

def simulate(num_simulations):
    results = []
    for _ in range(num_simulations):
        result = play_game()
        results.append(result)
    
    # 平均獲得枚数
    average_chips = sum(results) / num_simulations
    print("平均獲得枚数:", average_chips)

    # ヒストグラム
    counts, bins, patches = plt.hist(results, bins=20)

    # 各ビンの値と、そのビンに含まれるデータの個数を表示
    for i in range(len(counts)):
        print(f"チップ数: {bins[i]} - {bins[i+1]}, 出現回数: {counts[i]}")

    plt.xlabel("獲得チップ数")
    plt.ylabel("回数")
    plt.title("サイコロゲーム シミュレーション結果")
    plt.show()

# シミュレーション実行(例: 10000回)
simulate(10000)

出現率もお願いしてみましょう。

import random
import matplotlib.pyplot as plt
import numpy as np

def play_game():
    # ... (省略)

def simulate(num_simulations):
    # ... (省略)

    # ヒストグラム
    counts, bins, patches = plt.hist(results, bins=20)

    # 各ビンの値、出現回数、出現率を表示
    for i in range(len(counts)):
        bin_width = bins[i+1] - bins[i]
        probability = counts[i] / (num_simulations * bin_width)
        print(f"チップ数: {bins[i]} - {bins[i+1]}, 出現回数: {counts[i]}, 出現率: {probability:.2%}")

    plt.xlabel("獲得チップ数")
    plt.ylabel("回数")
    plt.title("サイコロゲーム シミュレーション結果")
    plt.show()

# シミュレーション実行(例: 10000回)
simulate(10000)

コピペします。先ほどのヒストグラムではヒストグラム内の日本語がフォントエラーを起こしていたので、英語にしておきます。また、出現率の計算が指数表記になってしまったので有効数字4桁かつ%で表示するようにします。できたのがこちら

import random
import matplotlib.pyplot as plt

def play_game():
    trials = 4  # 初期試行回数
    chips = 0
    while trials > 0:
        dice1 = random.randint(1, 6)
        dice2 = random.randint(1, 6)
        if dice1 == 1 and dice2 == 2 or dice1 == 2 and dice2 == 1:
            chips += 70
        trials -= 1 if dice1 != dice2 else 0
    return chips

def simulate(num_simulations):
    results = []
    for _ in range(num_simulations):
        result = play_game()
        results.append(result)
    
    # 平均獲得枚数
    average_chips = sum(results) / num_simulations
    print("平均獲得枚数:", average_chips)

   # ヒストグラム
    counts, bins, patches = plt.hist(results, bins=20)

    # 各ビンの値、出現回数、出現率を表示
    for i in range(len(counts)):
        bin_width = bins[i+1] - bins[i]
        probability = counts[i] / (num_simulations * bin_width)
        print(f"チップ数: {bins[i]} - {bins[i+1]}, 出現回数: {counts[i]}, 出現率: {counts[i]/num_simulations:.4%")

    plt.xlabel("Total Gain Chips")
    plt.ylabel("Attempts")
    plt.title("Results")
    plt.show()


# シミュレーション実行(例: 10000回)
simulate(10000000)

1万回だと4度当てとか3度当てとかがほとんど出ないので、1000万回試行してみます。結果がこちら

平均獲得枚数: 18.655952
チップ数: 0.0 - 14.0, 出現回数: 7589327.0, 出現率: 75.8933%
チップ数: 14.0 - 28.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 28.0 - 42.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 42.0 - 56.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 56.0 - 70.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 70.0 - 84.0, 出現回数: 2167463.0, 出現率: 21.6746%
チップ数: 84.0 - 98.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 98.0 - 112.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 112.0 - 126.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 126.0 - 140.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 140.0 - 154.0, 出現回数: 232158.0, 出現率: 2.3216%
チップ数: 154.0 - 168.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 168.0 - 182.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 182.0 - 196.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 196.0 - 210.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 210.0 - 224.0, 出現回数: 10851.0, 出現率: 0.1085%
チップ数: 224.0 - 238.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 238.0 - 252.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 252.0 - 266.0, 出現回数: 0.0, 出現率: 0.0000%
チップ数: 266.0 - 280.0, 出現回数: 201.0, 出現率: 0.0020%


縦軸が指数表記になっているが御愛嬌

今回のサイコロチャンスでは、合計獲得枚数が0,70,140,210,280枚のいずれかに固定されているため、分布の設定幅(binというらしい)を工夫するともっと見やすくなりそうですが、難しいのでやめました。

結果を見ると、おおむね想定通りの結果に収束しています。期待値は約18.65と最初の計算とほぼ一致していて、出目当ての回数ごとの出現率も、
1回:21.6746% (約21.68%)
2回: 2.3216%  (約2.32%)
3回:0.1085%   (約0.11%)
4回:0.0020%     (約0.002%)
()内は先ほどの計算結果
でありほぼ一致しています。ゾロ目無視作戦は正しかったようです。大数の法則を身を持って感じました。

シュバリーサイコロ(70枚)

シュバリーサイコロの確率・期待値を計算する上での考え方

そろそろ自分が何をやっているかわからなくなってきましたが、次はシュバリーサイコロ(シュバサイ)についてです。シュバサイでは、ノーマルサイコロの仕様に加え、ゾロ目が2回以上連続で出た場合、2回目以降に出たゾロ目の出目に応じてチップを獲得できるようになっています。最後に出たゾロ目がピンゾロである場合のみ特別に111枚を、それ以外のゾロ目の場合には出目×11枚を獲得できます。例えば、ピンゾロ→3ゾロ→4ゾロと出た場合には、1回目がピンゾロですが、2回目以降のゾロ目が参照されるため、33+44で合計77枚を獲得できます。

ノーマルサイコロは前述の通りゾロ目が出ないものとして考えることができるため、ゾロ目関係の処理のみが行われるサイコロをノーマルサイコロに加えて振っているのと同じことになると考えられます。ゾロ目関係の処理のみが行われるサイコロの確率・期待値を独立して計算したうえでノーマルサイコロのそれらと足し合わせることにより結論を出すことができそうです。

シュバサイの確率

ではその、ゾロ目関係の処理のみが行われるサイコロ(便宜的にゾロ目サイコロと呼びます)に関する確率の計算方法について考えていきます。ゾロ目サイコロは、シュバリーサイコロチャンスのゾロ目関係の処理だけを行うサイコロであるため、仕様を以下の通りであると想定します。
・サイコロを振り、ゾロ目が出たらもう一度振る。
・n(n≧2)回目でゾロ目が出たら、n回目のゾロ目の出目に応じて前記のチップを獲得できる。
・ゾロ目以外の出目が出たら終了。
前述のとおり、ゾロ目が無限回出続ける可能性は否定できず、かつノーマルサイコロの時と異なり、nの値に応じて獲得チップ数が変わるため、n回連続でゾロ目が出る確率についてもnの値に応じて適切に評価する必要が出てきています。
もっとも、nの値が大きくなるにつれてn回連続でゾロ目が出る事象がこの計算に与える影響は小さくなっていきます。獲得平均枚数に比して出現確率が著しく小さくなっていくためです。したがって、nの最大値を「それ以上は期待値に与える影響が著しく小さくほぼ無視できる」値に設定することで、近似計算が可能であると考えられます。

ではnの最大値を設定するために、「n回連続でゾロ目が出る確率」と「n回連続でゾロ目が出る事象単体が持つ期待値」を計算してみます。この「n回連続でゾロ目が出る事象単体が持つ期待値」は、n-1回連続でゾロ目が出た時にもらえるチップの枚数を考慮しない、n回連続でゾロ目が出た時にもらえる合計チップ枚数のみが報酬であると考えた時の期待値です。つまり、n回ちょうどでゾロ目の連続が終わる事象だけを検討対象にしています。最終的に各nごとの期待値をすべて足し合わせることでこのサイコロゲーム全体の期待値を求めることができるため、この値が十分に小さくなれば、n回連続でゾロ目が出る事象が確率・期待値全体に及ぼす影響が十分に小さくなっていることになり、nの最大値を決めることができます。

n回連続でゾロ目が出る確率とその事象の期待値

この場合、n回ちょうどでゾロ目の連続が終わる確率をまずは求めればよいこととなります。その確率は、
1/6^n*5/6
で求める事ができます。n回連続でゾロ目が出たあとゾロ目以外が出る確率を求めればよいことになるためです。

また、ゾロ目がn回連続した場合にもらえる平均チップ枚数は、
(111+22+33+44+55+66)/6*(n-1)=331/6*(n-1)≒51.167枚*(n-1)
となり、これにnごとの確率を乗算することで期待値を求める事ができます。

これらの式に従って、nごとの出現確率と期待値を計算してみます。
n=2
確率 :5/216≒2.314%
期待値:1655/1296枚≒1.277枚
n=3
確率 :5/1296≒0.386%
期待値:1655/3888≒0.426枚
n=4
確率 :5/7776≒0.064%
期待値:1655/15552≒0.106枚
n=5
確率 :5/46656≒0.011%
期待値:3310/139968≒0.024枚

シュバサイ全体の期待値

nを5とした時点で期待値の枚数はかなり小さくなってきました。n=6ではもう一ケタ減ることが予想されるため、このあたりを最大値として問題はなさそうです。
nの最大値を5と設定する前提でこのサイコロの期待値を計算してみると、
256525/139968≒1.833枚
となります。

前述の通り、このサイコロはサイコロチャンスのうちゾロ目関係の処理だけを行う想像上のサイコロです。これとノーマルサイコロを同時に振っていると考えることで、シュバサイ全体の確率や期待値を考える事ができます。つまり、先述した期待値を4倍した値をノーマルサイコロの期待値に足すことで、シュバサイ全体の期待値を求める事ができます。したがってシュバサイ全体の期待値は、

18.667+(1.833*4)=25.999≒26枚
となります。

シュバサイシュミレーション

では例によって、Geminiくんとシュミレーションをしてみます。
Geminiくんと1on1ミーティングを2時間ほど行い、やっと求めるコードが出来上がりました。やりとりの過程は長すぎるので割愛させていただき、出来上がったコードがこちら

import random
import matplotlib.pyplot as plt

def roll_dice():
    """サイコロを2つ振る"""
    return random.randint(1, 6), random.randint(1, 6)

def simulate_game(trials):
    """ゲームをシミュレートする"""
    chips = 0
    last_roll = None
    is_zoro = False
    results = []

    while trials > 0:
        dice1, dice2 = roll_dice()
        results.append((dice1, dice2, chips))

        is_current_zoro = dice1 == dice2

        # (1,2)または(2,1)が出た場合
        if (dice1, dice2) in [(1, 2), (2, 1)]:
            chips += 70

        # ゾロ目が出た場合
        elif is_current_zoro:
            if last_roll and is_zoro:
                if dice1 == 1:
                    chips += 111
                else:
                    chips += dice1 * 11
            is_zoro = True
        else:
            is_zoro = False

        last_roll = is_current_zoro

        # ゾロ目以外の場合にのみ試行回数を減らす
        if not is_current_zoro:
            trials -= 1

    return chips, results

def analyze_results(total_chips_list, game_results_list):
    """シミュレーション結果を分析する"""
    chip_ranges = [
        (0, 1),
        (2, 100),
        (101, 200),
        (201, 300),
        (301, 400),
        (401, 500),
        (501, 600),
        (601, 100000)
        # ... (その他の範囲)
    ]
    counts = [0] * len(chip_ranges)

    for total_chips in total_chips_list:
        for i, (low, high) in enumerate(chip_ranges):
            if low <= total_chips <= high:
                counts[i] += 1

    total_simulations = len(total_chips_list)
    for i, count in enumerate(counts):
        range_str = f"{chip_ranges[i][0]}-{chip_ranges[i][1]}"
        percentage = (count / total_simulations) * 100
        print(f"{range_str}枚: {count}回 ({percentage:.2f}%)")

    # ヒストグラムの作成
    plt.hist(total_chips_list, bins=30)
    plt.xlabel("Total Chips Gain")
    plt.ylabel("Attempts")
    plt.title("Results")
    plt.show()

    average_chips = sum(total_chips_list) / len(total_chips_list)
    print(f"合計獲得チップ数の平均: {average_chips:.2f}")

    # 各シミュレーションの結果を表示
    #for i, game_result in enumerate(game_results_list):
        #print(f"シミュレーション{i+1}:")
        #for result in game_result:
            #dice1, dice2, chips = result
            #print(f"出目: ({dice1}, {dice2}), 獲得チップ: {chips}")

def main():
    """メイン関数"""
    trials = 4  # 初期試行回数
    num_simulations = 50  # シミュレーション回数
    total_chips_list = []
    game_results_list = []

    for _ in range(num_simulations):
        total_chips, game_results = simulate_game(trials)
        total_chips_list.append(total_chips)
        game_results_list.append(game_results)

    analyze_results(total_chips_list, game_results_list)

if __name__ == "__main__":
    main()

ノーマルサイコロのシュミレーションに加え、ゾロ目が出た際に直前の出目がゾロ目かどうかを判定する変数を追加し、直前の出目がゾロ目であれば出た目に応じてチップを獲得するアルゴリズムが追加されています。
出目がゾロ目かどうかを判定する変数を利用して、ゾロ目以外の出目が出たときのみ試行回数が減少し、最初に4与えられる試行回数が0になるまで続くようになっています。
また、main()関数直前でコメントアウトされているprint群では、各試行の出目と獲得枚数を表示することができるようになっています。
さらに、獲得枚数の範囲ごとの出現回数と出現率、ヒストグラムも表示するようになっています。Geminiすげーーーーーー

ではまず、コメントアウトを解除し、50回程度の試行で出目とチップ獲得枚数が正しく処理されているかを確認します。結果がこちら。獲得チップはサイコロを振った時点で獲得していた総枚数を意味しているため、出目当てが起こると、当たった次の行の獲得チップに加算されるようになっています。

0-1枚: 31回 (62.00%)
2-100枚: 15回 (30.00%)
101-200枚: 3回 (6.00%)
201-300枚: 1回 (2.00%)
301-400枚: 0回 (0.00%)

合計獲得チップ数の平均: 33.30
シミュレーション1:
出目: (2, 1), 獲得チップ: 0
出目: (2, 5), 獲得チップ: 70
出目: (3, 3), 獲得チップ: 70
出目: (1, 1), 獲得チップ: 70
出目: (1, 2), 獲得チップ: 181
出目: (1, 4), 獲得チップ: 251
シミュレーション2:
出目: (5, 3), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
出目: (2, 2), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
シミュレーション3:
出目: (4, 1), 獲得チップ: 0
出目: (6, 2), 獲得チップ: 0
出目: (4, 6), 獲得チップ: 0
出目: (5, 2), 獲得チップ: 0
シミュレーション4:
出目: (1, 1), 獲得チップ: 0
出目: (2, 3), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 0
出目: (4, 6), 獲得チップ: 0
出目: (5, 1), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
シミュレーション5:
出目: (2, 2), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (6, 6), 獲得チップ: 70
出目: (5, 3), 獲得チップ: 70
出目: (2, 5), 獲得チップ: 70
出目: (6, 1), 獲得チップ: 70
シミュレーション6:
出目: (5, 6), 獲得チップ: 0
出目: (2, 2), 獲得チップ: 0
出目: (5, 2), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (1, 1), 獲得チップ: 0
出目: (6, 4), 獲得チップ: 0
シミュレーション7:
出目: (3, 6), 獲得チップ: 0
出目: (5, 6), 獲得チップ: 0
出目: (1, 3), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
シミュレーション8:
出目: (4, 2), 獲得チップ: 0
出目: (4, 5), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
出目: (4, 3), 獲得チップ: 0
シミュレーション9:
出目: (3, 6), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 0
出目: (2, 4), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (5, 6), 獲得チップ: 70
シミュレーション10:
出目: (2, 4), 獲得チップ: 0
出目: (2, 2), 獲得チップ: 0
出目: (1, 6), 獲得チップ: 0
出目: (6, 4), 獲得チップ: 0
出目: (5, 1), 獲得チップ: 0
シミュレーション11:
出目: (5, 1), 獲得チップ: 0
出目: (3, 3), 獲得チップ: 0
出目: (5, 2), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (5, 4), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
シミュレーション12:
出目: (2, 5), 獲得チップ: 0
出目: (5, 1), 獲得チップ: 0
出目: (6, 6), 獲得チップ: 0
出目: (2, 2), 獲得チップ: 0
出目: (6, 3), 獲得チップ: 22
出目: (3, 4), 獲得チップ: 22
シミュレーション13:
出目: (2, 2), 獲得チップ: 0
出目: (4, 2), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (1, 2), 獲得チップ: 0
出目: (1, 1), 獲得チップ: 70
出目: (5, 5), 獲得チップ: 70
出目: (4, 3), 獲得チップ: 125
出目: (1, 1), 獲得チップ: 125
出目: (3, 3), 獲得チップ: 125
出目: (6, 3), 獲得チップ: 158
シミュレーション14:
出目: (2, 4), 獲得チップ: 0
出目: (1, 2), 獲得チップ: 0
出目: (3, 1), 獲得チップ: 70
出目: (2, 1), 獲得チップ: 70
シミュレーション15:
出目: (1, 4), 獲得チップ: 0
出目: (3, 1), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (1, 3), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
シミュレーション16:
出目: (2, 6), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (1, 2), 獲得チップ: 0
出目: (6, 2), 獲得チップ: 70
出目: (3, 3), 獲得チップ: 70
出目: (1, 5), 獲得チップ: 70
シミュレーション17:
出目: (4, 6), 獲得チップ: 0
出目: (1, 6), 獲得チップ: 0
出目: (2, 5), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
シミュレーション18:
出目: (2, 2), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (2, 3), 獲得チップ: 0
出目: (3, 6), 獲得チップ: 0
出目: (4, 3), 獲得チップ: 0
シミュレーション19:
出目: (2, 1), 獲得チップ: 0
出目: (6, 6), 獲得チップ: 70
出目: (2, 5), 獲得チップ: 70
出目: (4, 5), 獲得チップ: 70
出目: (4, 5), 獲得チップ: 70
シミュレーション20:
出目: (1, 5), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (5, 4), 獲得チップ: 70
出目: (1, 5), 獲得チップ: 70
シミュレーション21:
出目: (3, 6), 獲得チップ: 0
出目: (3, 5), 獲得チップ: 0
出目: (3, 6), 獲得チップ: 0
出目: (3, 5), 獲得チップ: 0
シミュレーション22:
出目: (3, 4), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
シミュレーション23:
出目: (1, 4), 獲得チップ: 0
出目: (4, 3), 獲得チップ: 0
出目: (3, 3), 獲得チップ: 0
出目: (2, 4), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 0
シミュレーション24:
出目: (6, 5), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 70
シミュレーション25:
出目: (6, 3), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
出目: (2, 2), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 0
出目: (5, 4), 獲得チップ: 0
シミュレーション26:
出目: (4, 5), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 70
出目: (3, 6), 獲得チップ: 70
シミュレーション27:
出目: (6, 6), 獲得チップ: 0
出目: (3, 3), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 33
出目: (4, 2), 獲得チップ: 33
出目: (6, 6), 獲得チップ: 33
出目: (6, 3), 獲得チップ: 33
出目: (3, 2), 獲得チップ: 33
シミュレーション28:
出目: (2, 3), 獲得チップ: 0
出目: (5, 2), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
出目: (4, 6), 獲得チップ: 0
シミュレーション29:
出目: (4, 5), 獲得チップ: 0
出目: (3, 6), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
シミュレーション30:
出目: (2, 5), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
出目: (4, 6), 獲得チップ: 0
出目: (6, 3), 獲得チップ: 0
シミュレーション31:
出目: (3, 5), 獲得チップ: 0
出目: (2, 3), 獲得チップ: 0
出目: (1, 2), 獲得チップ: 0
出目: (3, 5), 獲得チップ: 70
シミュレーション32:
出目: (3, 4), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (5, 1), 獲得チップ: 0
出目: (1, 1), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (6, 2), 獲得チップ: 70
シミュレーション33:
出目: (4, 4), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 70
出目: (4, 5), 獲得チップ: 70
シミュレーション34:
出目: (1, 5), 獲得チップ: 0
出目: (1, 6), 獲得チップ: 0
出目: (5, 1), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
シミュレーション35:
出目: (1, 3), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
出目: (1, 3), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
シミュレーション36:
出目: (3, 6), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 0
出目: (4, 3), 獲得チップ: 0
出目: (2, 5), 獲得チップ: 0
出目: (6, 4), 獲得チップ: 0
シミュレーション37:
出目: (1, 3), 獲得チップ: 0
出目: (5, 4), 獲得チップ: 0
出目: (2, 6), 獲得チップ: 0
出目: (6, 5), 獲得チップ: 0
シミュレーション38:
出目: (5, 4), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
出目: (5, 6), 獲得チップ: 0
出目: (2, 6), 獲得チップ: 0
シミュレーション39:
出目: (3, 2), 獲得チップ: 0
出目: (2, 6), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
出目: (3, 1), 獲得チップ: 0
シミュレーション40:
出目: (2, 4), 獲得チップ: 0
出目: (6, 3), 獲得チップ: 0
出目: (6, 3), 獲得チップ: 0
出目: (6, 2), 獲得チップ: 0
シミュレーション41:
出目: (2, 2), 獲得チップ: 0
出目: (2, 6), 獲得チップ: 0
出目: (2, 3), 獲得チップ: 0
出目: (3, 2), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
シミュレーション42:
出目: (6, 4), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (5, 6), 獲得チップ: 0
シミュレーション43:
出目: (2, 3), 獲得チップ: 0
出目: (3, 3), 獲得チップ: 0
出目: (1, 1), 獲得チップ: 0
出目: (6, 6), 獲得チップ: 111
出目: (5, 6), 獲得チップ: 177
出目: (6, 2), 獲得チップ: 177
出目: (5, 3), 獲得チップ: 177
シミュレーション44:
出目: (3, 3), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (1, 6), 獲得チップ: 44
出目: (6, 2), 獲得チップ: 44
出目: (4, 3), 獲得チップ: 44
出目: (3, 4), 獲得チップ: 44
シミュレーション45:
出目: (1, 5), 獲得チップ: 0
出目: (2, 4), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 0
シミュレーション46:
出目: (6, 6), 獲得チップ: 0
出目: (6, 3), 獲得チップ: 0
出目: (1, 5), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0
出目: (2, 4), 獲得チップ: 0
シミュレーション47:
出目: (4, 6), 獲得チップ: 0
出目: (5, 6), 獲得チップ: 0
出目: (4, 2), 獲得チップ: 0
出目: (5, 3), 獲得チップ: 0
シミュレーション48:
出目: (2, 4), 獲得チップ: 0
出目: (2, 4), 獲得チップ: 0
出目: (3, 3), 獲得チップ: 0
出目: (4, 6), 獲得チップ: 0
出目: (3, 4), 獲得チップ: 0
シミュレーション49:
出目: (5, 1), 獲得チップ: 0
出目: (4, 5), 獲得チップ: 0
出目: (4, 4), 獲得チップ: 0
出目: (2, 1), 獲得チップ: 0
出目: (5, 5), 獲得チップ: 70
出目: (5, 4), 獲得チップ: 70
シミュレーション50:
出目: (5, 4), 獲得チップ: 0
出目: (1, 4), 獲得チップ: 0
出目: (6, 4), 獲得チップ: 0
出目: (6, 1), 獲得チップ: 0

処理はきちんと行われているようです。チップを獲得すべき時点で獲得していなかったり、獲得すべきでない時点で獲得してるといった不具合は見当たりません。試行回数が50回と少ないため平均値はどうでもよいのですが、1回目で2度当てに加えて33→11により251枚オールをかましています。いいなあ。43回目では33→11→66により177枚オールを見せつけています。いいなあ。

では適切なシュミレーションが行われている確認ができたところで、試行回数を増やして行います。結果を出力するととんでもないことになるので、結果出力部分はコメントアウトし、出ないとは限らないので400枚以上獲得の範囲も追加しました。各獲得枚数の出現率とヒストグラム、平均チップ獲得枚数だけを出力します。1000万回試行した結果がこちら。

0-1枚: 6781260回 (67.8126%)
2-100枚: 2575778回 (25.7578%)
101-200枚: 587243回 (5.8724%)
201-300枚: 51479回 (0.5148%)
301-400枚: 3842回 (0.0384%)
401-500枚: 358回 (0.0036%)
501-600枚: 37回 (0.0004%)
601-100000枚: 3回 (0.0000%)

合計獲得チップ数の平均: 26.0110


あまりにも少ないため見えないが、600枚以上のデータも存在する


平均値は先程計算した結果とほぼ一致しています。嬉しい。意外なのは、獲得0枚で走り抜けているデータ数が約67.81%しかないところです。シュバサイの8度振りが獲得0枚で走り抜ける確率は、わずか約45.98%となります。シュバリーには注意しましょう。逆でも全く同じことが言えるわけですが。
500枚を超えるデータが37回、なんと600枚を超えるデータも3回
出現しています。どういうこと?ノーマルサイコロでは280枚が最大獲得枚数です。シュバリー、夢がありますね。

まとめ

内容は以上になります。1000万回シュミレーションした結果に基づくサイコロチャンスの各確率や期待値のうち、読者の皆様の多くが関心を持ちそうなものをまとめておきます。

ノーマルサイコロ

1度以上出目当てする確率:24.11%
走り抜けの確率     :
75.89%
期待値         :
18.67

シュバリーサイコロ


チップ獲得が発生する確率:
32.19%
走り抜けの確率     :
67.81%
期待値         :
26.01

おわりに

果たしてここまで読んでくれている人がいるのか非常に疑問ですが、最後まで読んでいただき、ありがとうございます。33→11→11→44の266枚オールを食らい、「どういう確率やねん!」と雀荘を揺らしてから約2周間の執筆期間でした。ちなみに200枚以上獲得するシュバリーサイコロチャンスは0.5%以下です。どういう確率やねん。

シュミレーション結果と計算の結果がほぼ一致したのは嬉しかったです。Geminiくんと抱き合って喜びました。あとGeminiすごい。色々なことに使えそうです。皆さんもお話してみてください。なんと無料です。

ほぼGeminiと遊んでいただけのnoteでしたが、何かの役に立てば幸いです。また、この素晴らしいルールを考案し洗練してきたアンミカコミュニティの皆様に感謝いたします。白ぽっちよ永遠に。

ではみなさま、良いアンミカライフを。

以上


いいなと思ったら応援しよう!