开发Go游戏时list.append()存棋盘状态异常,求解答类相关问题
问题分析与解决
核心原因:可变对象的引用传递
你遇到的问题本质是Python中可变对象的引用机制导致的,和类知识的误解关联不大:
- 二维列表属于可变对象,当执行
ex_boards.append(current_board)时,并没有把当前棋盘的内容复制一份存入列表,而是把指向这个二维列表的内存引用添加到了ex_boards中。 - 后续每次修改
current_board(比如落子更新棋盘),都是在修改同一个内存地址里的内容,而ex_boards里所有元素都是指向这个地址的引用,所以最后所有元素都会显示成最后一次修改后的棋盘状态。
解决方法:保存棋盘的深拷贝
要保存每一步的独立状态,必须在append时创建当前棋盘的深拷贝(因为二维列表是嵌套结构,浅拷贝无法完全复制内层子列表):
import copy # 落子后执行以下代码保存当前棋盘状态 ex_boards.append(copy.deepcopy(current_board))
copy.deepcopy()会递归复制所有嵌套的可变对象,确保每个存入ex_boards的元素都是独立的新列表,后续修改原棋盘不会影响已保存的历史状态。
关于类的注意点
你提到ex_boards定义在Go类下方,如果它是类属性(而非实例属性),会导致所有Go类的实例共享同一个ex_boards列表,可能引发额外的状态混乱。正确的做法是将其定义为实例属性,在类的__init__方法中初始化:
class Go: def __init__(self): # 初始化实例独有的历史棋盘列表 self.ex_boards = [] # 初始化当前棋盘(以19路棋盘为例) self.current_board = [[0 for _ in range(19)] for _ in range(19)] def make_move(self, x, y, player): # 落子逻辑:更新当前棋盘 self.current_board[x][y] = player # 保存深拷贝后的棋盘状态 self.ex_boards.append(copy.deepcopy(self.current_board))
内容的提问来源于stack exchange,提问作者Michal Pielka
相关产品推荐
相关产品推荐

