在 Python 中为 7x7 板制作撤消功能

Making an undo function for a 7x7 board in Python

我目前正在尝试编写一款名为 Pah Tum 的游戏。游戏涉及一块 7x7 的棋盘。对于董事会,我刚刚创建了一个列表,其中包含 7 个列表,每个列表包含 7 个元素,基本上我只是将每一行制作成一个列表并将它们合并成一个大列表:

board = [[0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0]]

游戏应该有撤销功能,让玩家可以后退一步。我想我可以将整个板附加到一个单独的列表中,然后用它返回一个步骤。

        if input == 'u' or input == 'U':
            board = board_list[-1]
            del board_list[-1]

直到这里它起作用,但由于某些原因,board_list(我将当前板附加到的列表)总是作为一个整体更新,这意味着每个元素都会改变并成为新的板。

例如。如果我有

#board = [[0, 'B'], [0, 0]]
board_list.append(board)
.
.
.
#board = [[0, 'B'], [0, 'B']]
board_list.append(board)

在第一次追加之后我会得到

board_list = [[[0, 'B'], [0, 0]]]

第二个留给我

board_list = [[[0, 'B'], [0, 'B']], [[0, 'B'], [0, 'B']]]

我不知道为什么会这样。我搜索了类似的问题,但我只看到画布的撤消功能,我不确定我是否可以将它们用于这种情况。

当您将 board 附加到 board_list 时,您将 reference 添加到 original board。也许更好的选择是在移动时为更改的单元格添加以前的状态:

moves.append([x, y, board[x][y]])

然后当您撤消时,您会重新应用该状态:

undo_move = moves[-1]
board[undo_move[0]][undo_move[1]] = undo_move[2]
del moves[-1]

或更 Python 的:

x, y, board[x][y] = moves.pop()

或者,您可以复制整个图板并将其存储在列表中。

为了创建电路板副本列表,您需要为电路板实施深度复制方法 class。否则,您所做的就是一遍又一遍地复制同一个指针。 Python 通过引用传递,这就是问题的根源。 实施一种新方法,该方法创建一个新板,其字段与您当前的板相同,并且 return 从该方法指向该板的指针。 我建议阅读一些关于浅拷贝和深拷贝的内容。您可以找到更多详细信息 here.