無料マンガアプリでカイジを見ていたら
気になって仕方なくなってしまいました。

解説動画はこちら




さてチンチロリンのルールですが
こんな内容です。

サイコロを3つ同時に振って役が揃うまで振る(最大3回まで)

強い役が勝つ

役名条件
ピンゾロ1・1・1
ゾロ目2・2・2 , 3・3・3 , 4・4・4 , 5・5・5 , 6・6・6
シゴロ4・5・6
出目の大きい順番2枚が同じ、残った1つの目
ションベン役がなかった場合,お椀からサイコロが出た場合
ヒフミ1・2・3

他にも細かなルールは有りますが
今回は割愛します。

さてまずはチンチロリンの役を判定するプログラムを
作ってみましょう。

def tintiro_hand(h):
    # ピンゾロ
    if all([h[0]==1,h[1]==1,h[2]==1]):
        return 1
    # ゾロ目
    if h[0]==h[1] and h[1]==h[2]:
        return 2
    # シゴロ
    if [4,5,6]==list(sorted(h)):
        return 3
        # ヒフミ
    if [1,2,3]==list(sorted(h)):
        return 11
    # 出目 and ションベン
    calc = {}
    for n in h:
        if n in calc:
            calc[n]+= 1
        else:
            calc[n]=1
    if 2 in calc.values():
        return 3 + 7-sorted(calc.items(),key=lambda x:x[1])[0][0]
    else:
        return 10

def judge(h1,h_2):
    if h1==h_2:
        return 'DRAW'
    if h1<h_2:
        return 'WIN'
    else:
        return 'LOSE'


チンチロリンではサイコロを3つ使います。

このサイコロの組み合わせは
itertoolsで求めることが出来ます。

まずは通常のサイコロで戦った際の勝敗を見てみましょう。
import itertools
from fractions import Fraction

hands1 = list(itertools.product([1,2,3,4,5,6],repeat=3))
hands2 = list(itertools.product([1,2,3,4,5,6],repeat=3))
wins = {}
for hand1 in hands1:
    for hand2 in hands2:
        w = judge(tintiro_hand(hand1),tintiro_hand(hand2))
        if w in wins:
            wins[w] +=1
        else:
            wins[w] = 1
total = sum(wins.values())
draw,win,lose =wins['DRAW'],wins['WIN'],wins['LOSE']
print('DRAW\t' , Fraction(draw,total) , ' \t{:%}'.format(draw/total))
print('WIN \t'    , Fraction(win ,total)  , '\t{:%}'.format(win/total))
print('LOSE\t'   , Fraction(lose,total)  , '\t{:%}'.format(lose/total))

DRAW	 1639/5832  	28.103567%
WIN 	 4193/11664 	35.948217%
LOSE	 4193/11664 	35.948217%

だいたい36%ほどで勝ったり負けたりですね。

マンガではここで特別なサイコロが登場します。
それがシゴロ賽です!!!

4,5,6しか出目のない特殊なサイコロ

地下労働施設の班長
大槻が用いたイカサマサイコロです。

これを使うと極端に役の出方が変わります。

通常のサイコロと勝敗を比べてみましょう。
import itertools
from fractions import Fraction

hands1 = list(itertools.product([1,2,3,4,5,6],repeat=3))
hands2 = list(itertools.product([4,5,6,4,5,6],repeat=3))
wins = {}
for hand1 in hands1:
    for hand2 in hands2:
        w = judge(tintiro_hand(hand1),tintiro_hand(hand2))
        if w in wins:
            wins[w] +=1
        else:
            wins[w] = 1
total = sum(wins.values())
draw,win,lose =wins['DRAW'],wins['WIN'],wins['LOSE']
print('DRAW\t' , Fraction(draw,total) , ' \t{:%}'.format(draw/total))
print('WIN \t'    , Fraction(win ,total)  , '\t{:%}'.format(win/total))
print('LOSE\t'   , Fraction(lose,total)  , '\t{:%}'.format(lose/total))

DRAW	 107/1944 	5.504115%
WIN 	 175/1944 	9.002058%
LOSE	 277/324   	85.493827%

相手側の勝率が極端に変わりますね!!!

通常時35%ほどだった負け確率が85%と
50%ほど負ける確率が増加します。

実際に役が出る確率はどういう確率でしょうか?

お互いのサイコロの出目でみてみましょう。

サイコロの出目の組み合わせは
お互い 6**3 で216通りあります。

通常のサイコロを振ってみると
import itertools
import matplotlib.pyplot as plt
%matplotlib inline

hands1 = list(itertools.product([1,2,3,4,5,6],repeat=3))
hands = {}
for hand1 in hands1:
    h = tintiro_hand(hand1)
    if h in hands:
        hands[h] +=1
    else:
        hands[h] = 1

plt.figure(figsize=(12,6))
x = [k for k,v in sorted(hands.items())]
y = [v for k,v in sorted(hands.items())]
for x1,y1 in zip(x,y):
    plt.text(x1, y1+1 , y1 , size = 10, color = "green")
    plt.text(x1, y1+10 , '{:.01%}'.format(y1/216), size = 10, color = "black")
label = ['111','ゾロ目','シゴロ','6','5','4','3','2','1','ションベン','123']
plt.bar(x,y,tick_label=label)
plt.grid()
plt.show()
download-1
こんな確率ですね。
今回は3回振りなおしを考慮していないので
出目を考えるとションベンになる確率が高いですね。

これと比べてシゴロ賽はどうでしょうか?
import itertools
import matplotlib.pyplot as plt
%matplotlib inline

hands = list(itertools.product([4,5,6,4,5,6],repeat=3))
hands2 = {i:0 for i in range(1,12)}
for hand in hands:
    h2 = tintiro_hand(hand)
    if h2 in hands2:
        hands2[h2] +=1
    else:
        hands2[h2] = 1

plt.figure(figsize=(12,6))
x = [k for k,v in sorted(hands2.items())]
y = [v for k,v in sorted(hands2.items())]
for x1,y1 in zip(x,y):
    plt.text(x1, y1+1 , y1 , size = 10, color = "green")
    plt.text(x1, y1+10 , '{:.01%}'.format(y1/216), size = 10, color = "black")
label = ['111','ゾロ目','シゴロ','6','5','4','3','2','1','ションベン','123']
plt.bar(x,y,tick_label=label)
plt.grid()
plt.show()
download-2

強い手の確率が極端に上がります。

見比べてみると瞭然ですね。
スクリーンショット 2020-05-23 17.10.35

マンガではどうやってこのイカサマを見つけたかというと
出目をメモってる三好がいて
その出目の歪さからイカサマサイコロに気づいた・・・
という感じでした。

やはり、データの整備とデータから発見できるかという
まさにデータサイエンス的な要素をもつ
このチンチロリン編は

賭博破戒録カイジの第3章に出てきます。

みていない方はぜひご賞味ください。

最後は倍、いや100倍返しでwww

とまあ、456サイコロは売ってるみたいなので
これを使うと圧倒的に勝てますねーー

やはり、統計って大事ですよねー
今回はこれまでです
それでは