面向对象Bingo游戏BUG排查:猜对或耗尽次数后无法终止
解决Bingo数字猜谜游戏的终止BUG
问题描述
尝试用面向对象开发Bingo数字猜谜游戏,但存在BUG:当有玩家猜对数字或所有玩家耗尽猜测次数时,游戏无法终止。运行时玩家猜对后,游戏仍会继续让其他玩家进行猜测。
原代码及运行输出如下:
import random class Game: player_list = [] def __init__(self): self.rand_num = random.randint(1, 20) self.name = input("Enter your name: ") self.guess_left = 3 self.win_stats = False Game.player_list.append(self) def check_answer(self): answer = int(input(f'{self.name} guess a number: ')) if answer > self.rand_num: print("Guess lower") elif answer < self.rand_num: print("Guess higher") elif answer == self.rand_num: print("Bingo!") self.win_stats = True self.minus_guess_left() print(f"{self.name} you have {self.guess_left} guesses left") def minus_guess_left(self): self.guess_left -= 1 def has_guess_left(self): if self.guess_left > 0: return True return False def has_won(self): return self.win_stats @classmethod def game_has_winner(cls): if any(player.has_won() is True for player in cls.player_list): return True return False class GameController: def __init__(self): while True: for player in Game.player_list: if not player.has_won(): player.check_answer() if Game.game_has_winner(): break if __name__ == "__main__": while True: order = input("What is your order: ") if order == 'add': Game() elif order == 'start': GameController() elif order == 'exit': break
运行输出:
What is your order: add Enter your name: alex What is your order: add Enter your name: john What is your order: start alex guess a number: 10 Guess higher alex you have 2 guesses left john guess a number: 10 Guess higher john you have 2 guesses left alex guess a number: 15 Bingo! alex you have 1 guesses left john guess a number: 15 Guess lower john you have 1 guesses left What is your order:
问题分析
- 原
GameController逻辑是先让所有未获胜玩家完成一轮猜测,才检查是否有赢家,导致玩家猜对后,本轮剩余玩家仍会继续操作。 - 缺少所有玩家耗尽猜测次数的终止判断,即使没人猜对,游戏也会无限循环。
修复后的代码
import random class Game: player_list = [] def __init__(self): self.rand_num = random.randint(1, 20) self.name = input("Enter your name: ") self.guess_left = 3 self.win_stats = False Game.player_list.append(self) def check_answer(self): answer = int(input(f'{self.name} guess a number: ')) if answer > self.rand_num: print("Guess lower") elif answer < self.rand_num: print("Guess higher") elif answer == self.rand_num: print("Bingo!") self.win_stats = True self.minus_guess_left() print(f"{self.name} you have {self.guess_left} guesses left") def minus_guess_left(self): self.guess_left -= 1 def has_guess_left(self): return self.guess_left > 0 def has_won(self): return self.win_stats @classmethod def game_has_winner(cls): return any(player.has_won() for player in cls.player_list) @classmethod def all_players_no_guesses(cls): return all(not player.has_guess_left() for player in cls.player_list) class GameController: def __init__(self): while True: game_should_end = False for player in Game.player_list: # 只让未获胜且还有次数的玩家猜 if not player.has_won() and player.has_guess_left(): player.check_answer() # 每次玩家操作后立刻检查终止条件 if Game.game_has_winner() or Game.all_players_no_guesses(): game_should_end = True break if game_should_end or Game.all_players_no_guesses(): break if __name__ == "__main__": while True: order = input("What is your order: ") if order == 'add': Game() elif order == 'start': GameController() elif order == 'exit': break
改动说明
- 给
Game类新增类方法all_players_no_guesses,用于判断是否所有玩家都没有剩余猜测次数。 - 简化了
has_guess_left和game_has_winner的返回逻辑,让代码更简洁。 - 修改
GameController的循环逻辑:- 仅允许未获胜且还有猜测次数的玩家进行操作。
- 每个玩家完成一次猜测后,立刻检查是否有玩家获胜或所有玩家都没次数,满足任一条件就终止游戏。
- 每轮遍历结束后,额外兜底检查终止条件,避免遗漏。
这样修改后,只要有玩家猜对,游戏会立刻终止;当所有玩家都用完猜测次数时,游戏也会自动结束。
内容的提问来源于stack exchange,提问作者Sepehr_Sae
相关产品推荐
相关产品推荐

