pythonlistappendundo

Making an undo function for a 7x7 board in Python


I am currently trying to program a game called Pah Tum. The game involves a board that is 7x7. For the board I just created a list with 7 lists containing 7 elements each, basically I just made each row into a list and merged them into a big list:

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]]

The game should have an undo function, which enables the player to go back one step. I thought I could just append the whole board into a seperate list and use that to go back a step.

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

until here it works, but for some reason the board_list (the list I'm appending the current board to) always updates as a whole, meaning each element changes and becomes the new board.

eg. if I have

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

after the first append I'd get

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

and the second one leaves me with

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

I have no idea why this happens. I searched for similar questions but I only see undo functions for canvases and I'm not sure if I can use them for this scenario.


Solution

  • When you append board to board_list you're adding a reference to the original board. Perhaps a better option would be to add the previous state for the changed cell when you make a move:

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

    And then when you undo you reapply that state:

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

    Or more pythonically:

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

    Alternatively, you could make a copy of the entire board and store that in the list instead.