You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

德州扑克(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()

关键修复点

  1. 移除重复状态显示:删除了每轮下注后的display_game_state调用,仅在公共牌更新后显示一次状态,符合预期流程。
  2. 标准化回合流程:将下注逻辑提取为handle_betting_round函数,避免代码冗余,同时确保每个公共牌阶段后都触发输入提示。
  3. 修复手牌评估bug:完善了evaluate_hand中顺子判断的变量定义逻辑,避免因sorted_values长度不足导致的报错,同时统一用数值比较提升准确性。
  4. 重置轮次状态:每轮开始时重新初始化牌组、底池和公共牌,避免多轮游戏时的状态污染。
  5. 增加输入校验:对玩家下注金额做合法性检查,避免非法输入导致程序崩溃。

内容的提问来源于stack exchange,提问作者Aansh Patel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 05:50:54