Python开发Blackjack游戏时card_addition求和函数计算异常
问题原因
你的点数计算错误来自3个核心问题:
card_addition函数设计缺陷:每次调用时传入历史累计的total值,函数内部又会遍历整副手牌重新累加所有牌,导致旧牌被重复计算,点数随叫牌次数递增虚高。你给出的测试案例中,手牌['ace',2,10,8]算出24点,就是第二次叫牌时传入上次的total=13,重复累加了ace、2、10三张牌的点数导致的。- A牌计算逻辑冗余:先根据当前总和判断A记1还是11,再二次遍历调整的写法,在重复累加的基础上会进一步放大计算误差。
- 代码存在多处语法、缩进错误:包括stand分支误判函数对象而非输入变量、爆点判断缩进错位、初始手牌未计算点数、语句未正确换行等问题,会导致逻辑分支不触发、运行报错。
修正方案
1. 重写无状态点数计算函数
去掉传入历史total的参数设计,每次直接根据当前手牌从头计算总和,从根源避免重复累加问题,同时简化A牌的判断逻辑:
def card_addition(hand): total = 0 ace_count = 0 # 非A牌直接加点数,A先按11计算,同时统计A的数量 for card in hand: if card == "ace": ace_count += 1 total += 11 else: total += card # 只要爆点还有A可以调整,就把A从11改成1(每次减10) while total > 21 and ace_count > 0: total -= 10 ace_count -= 1 return total
2. 修复其他语法、逻辑错误
- 初始发完2张手牌后立刻计算初始点数,不要等第一次叫牌才算
- 修正stand分支判断条件,把
elif hit == "s"改为elif hit_stand == "s" - 调整爆点判断的缩进位置,每次更新玩家点数后立刻判断是否爆点
- 所有调用
card_addition的位置只传入手牌参数,不再传入历史累计值 - 补全庄家回合的点数计算逻辑,修正错位的打印、赋值语句
修正后可运行完整代码
import random cards = ["ace", 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10] user_hand = [] dealer_hand = [] hit_stand = "h" bust = False def hit(hand): hand.append(random.choice(cards)) # 初始发牌 for _ in range(2): user_hand.append(random.choice(cards)) dealer_hand.append(random.choice(cards)) dealer_hand.append("hidden") # 计算初始手牌点数 user_total = card_addition(user_hand) print(f"Your hand is {user_hand}, current total: {user_total}") print(f"Dealer's hand is {dealer_hand}") # 玩家回合 while user_total < 21 and hit_stand == "h": hit_stand = input("Hit or stand ? (h/s)") if hit_stand == "h": hit(user_hand) user_total = card_addition(user_hand) print(f"Your hand is {user_hand} and your total is {user_total}.") elif hit_stand == "s": print("STAND !") # 爆点判断 if user_total > 21: bust = True break # 庄家回合,玩家未爆点才触发 if not bust: dealer_hand.remove("hidden") dealer_total = card_addition(dealer_hand) while dealer_total < 16: hit(dealer_hand) dealer_total = card_addition(dealer_hand) print(f"Dealer hand is {dealer_hand} and the total is {dealer_total}.") # 胜负判断 if user_total > dealer_total: print("You win !") elif dealer_total > user_total: print("Dealer wins !") else: print("Draw !") else: print("BUST !")
逻辑验证
你之前的测试手牌['ace', 2, 10, 8]用修正后的函数计算:
- 先将A按11计算,总和为11+2+10+8=31,共1张A
- 31>21触发调整,把A改为1,总和减10得21,结果正确,不会再出现24的计算错误。
内容的提问来源于stack exchange,提问作者kepperguy
相关产品推荐
相关产品推荐

