二十一点(Blackjack)游戏主循环运行次数过多、发牌数量异常问题排查
二十一点游戏代码问题修复说明
核心问题列表
- 全局状态未在每局重置:玩家手牌、庄家手牌、当前局牌堆、手牌映射列表
lists/lists2均定义在主循环外,仅程序启动时初始化一次,重开游戏时会保留上一局的残留数据,导致手牌数量异常、循环重复执行。 - 牌池逻辑错误:每一次发牌都会调用
get_new_shuffled_deck()新建一副完整的洗好的牌,而非每局共用同一副牌,完全不符合21点的发牌规则。 - 玩家手牌清空时机错误:打印初始手牌后直接清空
player_hand,后续计算玩家点数时取值异常。 - 庄家逻辑错误:庄家抽牌过程中每抽一张就判断胜负,应该等庄家抽牌到≥17点停止后再统一结算。
- 缺失A牌点数适配规则:当前A永远按11点计算,没有实现爆牌时自动转1点的规则。
修复后完整代码
import random full_deck = {"Two of clubs": 2, "Three of clubs": 3, "Four of clubs": 4, "Five of clubs": 5, "Six of clubs": 6, "Seven of clubs": 7, "Eight of clubs": 8, "Nine of clubs": 9, "Ten of clubs": 10, "Jack of clubs": 10, "Queen of clubs": 10, "King of clubs": 10, "Ace of clubs": 11, "Two of diamonds": 2, "Three of diamonds": 3, "Four of diamonds": 4, "Five of diamonds": 5, "Six of diamonds": 6, "Seven of diamonds": 7, "Eight of diamonds": 8, "Nine of diamonds": 9, "Ten of diamonds": 10, "Jack of diamonds": 10, "Queen of diamonds": 10, "King of diamonds": 10, "Ace of diamonds": 11, "Two of hearts": 2, "Three of hearts": 3, "Four of hearts": 4, "Five of hearts": 5, "Six of hearts": 6, "Seven of hearts": 7, "Eight of hearts": 8, "Nine of hearts": 9, "Ten of hearts": 10, "Jack of hearts": 10, "Queen of hearts": 10, "King of hearts": 10, "Ace of hearts": 11, "Two of spades": 2, "Three of spades": 3, "Four of spades": 4, "Five of spades": 5, "Six of spades": 6, "Seven of spades": 7, "Eight of spades": 8, "Nine of spades": 9, "Ten of spades": 10, "Jack of spades": 10, "Queen of spades": 10, "King of spades": 10, "Ace of spades": 11, } chips = 7 counter_win = 0 def get_new_shuffled_deck(): deck = list(full_deck.items()) random.shuffle(deck) return deck def get_player_cards(player, cards, amount): for i in range(amount): last_element = cards[-1] player.append(last_element) cards.pop() return player def calculate_hand_value(hand): hand_value = 0 ace_count = 0 for card in hand: hand_value += card[1] if "Ace" in card[0]: ace_count +=1 # 处理A的点数转换 while hand_value >21 and ace_count>0: hand_value -=10 ace_count -=1 return hand_value def calculate_dealer_first_card(hand): return hand[0][1] close = False while not close: # 每局游戏重置所有状态 player_hand = [] dealer_hand = [] current_deck = get_new_shuffled_deck() # 发初始牌 get_player_cards(player_hand, current_deck, 2) get_player_cards(dealer_hand, current_deck, 2) lists = [list(k) for k in player_hand] lists2 = [list(m) for m in dealer_hand] # 投注逻辑 while True: try: player_bet_input = int(input("你想投注多少筹码?")) if player_bet_input < 1: print("你不能投注0筹码") elif player_bet_input > chips: print(f"你的筹码不足,当前剩余筹码:{chips},请减少投注金额") else: if player_bet_input == chips: print("你All in了所有筹码") else: print(f"你投注了{player_bet_input}筹码,当前剩余筹码{chips}") break except: print("请输入合法的数字") print(f"发牌完成,你的手牌是:{lists[0][0]} 和 {lists[1][0]},总点数为{calculate_hand_value(lists)}") print(f"庄家明牌为:{lists2[0][0]},点数为{calculate_dealer_first_card(lists2)}\n") # 玩家操作阶段 player_bust = False player_blackjack = False if calculate_hand_value(player_hand) == 21: print("恭喜你拿到Blackjack!") player_blackjack = True else: while calculate_hand_value(player_hand) < 21: print("你要继续抽牌还是停牌?") print("1 - 抽牌(Hit)") print("2 - 停牌(Stand)\n") answer = int(input("请输入选择(1/2):")) if answer == 1: print("\n你选择了抽牌\n") get_player_cards(player_hand, current_deck, 1) lists = [list(k) for k in player_hand] print(f"你抽到了:{lists[-1][0]},当前手牌:") for card in lists: print(f"- {card[0]}") current_val = calculate_hand_value(lists) print(f"当前手牌总点数:{current_val}\n") if current_val > 21: player_bust = True break elif answer ==2: print("\n你选择了停牌\n") break # 玩家爆牌直接结算 if player_bust: chips -= player_bet_input print("你爆牌了,GAME OVER") print(f"你输掉了{player_bet_input}筹码,当前剩余筹码:{chips}\n") elif player_blackjack: chips += player_bet_input *2 print(f"你赢了!获得{player_bet_input*2}筹码,当前剩余筹码:{chips}\n") else: # 庄家抽牌阶段 print("庄家开始抽牌,直到点数≥17,庄家手牌如下:") for card in lists2: print(f"- {card[0]}") while calculate_hand_value(dealer_hand) <17: get_player_cards(dealer_hand, current_deck, 1) lists2 = [list(m) for m in dealer_hand] print(f"庄家抽到了:{lists2[-1][0]}") dealer_val = calculate_hand_value(dealer_hand) player_val = calculate_hand_value(player_hand) print(f"\n庄家最终手牌总点数:{dealer_val},你的点数:{player_val}") # 结算 if dealer_val >21: print("庄家爆牌,你赢了!") chips += player_bet_input *2 elif dealer_val < player_val: print("你的点数更大,你赢了!") chips += player_bet_input *2 elif dealer_val > player_val: if dealer_val ==21: print("庄家拿到Blackjack,你输了") else: print("庄家点数更大,你输了") chips -= player_bet_input else: print("双方点数相同,平局") print(f"当前剩余筹码:{chips}\n") # 重开询问 if chips <=0: print("你已经没有筹码了,游戏结束") close = True else: question = input("是否再玩一局?(Y/N)").strip().upper() if question != "Y": close = True
内容的提问来源于stack exchange,提问作者Sasoki Siko
相关产品推荐
相关产品推荐

