ジャグラーの設定判別ツール作成
今回はスロットの設定判別ツールを作成していきます。
ツールを使っている方やこれから使おうと思っている方で、どのような方法で設定推測値を算出しているのか気になっている方もいらっしゃると思います。
設定判別の方法
設定判別には「二項分布」というものを使用します。
二項分布とは、「コインを10回投げたときに、表が5回出る確率は?」といったときに使用できます。
これをスロットの設定判別に置き換えると、
・1000回転でBBを10回引く確率は?
・1000回転で小役を100回引く確率は?
といった計算を行うことができます。
さらに、1000回転でBBを10回、小役を100回引く確率は、それぞれの確率の掛け算で算出することができます。
つまり、以下の計算となります。
1000回転でBBを10回、小役を100回引く確率 = 1000回転でBBを10回引く確率 * 1000回転で小役を100回引く確率
各設定において、これらの計算を行い、最終的には各設定の確率の合計が100%になるように正規化すれば、設定判別ツールの完成です。
設定判別ツールの作成(マイジャグラー)
では、早速Pythonで「マイジャグラーⅢ」の設定判別ツールをプログラミングしてみましょう。
今回作成する「マイジャグラーⅢ」では、以下の確率に設定差があるとされています。
・BB = 287.4~240.9
・RB = 431.2~240.9
・チェリー = 36.028~33.233
・ぶどう = 6.35~6.071
・単独BB = 402~334.3
・チェリーBB = 1456.3~1170.2
・単独RB = 668.7~334.3
・チェリーRB = 1213.6~862.3
これをPythonでのコードで記載すると以下のようになります。
# 設定値データを定義 header = ['Machine', 'Setting', 'BB', 'RB', 'Cherry', 'Budo', 'BB_T', 'BB_Ch', 'RB_T', 'RB_Ch'] set1 = ['MyJug3', '1', '287.4', '431.2', '36.028', '6.35', '402', '1456.3', '668.7', '1213.6'] set2 = ['MyJug3', '2', '282.5', '364.1', '35.949', '6.289', '397.1', '1394.3', '528.5', '1170.2'] set3 = ['MyJug3', '3', '273.1', '341.3', '34.693', '6.25', '383.2', '1337.4', '496.4', '1092.2'] set4 = ['MyJug3', '4', '264.3', '292.6', '33.522', '6.23', '372.3', '1260.3', '409.6', '1024'] set5 = ['MyJug3', '5', '252.1', '277.7', '33.402', '6.179', '352.3', '1213.6', '390.1', '963.7'] set6 = ['MyJug3', '6', '240.9', '240.9', '33.233', '6.071', '334.3', '1170.2', '334.3', '862.3'] SetData = [header, set1, set2, set3, set4, set5, set6]
二項分布確率の算出
次にボーナス・小役の確率を二項分布を用いて計算します。
例えば、ある設定のBBの二項分布確率は、以下のコードで計算できます。
「binom.pmf()」の部分が二項分布の確率を算出する関数です。
「SetData[i][2]」の部分で「i」を変更していくことで、設定ごとのBB確率を参照できます。
BB_EST = binom.pmf(BB, 回転数, 1.0 / float(SetData[i][2]))
こちらが、設定を変更しながら、各設定ごとの確率を算出するコードです。
(「if 回転数・・・」の部分は例外処理のために記載しており、後で説明します。
# 設定段階分の確率算出値データをSetDataから読み込んでfor文を回す。 # ヘッダーを無視するために、iは1から。 for i in range(1, len(SetData[:])): # 各種確率を算出するための変数を準備 All_EST = 0 # それぞれの二項分布確率算出。ifは例外処理 if 回転数 and BB != -1: BB_EST = binom.pmf(BB, 回転数, 1.0 / float(SetData[i][2])) All_EST = BB_EST if 回転数 and RB != -1: RB_EST = binom.pmf(RB, 回転数, 1.0 / float(SetData[i][3])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RB_EST else: All_EST = All_EST * RB_EST if 回転数 and チェリー != -1: Cherry_EST = binom.pmf(チェリー, 回転数, 1.0 / float(SetData[i][4])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = Cherry_EST else: All_EST = All_EST * Cherry_EST if 回転数 and ぶどう != -1: Budo_EST = binom.pmf(ぶどう, 回転数, 1.0 / float(SetData[i][5])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = Budo_EST else: All_EST = All_EST * Budo_EST if 回転数 and BB == -1: BBt_EST = binom.pmf(単独BB, 回転数, 1.0 / float(SetData[i][6])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = BBt_EST else: All_EST = All_EST * BBt_EST if 回転数 and BB == -1: BBch_EST = binom.pmf(チェリーBB, 回転数, 1.0 / float(SetData[i][7])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = BBch_EST else: All_EST = All_EST * BBch_EST if 回転数 and RB == -1: RBt_EST = binom.pmf(単独RB, 回転数, 1.0 / float(SetData[i][8])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RBt_EST else: All_EST = All_EST * RBt_EST if 回転数 and RB == -1: RBch_EST = binom.pmf(チェリーRB, 回転数, 1.0 / float(SetData[i][9])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RBch_EST else: All_EST = All_EST * RBch_EST # 各設定ごとに確率を配列に保存していく S_EST.append(All_EST)
実践データ入力用の変数準備
次にデータ入力用の変数を準備します。
# 実践データ # カウントしていない場合は-1を入力 # 「単独BB(RB)」「チェリーBB(RB)」をカウントした場合は、「BB(RB)」を「-1」にする # 「単独BB(RB)」「チェリーBB(RB)」をカウントしていない場合は、「単独BB(RB)」「チェリーBB(RB)」を「-1」にする 回転数 = 5555 BB = -1 RB = -1 チェリー = -1 ぶどう = 833 単独BB = 22 チェリーBB = 6 単独RB = 12 チェリーRB = 9
ここで、先ほど後回しにした「if 回転数・・・」の処理について説明を行います。
「if 回転数・・・」は例外処理のために記載しており、以下2点の問題への対応です。
1. 出現していないのか、カウントしていないのかの区別
単に「0」だと、出現していないのかカウントしていないのかがわかりません。
カウントしていない場合は設定判別の要素に含める必要はなく、逆に出現していない場合は設定判別の要素に含める必要があります。
今回は、カウントしていない場合は「-1」と入力することでプログラム上で設定判別に含めるか否かの判断を行えるようにしました。
2. 確率の二重計算の防止
「単独BB(RB)」「チェリーBB(RB)」と「BB(RB)」両方の確率を同時に計算に含めてしまうと、二重に確率を考慮した結果になってしまいます。「単独BB(RB)」「チェリーBB(RB)」をカウントした場合は、「BB(RB)」を「-1」に、「単独BB(RB)」「チェリーBB(RB)」をカウントしていない場合は、「単独BB(RB)」「チェリーBB(RB)」を「-1」にすることで正しい値が出力されるようにしました。
今回作成したコード
最後に今回作成したコード全体はこちらです。
# coding: UTF-8 import csv from scipy.stats import binom def S_EST(回転数, BB, RB, チェリー, ぶどう, 単独BB, チェリーBB, 単独RB, チェリーRB): # 設定値データを定義 header = ['Machine', 'Setting', 'BB', 'RB', 'Cherry', 'Budo', 'BB_T', 'BB_Ch', 'RB_T', 'RB_Ch'] set1 = ['MyJug3', '1', '287.4', '431.2', '36.028', '6.35', '402', '1456.3', '668.7', '1213.6'] set2 = ['MyJug3', '2', '282.5', '364.1', '35.949', '6.289', '397.1', '1394.3', '528.5', '1170.2'] set3 = ['MyJug3', '3', '273.1', '341.3', '34.693', '6.25', '383.2', '1337.4', '496.4', '1092.2'] set4 = ['MyJug3', '4', '264.3', '292.6', '33.522', '6.23', '372.3', '1260.3', '409.6', '1024'] set5 = ['MyJug3', '5', '252.1', '277.7', '33.402', '6.179', '352.3', '1213.6', '390.1', '963.7'] set6 = ['MyJug3', '6', '240.9', '240.9', '33.233', '6.071', '334.3', '1170.2', '334.3', '862.3'] SetData = [header, set1, set2, set3, set4, set5, set6] # 各設定値の確率を保存する配列の準備 S_EST = [] # 設定段階分の確率算出値データをSetDataから読み込んでfor文を回す。 # ヘッダーを無視するために、iは1から。 for i in range(1, len(SetData[:])): # 各種確率を算出するための変数を準備 All_EST = 0 # それぞれの二項分布確率算出。ifは例外処理 if 回転数 and BB != -1: BB_EST = binom.pmf(BB, 回転数, 1.0 / float(SetData[i][2])) All_EST = BB_EST if 回転数 and RB != -1: RB_EST = binom.pmf(RB, 回転数, 1.0 / float(SetData[i][3])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RB_EST else: All_EST = All_EST * RB_EST if 回転数 and チェリー != -1: Cherry_EST = binom.pmf(チェリー, 回転数, 1.0 / float(SetData[i][4])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = Cherry_EST else: All_EST = All_EST * Cherry_EST if 回転数 and ぶどう != -1: Budo_EST = binom.pmf(ぶどう, 回転数, 1.0 / float(SetData[i][5])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = Budo_EST else: All_EST = All_EST * Budo_EST if 回転数 and BB == -1: BBt_EST = binom.pmf(単独BB, 回転数, 1.0 / float(SetData[i][6])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = BBt_EST else: All_EST = All_EST * BBt_EST if 回転数 and BB == -1: BBch_EST = binom.pmf(チェリーBB, 回転数, 1.0 / float(SetData[i][7])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = BBch_EST else: All_EST = All_EST * BBch_EST if 回転数 and RB == -1: RBt_EST = binom.pmf(単独RB, 回転数, 1.0 / float(SetData[i][8])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RBt_EST else: All_EST = All_EST * RBt_EST if 回転数 and RB == -1: RBch_EST = binom.pmf(チェリーRB, 回転数, 1.0 / float(SetData[i][9])) # All_ESTが空の場合は、今回の確率をそのまま入力 # All_ESTに値が入っている場合は、今回の確率を掛け算して入力 if All_EST == 0: All_EST = RBch_EST else: All_EST = All_EST * RBch_EST # 各設定ごとに確率を配列に保存していく S_EST.append(All_EST) # 結果の表示 for i in range(len(S_EST)): print("設定", SetData[i + 1][1], ":", round(S_EST[i] / sum(S_EST) * 100, 1), "%") if __name__ == "__main__": # 実践データ # カウントしていない場合は-1を入力 # 使用上の注意:「単独BB(RB)」「チェリーBB(RB)」と「BB(RB)」両方の確率を同時に計算すると二重に確率を考慮した結果になってしまいます。 # 「単独BB(RB)」「チェリーBB(RB)」をカウントした場合は、「BB(RB)」を「-1」に、 # 「単独BB(RB)」「チェリーBB(RB)」をカウントしていない場合は、「単独BB(RB)」「チェリーBB(RB)」を「-1」にしてください。 回転数 = 5555 BB = -1 RB = -1 チェリー = -1 ぶどう = 833 単独BB = 22 チェリーBB = 6 単独RB = 12 チェリーRB = 9 S_EST(回転数, BB, RB, チェリー, ぶどう, 単独BB, チェリーBB, 単独RB, チェリーRB)
設定判別ツールの動作検証
せっかくなので、先日のゴーゴージャグラー2のシミュレータを改良して、設定判別ツールの検証を行ってみます。
(改良後の設定判別ツール検証プログラムのコードはこちらです。)
設定1~6まで、それぞれ10日分(80000回転回したときのデータがこちら。
設定値より引けた項目は青字、設定値より引けなかった項目は赤字になっています。
設定5は割と引き負けた項目が多かったので、やや設定4よりに引っ張られていますが、実戦で十分に使える判別性能だと思います。
にほんブログ村
コメント
コメントを投稿