这个修改过的二十一点游戏的最佳获胜策略是什么?
问题
是否有最好的价值继续保持下去,以便我赢得尽可能多的比赛? 如果是这样,那是什么?
编辑:是否有一个确切的获胜概率,可以计算一个给定的限制,独立于任何对手的行为? (自大学以来我没有做过概率统计)。 我有兴趣看到这个答案与我的模拟结果进行对比。
编辑:修正了我算法中的错误,更新了结果表。
背景
我一直在玩一个修改过的二十一点游戏,其中有一些来自标准规则的烦人的规则调整。 我已经制定了与标准二十一点规则不同的规则,还包括那些不熟悉的二十一点规则。
修改的21点规则
什么是一副牌?
一副扑克牌由52张牌组成,其中四种值分别为以下13个值:
1,2,3,4,5,6,7,8,9,10,J,Q,K,A
没有其他卡的财产是相关的。
这是一个Ruby表示:
CARDS = ((2..11).to_a+[10]*3)*4
算法
我已经接近这个如下:
这是在Ruby中实现的算法:
#!/usr/bin/env ruby
class Array
def shuffle
sort_by { rand }
end
def shuffle!
self.replace shuffle
end
def score
sort.each_with_index.inject(0){|s,(c,i)|
s+c > 21 - (size - (i + 1)) && c==11 ? s+1 : s+c
}
end
end
N=(ARGV[0]||100_000).to_i
NDECKS = (ARGV[1]||1).to_i
CARDS = ((2..11).to_a+[10]*3)*4*NDECKS
CARDS.shuffle
my_limits = (12..21).to_a
opp_limits = my_limits.dup
puts " " * 55 + "opponent_limit"
printf "my_limit |"
opp_limits.each do |result|
printf "%10s", result.to_s
end
printf "%10s", "net"
puts
printf "-" * 8 + " |"
print " " + "-" * 8
opp_limits.each do |result|
print " " + "-" * 8
end
puts
win_totals = Array.new(10)
win_totals.map! { Array.new(10) }
my_limits.each do |my_limit|
printf "%8s |", my_limit
$stdout.flush
opp_limits.each do |opp_limit|
if my_limit == opp_limit # will be a tie, skip
win_totals[my_limit-12][opp_limit-12] = 0
print " --"
$stdout.flush
next
elsif win_totals[my_limit-12][opp_limit-12] # if previously calculated, print
printf "%10d", win_totals[my_limit-12][opp_limit-12]
$stdout.flush
next
end
win = 0
lose = 0
draw = 0
N.times {
cards = CARDS.dup.shuffle
my_hand = [cards.pop, cards.pop]
opp_hand = [cards.pop, cards.pop]
# hit until I hit limit
while my_hand.score < my_limit
my_hand << cards.pop
end
# hit until opponent hits limit
while opp_hand.score < opp_limit
opp_hand << cards.pop
end
my_score = my_hand.score
opp_score = opp_hand.score
my_score = 0 if my_score > 21
opp_score = 0 if opp_score > 21
if my_hand.score == opp_hand.score
draw += 1
elsif my_score > opp_score
win += 1
else
lose += 1
end
}
win_totals[my_limit-12][opp_limit-12] = win-lose
win_totals[opp_limit-12][my_limit-12] = lose-win # shortcut for the inverse
printf "%10d", win-lose
$stdout.flush
end
printf "%10d", win_totals[my_limit-12].inject(:+)
puts
end
用法
ruby blackjack.rb [num_iterations] [num_decks]
该脚本默认为100,000次迭代和4次套牌。 100,000快速的MacBook Pro需要大约5分钟。
产出(N = 100 000)
opponent_limit
my_limit | 12 13 14 15 16 17 18 19 20 21 net
-------- | -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
12 | -- -7666 -13315 -15799 -15586 -10445 -2299 12176 30365 65631 43062
13 | 7666 -- -6962 -11015 -11350 -8925 -975 10111 27924 60037 66511
14 | 13315 6962 -- -6505 -9210 -7364 -2541 8862 23909 54596 82024
15 | 15799 11015 6505 -- -5666 -6849 -4281 4899 17798 45773 84993
16 | 15586 11350 9210 5666 -- -6149 -5207 546 11294 35196 77492
17 | 10445 8925 7364 6849 6149 -- -7790 -5317 2576 23443 52644
18 | 2299 975 2541 4281 5207 7790 -- -11848 -7123 8238 12360
19 | -12176 -10111 -8862 -4899 -546 5317 11848 -- -18848 -8413 -46690
20 | -30365 -27924 -23909 -17798 -11294 -2576 7123 18848 -- -28631 -116526
21 | -65631 -60037 -54596 -45773 -35196 -23443 -8238 8413 28631 -- -255870
解释
这是我奋斗的地方。 我不太清楚如何解释这些数据。 乍看之下,似乎总是停留在16日或17日的路上,但我不确定这是否容易。 我认为实际的人类对手不太可能会留在12,13和14可能,所以我应该抛出这些对手限制值? 另外,如何修改这个以考虑真实人类对手的变化? 例如,真正的人类可能仅仅基于“感觉”而保持在15,并且也可能基于“感觉”
我怀疑你的结果。 例如,如果对手的目标是19,那么你的数据表明,击败他的最好方法是打到20,但不会通过基本的气味测试。 你确定你没有错误吗? 如果我的对手要争取19或更好,我的策略是避免不惜一切代价地破釜沉舟:坚持13或更高(甚至12?)。 要走20场就要错了 - 不仅仅是小小的差距,而且还有很多。
我怎么知道你的数据不好? 因为你玩的二十一点游戏并不罕见 。 这是经销商在大多数赌场玩的方式:无论其他玩家手中握有什么东西,庄家都可以达到目标,然后停下来。 那个目标是什么? 站在硬17并击中软17.当你摆脱脚本中的错误,它应该确认赌场知道他们的业务。
当我对代码进行以下替换时:
# Replace scoring method.
def score
s = inject(0) { |sum, c| sum + c }
return s if s < 21
n_aces = find_all { |c| c == 11 }.size
while s > 21 and n_aces > 0
s -= 10
n_aces -= 1
end
return s
end
# Replace section of code determining hand outcome.
my_score = my_hand.score
opp_score = opp_hand.score
my_score = 0 if my_score > 21
opp_score = 0 if opp_score > 21
if my_score == opp_score
draw += 1
elsif my_score > opp_score
win += 1
else
lose += 1
end
结果与赌场经销商的行为一致: 17是最佳目标 。
n=10000
opponent_limit
my_limit | 12 13 14 15 16 17 18 19 20 21 net
-------- | -------- -------- -------- -------- -------- -------- -------- -------- -------- -------- --------
12 | -- -843 -1271 -1380 -1503 -1148 -137 1234 3113 6572
13 | 843 -- -642 -1041 -1141 -770 -93 1137 2933 6324
14 | 1271 642 -- -498 -784 -662 93 1097 2977 5945
15 | 1380 1041 498 -- -454 -242 -100 898 2573 5424
16 | 1503 1141 784 454 -- -174 69 928 2146 4895
17 | 1148 770 662 242 174 -- 38 631 1920 4404
18 | 137 93 -93 100 -69 -38 -- 489 1344 3650
19 | -1234 -1137 -1097 -898 -928 -631 -489 -- 735 2560
20 | -3113 -2933 -2977 -2573 -2146 -1920 -1344 -735 -- 1443
21 | -6572 -6324 -5945 -5424 -4895 -4404 -3650 -2560 -1443 --
一些其他的评论 :
目前的设计是不灵活的。 只需要很少的重构,就可以在游戏操作(交易,洗牌,保持运行状态)和玩家决策之间实现清晰的分离。 这将允许您针对彼此测试各种策略。 目前,你的策略被嵌入到所有与游戏操作代码纠结在一起的循环中。 您的实验可以更好地通过设计让您可以随意创建新玩家并制定战略。
两点评论:
看起来没有一个基于“命中限制”的统治策略:
2.你没有提到玩家是否可以看到他们的对手画了多少张牌(我想是这样)。 我希望将这些信息纳入“最佳”战略。 (回答)
由于没有关于其他玩家决定的信息,游戏变得更简单。 但是由于显然没有统治性的“纯粹”策略,所以最优策略将是一个“混合”策略。 也就是说:对于每个得分从12到21的一组概率,您是否应该停止或抽出另一张牌(编辑:对于给定得分,您将需要不同的概率,而对于没有对手的对手,则需要不同的概率)。然后执行策略需要您可以随机选择(根据概率)每次新抽签后是停止还是继续。 然后你可以找到游戏的纳什均衡。
当然,如果你只是问一个比较简单的问题:针对次优球员的最佳赢球策略是什么(例如那些总是停在16,17,18或19的球员),你会问一个完全不同的问题,你将不得不指定与其他玩家相比,你的确切方式是有限的。
以下是关于您收集的数据的一些想法:
要以另一种方式展示您的数据,第一个数字是您的对手的限制,第二组数字是您可以选择并赢得的限制。 带星号的是“winningest”选项:
12: 13, 14, 15, 16*, 17, 18
13: 14, 15, 16*, 17, 18, 19
14: 15, 16, 17*, 18, 19
15: 16, 17*, 18, 19
16: 17, 18*, 19
17: 18*, 19
18: 19*, 20
19: 12, 20*
20: 12*, 13, 14, 15, 16, 17
21: 12*, 13, 14, 15, 16, 17, 18, 19, 20
从中可以看出,如果对手选择随机的“命中限制”选择策略,17或18的命中限制是最安全的选择,因为17和18将击败7/10对手的“命中限制”。
当然,如果你的对手是人类,你不能回复他们自我施加18或19以上的“命中限制”,这样就完全否定了以前的计算。 但我仍然认为这些数字很有用:
我同意,对于任何一手牌,你都可以有把握地相信你的对手将有一个限制,在这之后他们会停止命中,他们会留下来。 如果你能猜到这个限制,你可以根据这个估算选择你自己的极限。
如果你认为他们乐观或者乐于冒险,那么选择一个20的限制 - 长期来说,如果他们的限制高于17,他们就会打败他们。如果你确实有信心,选择一个限制12 - 如果他们的限制在18以上,并且在这里有更频繁的奖金,那将会赢。
如果你认为他们保守或冒险,选择18的限制。如果他们自己在18以下的任何地方,这将会赢。
对于中立的场合,也许想想你的限制会是什么,没有任何外界的影响。 你通常会打到16? 一个17?
总之,你只能猜测你的对手的限制是什么,但如果你猜对了,你可以用这些统计数据长期打败他们。
链接地址: http://www.djcxy.com/p/30695.html上一篇: What is the optimal winning strategy for this modified blackjack game?