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)
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.