Search code examples
pythonclassstore

How do I permanently store data in a class python


I have to create a game of Sokoban in Python and I have defined methods in my Sokoban class to find_player() , complete() , get_steps() and move() . I need to create a restart() method and an undo() method but I don't know how to do that. I can't find a way to store the original board or previous boards. I tried making defining another board in the __init__ but it just updates with self.__board instead of saving the initial board. I've also tried making a list in the __init__ and tried appending each move's "board" to the list but it changes every board in the list. I've attached my code if anyone can help.

class Sokoban:
    """Your code here"""
    def __init__(self, board):
        self.__board = board
        self.__original_board = board
        self.__steps = 0
        self.__last_step = []
        self.__position = (0, 0)

    def restart(self):
        first_board = self.__original[0]
        new_board = []
        for i in range(len(first_board)):
             new_board.append(first_board[i])
        print(self.__original)
        return Sokoban(self.__original_board)

    def undo(self):
        return

  

def main(board):
    game = Sokoban(board)
    message = 'Press w/a/s/d to move, r to restart, or u to undo'
    print(message)
    while not game.complete():
        print(game)
        move = input('Move: ').lower()
        while move not in ('w', 'a', 's', 'd', 'r', 'u'):
            print('Invalid move.', message)
            move = input('Move: ').lower()
        if move == 'r':
            game.restart()
        elif move == 'u':
            game.undo()
        else:
            game.move(move)
    print(game)
    print(f'Game won in {game.get_steps()} steps!')


test_board = [
    ['*', '*', '*', '*', '*', '*', '*', '*'],
    ['*', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
    ['*', 'P', ' ', '#', ' ', ' ', ' ', '*'],
    ['*', '*', '*', '*', '*', ' ', '#', '*'],
    ['*', 'o', ' ', ' ', ' ', ' ', ' ', '*'],
    ['*', ' ', ' ', ' ', ' ', ' ', 'o', '*'],
    ['*', '*', '*', '*', '*', '*', '*', '*']
]
main(test_board)

Solution

  • You'll need to (deep) copy the board list-of-lists if you don't want the same value (all the way up to test_board) to get changed.

    import copy
    
    # ...
    
       def __init__(self, board):
            self.__board = copy.deepcopy(board)
            self.__original_board = copy.deepcopy(board)
    

    Beyond that, maybe .restart() should just reset the game object's state, not return a new object?

        def __init__(self, board):
            self.__original_board = copy.deepcopy(board)
            self.restart()
    
        # ...
    
        def restart(self):
            self.__steps = 0
            self.__last_step = []
            self.__position = (0, 0)
            self.__board = copy.deepcopy(self.__original_board)
    

    That way, a simple game.restart() call will do.