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

Python类中self.board被意外覆盖问题排查求助

问题排查与解决:递归井字棋AI原始棋盘被意外覆盖

核心原因确认

你的怀疑完全正确:问题出在c_board对象创建时的浅拷贝而非深拷贝。当你基于原始棋盘生成模拟棋盘时,如果没有对self.field进行深拷贝,模拟棋盘的field会和原始棋盘的field指向同一个内存地址。后续调用fillBoard修改模拟棋盘的field时,实际上修改的是原始棋盘共享的那个数组,最终导致aiPlayer的self.board被意外覆盖。

关键代码问题点分析

假设你的c_board初始化代码类似以下结构:

class c_board:
    def __init__(self, field):
        # 浅拷贝:直接引用传入的field对象
        self.field = field

    def fillBoard(self, pos, player):
        self.field[pos] = player

这种情况下,当你从aiPlayer的self.board.field创建新的c_board实例时,新实例的self.field只是原始field的引用,而非独立副本。递归搜索中修改模拟棋盘的field,会直接同步到原始棋盘的field上。

而随机/顺序走棋模式下没有触发递归模拟,所以不会修改共享的field,因此self.board能保持初始状态。

修复方案

需要在c_board的初始化方法中对field进行深拷贝,确保每个棋盘实例拥有独立的field数组:

方案1:针对列表的手动拷贝

如果field是一维列表:

class c_board:
    def __init__(self, field):
        # 创建一维列表的独立副本
        self.field = field.copy()
        # 或者使用切片语法:self.field = field[:]

如果field是二维列表(比如3x3的井字棋棋盘):

class c_board:
    def __init__(self, field):
        # 逐行拷贝二维列表,生成独立副本
        self.field = [row.copy() for row in field]

方案2:使用copy模块的深拷贝函数

对于更复杂的嵌套结构,推荐使用Python内置的copy模块实现深拷贝:

import copy

class c_board:
    def __init__(self, field):
        self.field = copy.deepcopy(field)

验证方式

修改后,可通过打印内存地址确认拷贝是否独立:

# 打印原始棋盘field的内存地址
print(id(self.board.field))
# 创建模拟棋盘
sim_board = c_board(self.board.field)
# 打印模拟棋盘field的内存地址
print(id(sim_board.field))

如果两个地址不同,说明已经实现了独立拷贝,后续修改模拟棋盘不会再影响原始棋盘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:15:57