Python井字棋循环调用函数时字典无法更新原因排查
问题根因
所有需要跨函数调用保留的状态都被定义在了user_input()函数内部:
- 每次调用函数时,都会重新执行字典初始化逻辑,生成一个值为1-9的全新
dic,上一次调用中对字典的修改会随着函数执行结束、局部变量销毁直接丢失,不可能留存到下一次调用。 - 同理,
count = 2写在函数内部会导致回合数永远重置为2,永远判定当前玩家是X,不会切换到O;函数末尾手动写flag = False也会直接覆盖之前的落子有效标记。 - 额外语法问题:代码里拼接棋盘字符串时直接硬敲了回车,没有用
\n转义,运行时会直接报语法错误。
修复方法
选以下任意一种实现即可:
方法1:把状态初始化移到函数外,作为参数传入
把棋盘字典、回合计数放到while循环外层初始化,函数只负责处理单次输入逻辑,接收当前状态、返回更新后的状态:
def user_input(dic, count): line = "----------" x1 = f'{dic["empty_1"]} | {dic["empty_2"]} | {dic["empty_3"]}' x2 = f'{dic["empty_4"]} | {dic["empty_5"]} | {dic["empty_6"]}' x3 = f'{dic["empty_7"]} | {dic["empty_8"]} | {dic["empty_9"]}' playground = f"{x1}\n{line}\n{x2}\n{line}\n{x3}\n" check = "123456789" player_1, player_2 = "X", "O" flag = False print(playground) decision = input("Enter field-number: ").strip() current_player = player_1 if count % 2 == 0 else player_2 field = f"empty_{decision}" # 增加输入合法性校验,避免触发KeyError if field not in dic: print("Please enter a valid number between 1 and 9!\n") return dic, count, flag if dic[field] in check: dic[field] = current_player flag = True count += 1 else: print("Can´t place there!\n") return dic, count, flag # 循环外初始化需要持久保存的状态 if __name__ == "__main__": # 初始化棋盘 dic = {f"empty_{i}": str(i) for i in range(1, 10)} count = 2 # 替换成自定义循环终止条件,比如未分胜负、棋盘未填满时继续 while True: dic, count, valid_move = user_input(dic, count) # 在此处补充胜负判断、平局判断逻辑即可
方法2:用类封装游戏状态
把所有游戏相关的状态和逻辑收拢到类中,棋盘、回合数作为实例属性,只会在类实例化时初始化一次:
class TicTacToe: def __init__(self): # 初始化逻辑仅在实例化时执行一次,不会重复重置 self.dic = {f"empty_{i}": str(i) for i in range(1, 10)} self.count = 2 self.player = ("X", "O") self.line = "----------" def print_board(self): x1 = f'{self.dic["empty_1"]} | {self.dic["empty_2"]} | {self.dic["empty_3"]}' x2 = f'{self.dic["empty_4"]} | {self.dic["empty_5"]} | {self.dic["empty_6"]}' x3 = f'{self.dic["empty_7"]} | {self.dic["empty_8"]} | {self.dic["empty_9"]}' print(f"{x1}\n{self.line}\n{x2}\n{self.line}\n{x3}\n") def user_input(self): self.print_board() check = set("123456789") flag = False decision = input("Enter field-number: ").strip() current_player = self.player[self.count % 2] field = f"empty_{decision}" if field not in self.dic: print("Please enter a valid number between 1 and 9!\n") return flag if self.dic[field] in check: self.dic[field] = current_player flag = True self.count += 1 else: print("Can´t place there!\n") return flag # 启动游戏 if __name__ == "__main__": game = TicTacToe() while True: valid = game.user_input() # 补充胜负、平局判定逻辑
内容的提问来源于stack exchange,提问作者user18917708
相关产品推荐
相关产品推荐

