お知らせ

ただいま、シンタックスハイライターの設定を見直しております。
プログラムが見にくくなっているページがありますが、ご容赦ください。

ブラックジャックでディーラーと同じ法則でカードを引いたら、ディーラーに勝てるのだろうか?

モデル化とシミュレーション

こんにちは。まだまだブラックジャックでシミュレーションしてみます。

ブラックジャックで、ディーラーは17以上になるまでカードをヒットし続けるということになっています。

そうしたら、そうしたら、その法則が最強説なんじゃないかと思ってしまったんですね、ハイ!

ということで、シミュレーションしてみることにします。

勝敗について

ここまでは、プレイヤーとディーラーのそれぞれ一方に注目していたのであまり気にしていませんでしたが、ここからは対戦になるので、勝敗の決め方を簡単に確認しておきます。

参考にしたサイトは、次になります。

とりあえず、以下により勝敗を決めます。

  1. ブラックジャック(A+10・J・Q・Kのいずれか)が一方だけならば、ブラックジャックになった方が勝ち
  2. プレイヤーがバーストしたらとにかく負け
  3. 合計が21に近いほうが勝ち
  4. ブラックジャック以外で合計が同じ場合には引き分け

これにより判定するよう、プログラムを作成します。

シミュレーションするプログラム

単に今まで書いたことに従って、ヒットしたり、勝敗を判定したりしているだけなので、プログラムの詳細は割愛します。

毎回1ドルずつ掛けることにして、収支も出してみます。

import random
def draw():
    x = random.randint( 0, 51 )
    while x in ca:
        x = random.randint( 0, 51 )
    ca.append(x)
    return x
def calc( hand ):
    s = 0
    flag = False
    for h in hand:
        s += 10 if ( h % 13 ) > 9 else ( ( h % 13 ) + 1 )
        if h % 13 ==0:
            flag = True
    if s < 12 and flag:
        s += 10
    return s

point = 0
cnt = {}
wi = 0
lo = 0
dr = 0
tr = 10000000
for i in range( 0, tr ):
    ca = []
    c_hand = [ draw() ]
    d_hand = [ draw() ]
    c_hand.append( draw() )
    d_hand.append( draw() )
    cp = calc( c_hand )
    dp = calc( d_hand )
    if cp==21 and dp!=21:
        wi += 1
        point += 1.5
        continue
    elif cp!=21 and dp==21:
        lo += 1
        point -= 1.0
        continue
    while cp < 17:
        c_hand.append( draw() )
        cp = calc( c_hand )
    if cp > 21:
        lo += 1
        point -= 1.0
        continue
    dp = calc( d_hand )
    while dp < 17:
        d_hand.append( draw() )
        dp = calc( d_hand )
    if dp > 21:
        wi += 1
        point += 1.0
        continue
    if cp > dp:
        wi += 1
        point += 1.0
    elif cp < dp:
        lo += 1
        point -= 1.0
    else:
        dr += 1
print('プレーヤー: 勝ち{}回 引き分け{}回 負け{}回'.format( wi, dr, lo ))
print('プレーヤー: 勝ち{:0.2f}% 引き分け{:0.2f}% 負け{:0.2f}% 収支{:0.1f}ドル'
        .format( wi*100/tr, dr*100/tr, lo*100/tr , point ))

シミュレーションの結果

それでは、実行結果です。

勝負を1000万回させてみた結果です。(なお、実行時間は約1分半でした)

プレーヤー: 勝ち4126842回 引き分け948255回 負け4924903回
プレーヤー: 勝ち41.27% 引き分け9.48% 負け49.25% 収支-565551.5ドル

予想以上に差をつけられて、勝率はディーラーの方が高いですね。

収支も56万ドルもマイナスになってしまいました・・・

作戦を練り直してみます!

今回はこれでおしまいにします。それではまた。

Posted by kasugai