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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Python中为7x7板制作撤销功能相关的知识,希望对你有一定的参考价值。

我目前正在尝试编写一款名为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时,您将添加对原始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]

或更热情地:

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

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

另一答案

要创建电路板副本列表,您需要为电路板类实现深度复制方法。否则,你所做的只是一遍又一遍地复制相同的指针。 Python通过引用传递,这是您的问题的根源。实现一种新方法,该方法创建一个与当前电路板具有相同字段的新电路板,并从该方法返回指向该电路板的指针。我建议阅读一些浅浅的副本。你可以找到更多细节here

以上是关于在Python中为7x7板制作撤销功能的主要内容,如果未能解决你的问题,请参考以下文章

python 用于在终端中运行的sublime text 3的简单代码片段制作工具

记事本

PPAPI+Skia实现的涂鸦板

有没有办法在 Python 中为具有多个分类的随机森林制作部分依赖图(使用 scikit-learn)?

如何在pyqt5中为一个小部件制作一个清晰的板子功能

如何找到故事板制作的视图控制器实例