Python游戏循环异常:第三次迭代后提前终止问题排查
问题背景
项目基于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语句后,程序无法跳回对局循环,直接提前终止。
关键问题分析
缺少全局游戏循环:现有的
while match_going and PlayerTurn只是单局游戏的循环,没有外层循环包裹整个多轮游戏流程。当第一局结束后,即使重置了match_going和PlayerTurn,也没有逻辑触发重新进入对局循环——程序执行到继续游戏的代码后就走到了文件末尾,自然终止。Dealer回合逻辑混乱:在Dealer的抽牌循环(
while dealer_score < 16)中,每抽一张牌就立刻判断胜负并修改match_going,这会导致Dealer还没完成所有必须的抽牌动作就提前终止对局。这种提前修改状态的行为可能引发后续循环的异常。变量作用域隐患:如果
match_going和PlayerTurn是局部变量,在reset()或startMatch()中修改的可能不是全局的状态变量,导致重置后循环条件依然不满足。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

