德州扑克(Texas Hold'em)游戏输出重复及输入提示缺失问题
问题分析与修复方案
问题1:输出内容连续重复显示
当前代码在每轮下注完成后额外调用了一次display_game_state,导致游戏状态被重复打印。比如翻牌后显示状态,玩家下注后又再次显示相同的公共牌状态,造成冗余输出。
问题2:回合流程逻辑混乱(输入触发异常)
代码里的回合流程没有严格遵循德州扑克的标准阶段(翻牌→下注、转牌→下注、河牌→下注),且全局变量未做轮次重置,可能导致多轮游戏时状态异常。另外,evaluate_hand函数存在潜在报错风险:当sorted_values长度不足5时,straight_values_int未定义就被使用,会触发NameError。
修复后的完整代码
import random # Initialize deck and shuffle suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades'] values = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Jack', 'Queen', 'King', 'Ace'] # Initialize players players = [{'name': f'Player {i + 1}', 'hand': [], 'chips': 1000, 'money': 1000} for i in range(2)] # Deal a hand of cards def deal_hand(deck, num_cards=2): return [deck.pop() for _ in range(num_cards)] # Deal a specified number of community cards def deal_community_cards(deck, num_cards): return [deck.pop() for _ in range(num_cards)] # Display the community cards def display_community(community_cards): print("\nCommunity cards:") if community_cards: for card in community_cards: print(f" {card['value']} of {card['suit']}") else: print(" No community cards yet.") # Determine the winner(s) of the game def determine_winner(players, community_cards): for player in players: player['best_hand'] = evaluate_hand(player['hand'], community_cards) best_hand_value = max(player['best_hand'][0] for player in players) winners = [player for player in players if player['best_hand'][0] == best_hand_value] if len(winners) > 1: for i in range(5): max_kicker_value = max(player['best_hand'][1][i] for player in winners) winners = [player for player in winners if player['best_hand'][1][i] == max_kicker_value] if len(winners) == 1: break elif len(winners) == 0: raise ValueError("No valid winners") return winners # Evaluate a player's hand def evaluate_hand(player_hand, community_cards): all_cards = player_hand + community_cards values_map = {'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10, 'Jack': 11, 'Queen': 12, 'King': 13, 'Ace': 14} suits = set(card['suit'] for card in all_cards) values_count = {value: sum(1 for card in all_cards if card['value'] == value) for value in values_map} sorted_values = sorted(values_count.keys(), key=lambda x: (values_count[x], values_map[x]), reverse=True) flush = len(suits) == 1 straight = False straight_values_int = [] if len(sorted_values) >= 5: straight_values = sorted_values[:5] straight_values_int = [values_map[value] for value in straight_values] # 检查常规顺子 if straight_values_int[-1] - straight_values_int[0] == 4: straight = True # 检查A-2-3-4-5的特殊顺子 elif straight_values_int == [14,5,4,3,2]: straight = True straight_values_int = [2,3,4,5,14] # 同花顺 if straight and flush: return (9, straight_values_int) # 四条 if 4 in values_count.values(): quad_value = next(key for key, val in values_count.items() if val ==4) kicker = [v for v in sorted_values if v != quad_value][0] return (8, [values_map[quad_value]]*4 + [values_map[kicker]]) # 葫芦 if 3 in values_count.values() and 2 in values_count.values(): three_value = next(key for key, val in values_count.items() if val ==3) pair_value = next(key for key, val in values_count.items() if val ==2) return (7, [values_map[three_value]]*3 + [values_map[pair_value]]*2) # 同花 if flush: return (6, [values_map[v] for v in sorted_values[:5]]) # 顺子 if straight: return (5, straight_values_int) # 三条 if 3 in values_count.values(): three_value = next(key for key, val in values_count.items() if val ==3) kickers = [values_map[v] for v in sorted_values if v != three_value][:2] return (4, [values_map[three_value]]*3 + kickers) # 两对 if list(values_count.values()).count(2) ==2: pairs = sorted([key for key, val in values_count.items() if val ==2], key=lambda x: values_map[x], reverse=True) kicker = [values_map[v] for v in sorted_values if v not in pairs][0] return (3, [values_map[p] for p in pairs] + [kicker]) # 一对 if 2 in values_count.values(): pair_value = next(key for key, val in values_count.items() if val ==2) kickers = [values_map[v] for v in sorted_values if v != pair_value][:3] return (2, [values_map[pair_value]]*2 + kickers) # 高牌 return (1, [values_map[v] for v in sorted_values[:5]]) # Display the current state of the game def display_game_state(players, community_cards, pot, reveal_player=0, game_over=False): print("\n" + "-"*50) for i, player in enumerate(players): print(f"\n{player['name']}'s hand:") if i == reveal_player or game_over: for card in player['hand']: print(f" {card['value']} of {card['suit']}") else: print(" ??? ???") print(f" Balance: {player['money']}") display_community(community_cards) print(f"\nPot: {pot}") print("-"*50 + "\n") # Simulate a single turn of the game def play_turn(): # 重置每轮的全局状态 global players deck = [{'suit': suit, 'value': value} for suit in suits for value in values] random.shuffle(deck) pot = 0 community_cards = [] # 盲注阶段 for player in players: player['hand'] = deal_hand(deck) # 小盲/大盲简化为每人20 player['money'] -=20 pot +=20 # 翻牌阶段(3张公共牌) community_cards.extend(deal_community_cards(deck,3)) display_game_state(players, community_cards, pot) # 下注流程 pot = handle_betting_round(players, pot) # 转牌阶段(第4张公共牌) community_cards.extend(deal_community_cards(deck,1)) display_game_state(players, community_cards, pot) # 下注流程 pot = handle_betting_round(players, pot) # 河牌阶段(第5张公共牌) community_cards.extend(deal_community_cards(deck,1)) display_game_state(players, community_cards, pot) # 下注流程 pot = handle_betting_round(players, pot) # 摊牌阶段 display_game_state(players, community_cards, pot, game_over=True) winners = determine_winner(players, community_cards) if len(winners) ==1: winners[0]['money'] += pot print(f"Winner: {winners[0]['name']} takes the pot of {pot}!") else: split_pot = pot // len(winners) for winner in winners: winner['money'] += split_pot print(f"It's a tie! Each winner gets {split_pot} from the pot.") # 通用下注流程函数,避免重复代码 def handle_betting_round(players, pot): # Player 1下注 while True: try: bet_amount = int(input(f"{players[0]['name']}, enter your bet amount (current balance: {players[0]['money']}): ")) if bet_amount <0 or bet_amount > players[0]['money']: print("Invalid bet amount! Please enter a value between 0 and your balance.") continue break except ValueError: print("Please enter a valid number.") players[0]['money'] -= bet_amount pot += bet_amount # Player 2固定下注20(可扩展为AI逻辑) player2_bet =20 if player2_bet > players[1]['money']: player2_bet = players[1]['money'] players[1]['money'] -= player2_bet pot += player2_bet print(f"{players[1]['name']} bets {player2_bet}") return pot # Run a single turn of the game play_turn()
关键修复点
- 移除重复状态显示:删除了每轮下注后的
display_game_state调用,仅在公共牌更新后显示一次状态,符合预期流程。 - 标准化回合流程:将下注逻辑提取为
handle_betting_round函数,避免代码冗余,同时确保每个公共牌阶段后都触发输入提示。 - 修复手牌评估bug:完善了
evaluate_hand中顺子判断的变量定义逻辑,避免因sorted_values长度不足导致的报错,同时统一用数值比较提升准确性。 - 重置轮次状态:每轮开始时重新初始化牌组、底池和公共牌,避免多轮游戏时的状态污染。
- 增加输入校验:对玩家下注金额做合法性检查,避免非法输入导致程序崩溃。
内容的提问来源于stack exchange,提问作者Aansh Patel
相关产品推荐
相关产品推荐

