ディーラーがバストする確率をシミュレーションしてみた


背景

ブラックジャックでディーラーがバストする確率を、プログラムを書いてシミュレーションしてみました。

自分のアクション(ヒット、スタンド、ダブル、スプリット)を決める際に、自分で勝ちに行くのか(行かざるを得ないのか)、ディーラーのバストに期待するのか、考えるベースとしたい。

結果

バーの上にマウスを乗せると詳細な確率が表示されます。

考察

  • 2から6までは弱いカード、7以上は強いカードというイメージだったが、2と7はあまり変わらないのが意外だった。2は次に2回連続10が出なければバストせず、まだ自由度があるため、結構強い。
  • 3から6まではディーラーのバストに期待できるが、せいぜい3回に1回。
  • 10とAには圧倒的に差がある。

計算に用いたプログラム(Go言語)

 1package main
 2
 3import (
 4	"fmt"
 5	"math/rand"
 6	"time"
 7
 8	"github.com/dustin/go-humanize"
 9)
10
11func main() {
12	rand.Seed(time.Now().Unix())
13	fmt.Println("最初のカード\tBustする確率")
14	fmt.Println("------------------------------------------------")
15
16	for firstCard := 1; firstCard <= 10; firstCard++ {
17		busted := 0
18
19		// 最初のカードごとに平均100万回(合計1,000万回)試行する
20		for i := 0; i < 1000000; i++ {
21			cards := []int{}
22			cards = append(cards, firstCard)
23
24			var total int
25			for {
26				cards = append(cards, getCard())
27
28				total = getTotal(cards)
29				if total >= 17 {
30					break
31				}
32			}
33
34			if total > 22 {
35				busted++
36			}
37		}
38
39		fmt.Printf("%d\t\t%.1f%% (%s回 / 1,000,000回)\n",
40			firstCard,
41			float64(busted)*100/float64(1000000),
42			humanize.Comma(int64(busted)))
43	}
44}
45
46func getCard() int {
47	r := rand.Intn(13) + 1
48	if r > 10 {
49		r = 10
50	}
51
52	return r
53}
54
55func getTotal(cards []int) int {
56	total := 0
57
58	// まずは1を1回だけ11とみなす
59	firstApply := true
60	for _, v := range cards {
61		if v == 1 && firstApply == false {
62			total++
63		} else if v == 1 && firstApply == true {
64			total += 11
65			firstApply = false
66		} else {
67			total += v
68		}
69	}
70
71	if total <= 21 {
72		return total
73	}
74
75	// 1を全て1と解釈して21以下にできないか試みる
76	total = 0
77	for _, v := range cards {
78		total += v
79	}
80
81	return total
82}

comments powered by Disqus