在 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.
我目前正在尝试编写一款名为 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.