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

Python游戏循环异常:第三次迭代后提前终止问题排查

游戏循环提前终止Bug分析求助

问题背景

项目基于logic.py和card.py两个核心文件,游戏对局循环依赖match_going和PlayerTurn两个布尔变量控制。在用户选择继续游戏的流程中,已将这两个变量重置为True,但程序在第三次运行startMatch()后直接终止,无法回到logic.py第53行的对局while循环。

核心代码片段

对局循环逻辑

# This code is ran before the code above 
while match_going and PlayerTurn:
    # Grab input inside the loop so it asks every time
    player_input = input("Stand or Hit:\n").lower()

    if player_input == "hit":
        deck.draw_card(Player_Hand,"Player")
        player_score = deck.ScoreCard(Player_Hand)
        print("Player's Hand Score Currently:\n", player_score)

        # Check if they busted
        if player_score > 21:
            print("Past 21! You busted...")
            PlayerTurn = False
            match_going = False


    elif player_input == "stand":
        PlayerTurn = False
        print("**Dealer's Turn**")
        deck.draw_card(Dealer_Hand,"Dealer")
        dealer_score = deck.ScoreCard(Dealer_Hand)
        # Dealer must hit until they beat 16 or land on 16
        while dealer_score < 16:
            deck.draw_card(Dealer_Hand,"Dealer")
            dealer_score = deck.ScoreCard(Dealer_Hand)
            if dealer_score == 16 and player_score > dealer_score:
                print("You win!")
                match_going = endMatch()
                WinCounter += 1
            if dealer_score == 16 and dealer_score > player_score:
                print("Dealer Wins!")
                match_going = endMatch()
            if dealer_score >= player_score and dealer_score <= 21:
                print("Dealer wins!")
                match_going = endMatch()
            elif dealer_score < player_score and player_score <= 21:
                print("You win!")
                match_going = endMatch()
                WinCounter += 1
            elif dealer_score > 21:
                print("Dealer bust you win!")
                match_going = endMatch()
                WinCounter += 1
            elif dealer_score == player_score:
                print("Match was a draw!")
                match_going = endMatch() # Ends game loop

继续游戏逻辑

print("Current Win Streak:",WinCounter)
user_continue_match = str(input("\nContinue Playing? Y/N").upper())
if user_continue_match == "Y":
    reset()
    match_going = True
    PlayerTurn = True
    startMatch()
    player_score = deck.ScoreCard(Player_Hand)
    dealer_score = deck.ScoreCard(Dealer_Hand) 
if user_continue_match == "N":
    print("Your Are Safe To Close Program")
# This runs in the same file after match_going & PlayerTurn has been set to false

预期与实际现象

预期结果:程序持续运行直到用户输入"N",每次选择继续后都能回到logic.py第53行的对局循环。
实际现象:执行完第103行的继续游戏if语句后,程序无法跳回对局循环,直接提前终止。

关键问题分析

  1. 缺少全局游戏循环:现有的while match_going and PlayerTurn只是单局游戏的循环,没有外层循环包裹整个多轮游戏流程。当第一局结束后,即使重置了match_going和PlayerTurn,也没有逻辑触发重新进入对局循环——程序执行到继续游戏的代码后就走到了文件末尾,自然终止。

  2. Dealer回合逻辑混乱:在Dealer的抽牌循环(while dealer_score < 16)中,每抽一张牌就立刻判断胜负并修改match_going,这会导致Dealer还没完成所有必须的抽牌动作就提前终止对局。这种提前修改状态的行为可能引发后续循环的异常。

  3. 变量作用域隐患:如果match_going和PlayerTurn是局部变量,在reset()或startMatch()中修改的可能不是全局的状态变量,导致重置后循环条件依然不满足。

  4. endMatch()返回值不确定:match_going = endMatch()中,如果endMatch()没有返回正确的布尔值(比如应该返回False结束单局),可能导致后续重置变量时出现状态异常。

修复建议

  • 添加外层全局循环:将整个游戏流程(初始化、对局循环、继续游戏判断)放到一个外层循环中,确保用户选择继续时能重新启动对局:
while True:
    # 初始化单局状态
    match_going = True
    PlayerTurn = True
    startMatch()
    
    # 单局对局循环
    while match_going and PlayerTurn:
        # 原对局逻辑代码...
    
    # 胜负展示与继续游戏判断
    print("Current Win Streak:",WinCounter)
    user_continue_match = input("\nContinue Playing? Y/N").upper()
    if user_continue_match == "N":
        print("Your Are Safe To Close Program")
        break
    # 选择继续时重置状态
    reset()
  • 重构Dealer回合逻辑:先完成Dealer所有必须的抽牌动作,再一次性判断胜负,避免提前修改match_going:
elif player_input == "stand":
    PlayerTurn = False
    print("**Dealer's Turn**")
    deck.draw_card(Dealer_Hand,"Dealer")
    dealer_score = deck.ScoreCard(Dealer_Hand)
    
    # 先完成所有抽牌动作
    while dealer_score < 16:
        deck.draw_card(Dealer_Hand,"Dealer")
        dealer_score = deck.ScoreCard(Dealer_Hand)
    
    # 抽牌结束后统一判断胜负
    if dealer_score > 21:
        print("Dealer bust you win!")
        WinCounter += 1
    elif dealer_score > player_score:
        print("Dealer wins!")
    elif dealer_score < player_score:
        print("You win!")
        WinCounter += 1
    else:
        print("Match was a draw!")
    match_going = endMatch()
  • 确认变量作用域:如果match_going、PlayerTurn是全局变量,在修改时确保使用global关键字(如果在函数内修改);或者改用类来封装游戏状态,避免作用域问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 17:17:26