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()