21点,BlackJack是很流行的一款扑克游戏。开局阶段,给玩家发两张牌(都是明牌),给庄家发两张牌(一张明牌,一张暗牌)。之后玩家可以选择要牌或停止。在玩家停止要牌后,庄家必须一直要牌大于16点。
如果玩家的牌大于22点,则玩家“爆牌”输。如果庄家的牌大于22点,则庄家“爆牌”输。如果大家都没有爆牌,那就开始比较大小,来判断庄家胜利还是玩家胜利。
比较特殊的地方在于,A可以是11或者1。以及JQK都是10点。如果开局直接发到【A,10】,【A,J】,【A,Q】,【A,K】则称为直接获得了BlackJack。如果是玩家获得了BlackJack则玩家直接胜利,如果是庄家获得了Black Jack则玩家直接输。
这个游戏玩家的核心是,根据玩家手上的牌,以及庄家露出来的牌,判断是否要牌。那么我这个程序就是计算何时计算。一般的21点游戏中,都是多副扑克牌。因此可以近似认为每一张牌抽到的概率都是一样大的(即假设从无穷多的牌里面抽牌)。
程序分两个部分,第一个部分是计算庄家露出来的牌,及其最后的概率。先贴结果。
第二个部分是根据目前玩家手中牌的和,计算玩家再【要一张牌】的情况下,【获胜或打平】的概率。注意这里是只要一张牌,所以这个概率可能定量是有问题的。结论是玩家手牌大于等于17后就别再要了。
计算21点的代码参考了
Python实现21点扑克牌游戏_索儿呀的博客-CSDN博客_21点扑克牌游戏python
这个程序就是套一个大循环遍历的
第一段代码
Cards = ['','A','2','3','4','5','6','7','8','9','10','J','Q','K']
values = {1:11,2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8,9:9, 10:10, 11:10, 12:10, 13:10}
def compute_total(hand):
"""计算并返回一手牌的点数和"""
result = 0 #初始化点数和为0
numAces = 0 #A的个数
# 计算点数和A的个数
for card in hand:
#print(hand,card)
result += values[card]
if card == 1:
numAces += 1
#如果点数和>21,则尝试把A当做1来计算
# (即减去10),多个A循环减去10,直到点数<=21
while result > 21 and numAces > 0:
result -= 10
numAces -= 1
return result
def Home(house):
home = []
for i in house:
home.append(i)
return home
#看看庄家明一张手牌的情况下,结果是17点,18点,19点,20点,21点和爆牌的概率
houseall = []
for a1 in range(9,10):#这个地方可以设置第一张牌露出来的是哪张
print(Cards[a1],'是第一张牌的情况下:')
for a2 in range(1,14):
house = [a1,a2]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a3 in range(1,14):
house = [a1,a2,a3]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a4 in range(1,14):
house = [a1,a2,a3,a4]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a5 in range(1,14):
house = [a1,a2,a3,a4,a5]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a6 in range(1,14):
house = [a1,a2,a3,a4,a5,a6]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a7 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a8 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7,a8]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a9 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7,a8,a9]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a10 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a11 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
for a12 in range(1,14):
house = [a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12]
if compute_total(house)>16:
fine = compute_total(house)
house.append(fine)
houseall.append(Home(house))
continue
else:
print(house)#经过实验居然最多抽出12张
Iseeall = {17:0,18:0,19:0,20:0,21:0,'large':0}# this is probability
for result in houseall:
changdu = len(result)-2
gailv = (1/13)**changdu
if result[-1]>21:
Iseeall['large']+=gailv
else:
Iseeall[result[-1]]+=gailv
Isone = Iseeall[17]+Iseeall[18]+Iseeall[19]+Iseeall[20]+Iseeall[21]+Iseeall['large']
print(Iseeall)
print(Isone)
第二段代码
house = {'A': {17: 0.1889173, 18: 0.1889173, 19: 0.1889173, 20: 0.1889173, 21: 0.077806189, 'out': 0.166524613},
'2': {17: 0.13980914, 18: 0.13490735, 19: 0.129655433, 20: 0.124026456, 21: 0.117993485, 'out': 0.353608136},
'3': {17: 0.135033988, 18: 0.130482326, 19: 0.125580537, 20: 0.12032862, 21: 0.114699643, 'out': 0.373874885},
'4': {17: 0.130489736, 18: 0.125938074, 19: 0.121386413, 20: 0.116484624, 21: 0.111232707, 'out': 0.394468446},
'5': {17: 0.122251285, 18: 0.122251285, 19: 0.117699624, 20: 0.113147963, 21: 0.108246173, 'out': 0.41640367},
'6': {17: 0.165438177, 18: 0.106266579, 19: 0.106266579, 20: 0.101714918, 21: 0.097163256, 'out': 0.423150492},
'7': {17: 0.368566194, 18: 0.137796963, 19: 0.078625365, 20: 0.078625365, 21: 0.074073704, 'out': 0.262312408},
'8': {17: 0.128566544, 18: 0.359335775, 19: 0.128566544, 20: 0.069394947, 21: 0.069394947, 'out': 0.244741242},
'9': {17: 0.119995441, 18: 0.119995441, 19: 0.350764672, 20: 0.119995441, 21: 0.060823844, 'out': 0.228425159},
'10': {17: 0.1207097, 18: 0.1207097, 19: 0.1207097, 20: 0.3707097, 21: 0.037376367, 'out': 0.229784833},
'J': {17: 0.1207097, 18: 0.1207097, 19: 0.1207097, 20: 0.3707097, 21: 0.037376367, 'out': 0.229784833},
'Q': {17: 0.1207097, 18: 0.1207097, 19: 0.1207097, 20: 0.3707097, 21: 0.037376367, 'out': 0.229784833},
'K': {17: 0.1207097, 18: 0.1207097, 19: 0.1207097, 20: 0.3707097, 21: 0.037376367, 'out': 0.229784833}}
Cards = ['','A','2','3','4','5','6','7','8','9','10','J','Q','K']
values = {1:1,2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8,9:9, 10:10, 11:10, 12:10, 13:10}
def compute_total(hand):
"""计算并返回一手牌的点数和"""
result = 0 #初始化点数和为0
numAces = 0 #A的个数
# 计算点数和A的个数
for card in hand:
#print(hand,card)
result += values[card]
if card == 1:
numAces += 1
#如果点数和>21,则尝试把A当做1来计算
# (即减去10),多个A循环减去10,直到点数<=21
while result > 21 and numAces > 0:
result -= 10
numAces -= 1
return result
#我想算的是,如果我要牌之后赢的概率大于我要牌之前赢的概率,那就得要
def PlayerWin(mynum,houseCard):
if mynum >21:
return 0
if mynum <17:
return house[houseCard]['out']
if mynum ==17:
return house[houseCard]['out']+house[houseCard][17]
if mynum ==18:
return house[houseCard]['out']+house[houseCard][17]+house[houseCard][18]
if mynum ==19:
return house[houseCard]['out']+house[houseCard][17]+house[houseCard][18]+house[houseCard][19]
if mynum ==20:
return 1-house[houseCard][21]
if mynum ==21:
return 1
for a1 in range(8,9):
print('\n')
print('手上的牌和是',a1,'的情况下:')
for house1 in range(1,14):
print('庄家手上的牌是',Cards[house1])
print('不要牌赢的概率是',PlayerWin(a1,Cards[house1]))
yaopaiyin = 0
for nextcard in range(1,14):
nextsum = a1 + values[nextcard]
yaopaiyin +=PlayerWin(nextsum,Cards[house1])/13
print('要牌赢的概率是',yaopaiyin)
print()