今回はブラックジャックの
シミュレーションをしてみました。
解説動画はこちら
今回は
・初期カードは52枚を4セット
・配ったら捨て残り10枚以下になったらカード交換
さて簡単なプログラムを組んでみることとします。
カードはスペード、ハート、クラブ、ダイヤの4種類で
1-13まであります。
それを4セット使うこととします。
最初は点数計算です
1は11とも計算できるルールがあるので
21を超えない場合は11として数え
21を超えても1とするようにしました。
次に1ゲームの実行を行うことを考えます。
最初に2枚ずつ配り
そこからは1枚ずつ配ります。
そこまで複雑なものでも無く
プレイヤーは18以上
ディーラーは17以上になるまで
カードを引き続けます。
カードが揃ったら勝負に入り
バーストせず21に近い方が勝ちです。
これで対戦の準備が出来ました。
カードを作って対戦してみることとしましょう。
100回ほど対戦し
途中カードが尽きそうになったら
カードを入れ替えます。
最終的に結果がどうなるのかも
集計してみることとします。
こんな感じでプレイヤーとディーラーの
勝ちを集計してみました。
これだけだとあまり面白くは無いですよね。
やはり醍醐味は「金を掛ける」
ということだと思いますんで
金を掛けるシミュレーションもしてみましょう。
資金は10万円
掛け金は1000円
勝ったら倍もらえるようにしました。
シミュレーションをしてみました。
解説動画はこちら
今回は
ブラックジャックのシミュレーターを作って
遊んでみることとしました。
開発するブラックジャックのルールなどを
決めておきましょう。
こんなルールのプログラムを作ることとします。
遊んでみることとしました。
開発するブラックジャックのルールなどを
決めておきましょう。
こんなルールのプログラムを作ることとします。
・初期カードは52枚を4セット
・配ったら捨て残り10枚以下になったらカード交換
・プレイヤーとディーラーの2人対戦
・実行開始時、プレイヤーディーラーそれぞれカードを2枚引く
・先にプレイヤーがカードを引きディーラーが次に引く
・ディーラーは自分の手札が17以上になるまで引き続ける
・プレイヤーは18以上なら勝負、21を超えていたらバースト
・21に近い方の勝ちで掛け金の倍額をもらえ引き分けは戻し
・JとQとKは10として扱う
・ダブルダウンなし、スピリットなし、サレンダーなし
・その他特殊なルールなし
・その他特殊なルールなし
さて簡単なプログラムを組んでみることとします。
カードはスペード、ハート、クラブ、ダイヤの4種類で
1-13まであります。
それを4セット使うこととします。
最初は点数計算です
1は11とも計算できるルールがあるので
21を超えない場合は11として数え
21を超えても1とするようにしました。
# ライブラリ
import random
# 点数計算
def score_calc(hands):
score = 0
flg = False
for hand in hands:
s = int(hand.split(':')[1])
if s>=10:
score += 10
elif s==1:
score+=1
flg=True
else:
score += s
if score>21 and flg:
score = 0
for hand in hands:
s = int(hand.split(':')[1])
if s>=10:
score += 10
elif s==1:
score+=1
else:
score += s
return score
次に1ゲームの実行を行うことを考えます。
最初に2枚ずつ配り
そこからは1枚ずつ配ります。
そこまで複雑なものでも無く
プレイヤーは18以上
ディーラーは17以上になるまで
カードを引き続けます。
カードが揃ったら勝負に入り
バーストせず21に近い方が勝ちです。
# ゲーム
def game1(game_card):
# 初期配
player = [game_card.pop(0)]
player += [game_card.pop(0)]
dealer = [game_card.pop(0)]
dealer += [game_card.pop(0)]
p_flg , d_flg = False,False
# ディール
while True:
# プレイヤーは18以上になるまで引く
if score_calc(player)>=18:
p_flg = True
# ディーラーは17以上になるまで引く
if score_calc(dealer)>=17:
d_flg = True
if not p_flg:
player += [game_card.pop(0)]
if not d_flg:
dealer += [game_card.pop(0)]
if p_flg and d_flg:
break
# 勝負
p_num = score_calc(player)
d_num = score_calc(dealer)
win = 'draw'
if p_num > 21 and d_num > 21:
win = 'draw'
elif p_num > 21 and d_num <=21:
win = 'dealer'
elif p_num <= 21 and d_num >21:
win = 'player'
elif p_num < d_num:
win = 'dealer'
elif p_num > d_num:
win = 'player'
result = {'player':p_num,'dealer':d_num,'win':win}
return result
これで対戦の準備が出来ました。
カードを作って対戦してみることとしましょう。
100回ほど対戦し
途中カードが尽きそうになったら
カードを入れ替えます。
# カードのセット数
sets = 4
#スペード、ハート、クラブ、ダイヤ * 13枚
card = [c+':'+str(n) for c in ['S','H','C','D'] for n in range(1,14)]
# カード作成
cards = card * sets
# シャッフル
random.shuffle(cards)
# 対戦
results = []
for i in range(100):
# 1ゲームの結果
tmp = game1(cards)
results.append(tmp)
# 10枚以下になったらカードを交換
if len(cards)<=10:
cards = card * sets
random.shuffle(cards)
最終的に結果がどうなるのかも
集計してみることとします。
# 対戦結果のサマリー
calc = {'player': 0, 'dealer': 0}
for row in results:
if row['win'] == 'player':
calc['player'] +=1
if row['win'] == 'dealer':
calc['dealer'] +=1
print(calc){'player': 30, 'dealer': 42}こんな感じでプレイヤーとディーラーの
勝ちを集計してみました。
これだけだとあまり面白くは無いですよね。
やはり醍醐味は「金を掛ける」
ということだと思いますんで
金を掛けるシミュレーションもしてみましょう。
資金は10万円
掛け金は1000円
勝ったら倍もらえるようにしました。
fund = 100000
latch = 1000
# カードのセット数
sets = 4
#スペード、ハート、クラブ、ダイヤ * 13枚
card = [c+':'+str(n) for c in ['S','H','C','D'] for n in range(1,14)]
# カード作成
cards = card * sets
# シャッフル
random.shuffle(cards)
# 対戦
results = []
for i in range(100):
# 1ゲームごとにかける
fund -= latch
tmp = game1(cards)
win = tmp['win']
results.append(tmp)
# 勝ったら倍額貰える
if win=='player':
fund += latch * 2
# 引き分けは戻し
elif win=='draw':
fund += latch
# 10枚以下になったらカードを交換
if len(cards)<=10:
cards = card * sets
random.shuffle(cards)さて結果はどうなるんでしょうか!!!# 対戦結果のサマリー
calc = {'player': 0, 'dealer': 0}
for row in results:
if row['win'] == 'player':
calc['player'] +=1
if row['win'] == 'dealer':
calc['dealer'] +=1
print(calc)
print('資金残り : ' , fund){'player': 41, 'dealer': 31}
資金残り : 110000
今回は勝ちが多くて儲かっていますね!!
ここからは掛け方を変えて
試してみることとしましょう。
最初はグッドマン法です。
これは、勝ちに応じて賭け金を「1、2、3、5」と
4段階で増やし負けた時点で1に賭け金を戻す手法です。
プログラムをちょっと改良して
掛け金を変えてみます。
さて、結果は??
資金残り : 102000
負けが少し多くても
資金が初期金額を上回っていますね。
うまく掛け金が多い時に勝てれば
初期金額を上回れますが
そううまくは行きませんね。
次は10%投資法です。
今回は勝ちが多くて儲かっていますね!!
ここからは掛け方を変えて
試してみることとしましょう。
最初はグッドマン法です。
これは、勝ちに応じて賭け金を「1、2、3、5」と
4段階で増やし負けた時点で1に賭け金を戻す手法です。
プログラムをちょっと改良して
掛け金を変えてみます。
fund = 100000
latch = 1000
# カードのセット数
sets = 4
#スペード、ハート、クラブ、ダイヤ * 13枚
card = [c+':'+str(n) for c in ['S','H','C','D'] for n in range(1,14)]
# カード作成
cards = card * sets
# シャッフル
random.shuffle(cards)
# 対戦
results = []
for i in range(100):
# 1ゲームごとにかける
fund -= latch
tmp = game1(cards)
tmp['latch'] = latch
win = tmp['win']
# 勝ったら倍額貰える
if win=='player':
fund += latch * 2
if latch < 3000:
latch += 1000
elif latch ==3000:
latch += 2000
# 引き分けは戻し
elif win=='draw':
fund += latch
else:
latch = 1000
tmp['fund'] = fund
results.append(tmp)
# 10枚以下になったらカードを交換
if len(cards)<=10:
cards = card * sets
random.shuffle(cards)
さて、結果は??
# 対戦結果のサマリー
calc = {'player': 0, 'dealer': 0}
for row in results:
if row['win'] == 'player':
calc['player'] +=1
if row['win'] == 'dealer':
calc['dealer'] +=1
print(calc)
print('資金残り : ' , fund)
{'player': 34, 'dealer': 35}
資金残り : 102000
負けが少し多くても
資金が初期金額を上回っていますね。
うまく掛け金が多い時に勝てれば
初期金額を上回れますが
そううまくは行きませんね。
次は10%投資法です。
これは掛け金を毎回、資金の10%で掛けてみる
というものです。
掛け金を資金の10分の1にするように
変えてみることとします。
勝ちが多ければ、そりゃあ増えますが
負けが混むと目も当てられません。
長く続けることは出来ますが
アップダウンが激しすぎますね。
最後は31システム投資法です。
1,1,1,2,2,4,4,8,8 に分けて賭ける手法で
2連勝すると初期金額を上回り
全部負けてもこの分しか負けません。
資金残り : 103000
何度か試してみましたが
資金の推移としては連勝さえできれば
かなりの確率で初期金額を上回れます。
というものです。
掛け金を資金の10分の1にするように
変えてみることとします。
fund = 100000
# カードのセット数
sets = 4
#スペード、ハート、クラブ、ダイヤ * 13枚
card = [c+':'+str(n) for c in ['S','H','C','D'] for n in range(1,14)]
# カード作成
cards = card * sets
# シャッフル
random.shuffle(cards)
# 対戦
results = []
for i in range(100):
# 1ゲームごとにかける , 資金の10%
latch = fund//10
fund -= latch
tmp = game1(cards)
tmp['latch'] = latch
win = tmp['win']
# 勝ったら倍額貰える
if win=='player':
fund += latch * 2
# 引き分けは戻し
elif win=='draw':
fund += latch
tmp['fund'] = fund
results.append(tmp)
# 10枚以下になったらカードを交換
if len(cards)<=10:
cards = card * sets
random.shuffle(cards)
# 対戦結果のサマリー
calc = {'player': 0, 'dealer': 0}
for row in results:
if row['win'] == 'player':
calc['player'] +=1
if row['win'] == 'dealer':
calc['dealer'] +=1
print(calc)
print('資金残り : ' , fund){'player': 46, 'dealer': 35}
資金残り : 200700
勝ちが多ければ、そりゃあ増えますが
負けが混むと目も当てられません。
長く続けることは出来ますが
アップダウンが激しすぎますね。
最後は31システム投資法です。
1,1,1,2,2,4,4,8,8 に分けて賭ける手法で
2連勝すると初期金額を上回り
全部負けてもこの分しか負けません。
fund = 100000
# カードのセット数
sets = 4
#スペード、ハート、クラブ、ダイヤ * 13枚
card = [c+':'+str(n) for c in ['S','H','C','D'] for n in range(1,14)]
# カード作成
cards = card * sets
# シャッフル
random.shuffle(cards)
# 対戦
results = []
for i in [1,1,1,2,2,4,4,8,8]:
# 1ゲームごとにかける額は31の金額で
latch = 1000 * i
fund -= latch
tmp = game1(cards)
tmp['latch'] = latch
win = tmp['win']
# 勝ったら倍額貰える
if win=='player':
fund += latch * 2
# 引き分けは戻し
elif win=='draw':
fund += latch
tmp['fund'] = fund
results.append(tmp)
# 10枚以下になったらカードを交換
if len(cards)<=10:
cards = card * sets
random.shuffle(cards)
# 対戦結果のサマリー
calc = {'player': 0, 'dealer': 0}
for row in results:
if row['win'] == 'player':
calc['player'] +=1
if row['win'] == 'dealer':
calc['dealer'] +=1
print(calc)
print('資金残り : ' , fund)
{'player': 5, 'dealer': 2}
資金残り : 103000
何度か試してみましたが
資金の推移としては連勝さえできれば
かなりの確率で初期金額を上回れます。
[{'player': 18, 'dealer': 25, 'win': 'player', 'latch': 1000, 'fund': 101000},
{'player': 19, 'dealer': 22, 'win': 'player', 'latch': 1000, 'fund': 102000},
{'player': 21, 'dealer': 19, 'win': 'player', 'latch': 1000, 'fund': 103000},
{'player': 18, 'dealer': 17, 'win': 'player', 'latch': 2000, 'fund': 105000},
{'player': 19, 'dealer': 20, 'win': 'dealer', 'latch': 2000, 'fund': 103000},
{'player': 21, 'dealer': 22, 'win': 'player', 'latch': 4000, 'fund': 107000},
{'player': 18, 'dealer': 19, 'win': 'dealer', 'latch': 4000, 'fund': 103000},
{'player': 21, 'dealer': 21, 'win': 'draw', 'latch': 8000, 'fund': 103000},
{'player': 22, 'dealer': 22, 'win': 'draw', 'latch': 8000, 'fund': 103000}]
推移はこんな感じですが
2連勝したらそこで打ち切る
というルールでやれば、回収金額の方が
多くなるかもしれません。
そうは上手くは行かないんですけどね・・・
この掛け方はいわゆる
マーチンゲール法というものの派生で
必ず勝てる掛け方ではありません。
まとめですが
シミュレーションでは初期金額を上回ることもあれば
大きく下回ることもあります。
必勝出来ないのであれば
リスクも当然あるので
やるべきでは無いでしょうねーーー
次は掛け方以外にも
ハンドの関係性からのカードの引き方や
攻略法も見ていきたいと思います。
今回はここまでです
それでは。
推移はこんな感じですが
2連勝したらそこで打ち切る
というルールでやれば、回収金額の方が
多くなるかもしれません。
そうは上手くは行かないんですけどね・・・
この掛け方はいわゆる
マーチンゲール法というものの派生で
必ず勝てる掛け方ではありません。
まとめですが
シミュレーションでは初期金額を上回ることもあれば
大きく下回ることもあります。
必勝出来ないのであれば
リスクも当然あるので
やるべきでは無いでしょうねーーー
次は掛け方以外にも
ハンドの関係性からのカードの引き方や
攻略法も見ていきたいと思います。
今回はここまでです
それでは。
