Home > front end >  How do I permanently store data in a class python
How do I permanently store data in a class python

Time:10-13

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 find_player(self):
        for row in range(len(self.__board)):
            for column in range(len(self.__board[row])):
                if self.__board[row][column] == "P":
                    self.__position = (row, column)
        return self.__position

    def complete(self):
        for row in self.__board:
            for column in row:
                if column == "o":
                    return False
        return True

    def get_steps(self):
        return self.__steps

    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 move(self, direction):
        row, column = self.find_player()[0], self.find_player()[1]
        if direction == "w":
            if self.__board[row - 1][column] == "#" and self.__board[row - 2][column] == "o":
                self.__board[row][column] = " "
                self.__board[row - 1][column] = "P"
                self.__board[row - 2][column] = " "
            elif self.__board[row - 1][column] != "o" and self.__board[row - 1][column] != "*":
                if self.__board[row - 1][column] == "#" and self.__board[row - 2][column] != "o" and self.__board[row - 2][column] != "*":
                    self.__board[row][column] = " "
                    self.__board[row - 1][column] = "P"
                    self.__board[row - 2][column] = "#"
                else:
                    self.__board[row][column] = " "
                    self.__board[row - 1][column] = "P"
            else:
                return self.__board
            self.__last_step.append("w")
        if direction == "a":
            if self.__board[row][column - 1] == "#" and self.__board[row][column - 2] == "o":
                self.__board[row][column] = " "
                self.__board[row][column - 1] = "P"
                self.__board[row][column - 2] = " "
            elif self.__board[row][column - 1] != "o" and self.__board[row][column - 1] != "*":
                if self.__board[row][column - 1] == "#" and self.__board[row][column - 2] != "o" and self.__board[row][column - 2] != "*":
                    self.__board[row][column] = " "
                    self.__board[row][column - 1] = "P"
                    self.__board[row][column - 2] = "#"
                else:
                    self.__board[row][column] = " "
                    self.__board[row][column - 1] = "P"
            else:
                return self.__board
            self.__last_step.append("a")
        if direction == "s":
            if self.__board[row   1][column] == "#" and self.__board[row   2][column] == "o":
                self.__board[row][column] = " "
                self.__board[row   1][column] = "P"
                self.__board[row   2][column] = " "
            elif self.__board[row   1][column] != "o" and self.__board[row   1][column] != "*":
                if self.__board[row   1][column] == "#" and self.__board[row   2][column] != "o" and self.__board[row   2][column] != "*":
                    self.__board[row][column] = " "
                    self.__board[row   1][column] = "P"
                    self.__board[row   2][column] = "#"
                else:
                    self.__board[row][column] = " "
                    self.__board[row   1][column] = "P"
            else:
                return self.__board
            self.__last_step.append("s")
        if direction == "d":
            if self.__board[row][column   1] == "#" and self.__board[row][column   2] == "o":
                self.__board[row][column] = " "
                self.__board[row][column   1] = "P"
                self.__board[row][column   2] = " "
            elif self.__board[row][column   1] != "o" and self.__board[row][column   1] != "*":
                if self.__board[row][column   1] == "#" and self.__board[row][column   2] != "o" and self.__board[row][column   2] != "*":
                    self.__board[row][column] = " "
                    self.__board[row][column   1] = "P"
                    self.__board[row][column   2] = "#"
                else:
                    self.__board[row][column] = " "
                    self.__board[row][column   1] = "P"
            else:
                return self.__board
            self.__last_step.append("d")
        progress = self.__board
        self.__steps  = 1
        return self.__board

    def __str__(self):
        output = ""
        for items in self.__board:
            for i in items:
                output  = i
            output  = "\n"
        return output



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)

CodePudding user response:

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.

CodePudding user response:

May be you can use in-memory databases for store your data for testing.

  • Related