def test_check_elem_action_seq(): wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_01.txt") # first test answer = check_elem_action_seq(wh, ['Right', 'Right', 'Down']) expected_answer = '#### \n# .# \n# ###\n#* #\n# $@#\n# ###\n#### ' fcn = test_check_elem_action_seq print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ') print(expected_answer) print('But, received ') print(answer) # second test answer = check_elem_action_seq(wh, ['Right', 'Right', 'Right']) expected_answer = 'Impossible' fcn = test_check_elem_action_seq print('<< Second test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ') print(expected_answer) print('But, received ') print(answer)
def test_taboo_cells(n): problem_file = "./warehouses/warehouse_%s.txt" % str(n) print("Testing:", problem_file) wh = Warehouse() wh.load_warehouse(problem_file) answer = taboo_cells(wh) print(answer)
def test_weighted(n): problem_file = "./warehouses/warehouse_%s.txt" % str(n) print(n, ": ", end="") wh = Warehouse() wh.load_warehouse(problem_file) time1 = time.time() solve_weighted_sokoban_elem(wh, [1 for box in wh.boxes]) print('{:06.3f}s'.format(time.time() - time1))
def test_elem(n): problem_file = "./warehouses/warehouse_%s.txt" % str(n) print(n, ": ", end="") wh = Warehouse() wh.load_warehouse(problem_file) time1 = time.time() solve_sokoban_elem(wh) print('{:06.3f}s'.format(time.time() - time1))
def test(n): problem_file = "./warehouses/warehouse_%s.txt" % str(n) print("Testing:", problem_file) wh = Warehouse() wh.load_warehouse(problem_file) time1 = time.time() answer = solve_sokoban_elem(wh) print(time.time() - time1) print(answer)
def print_taboo_spaces(warehouse_id): """ Calculates the taboo cells for the given warehouse id and prints them @param warehouse_id: ID of warehouse to load taboo spaces for """ problem_file = "./warehouses/warehouse_{:02d}.txt".format(warehouse_id) wh = Warehouse() wh.load_warehouse(problem_file) print(wh) print("TABOO CELLS: ") taboo = taboo_cells(wh) print(taboo)
def test_taboo_cells(): wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_01.txt") expected_answer = '#### \n#X # \n# ###\n# X#\n# X#\n#XX###\n#### ' answer = taboo_cells(wh) fcn = test_taboo_cells print('<< Testing {} >>'.format(fcn.__name__)) if answer==expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ');print(expected_answer) print('But, received ');print(answer)
def warehouse_solution(number): result = None average_time = 0 problem_file = "./warehouses/warehouse" warehouse_problem = "./warehouses/warehouse_{:02d}.txt".format(number) wh = Warehouse() wh.load_warehouse(warehouse_problem) solution = solve_sokoban_elem(wh) print(solution) with open("./Warehouse_solutions/warehouse_{:02d}.txt".format(number), "w+") as file: file.write("The solution for warehouse {} is {}".format( number, solution)) file.close()
def tester(num): problem_file = "./warehouses/warehouse_{:02d}.txt".format(num) print('Warehouse number:{0}'.format(num)) wh = Warehouse() wh.load_warehouse(problem_file) t0 = time.time() result = solve_sokoban_macro(wh) t1 = time.time() print('Macro Solver took {:.6f} seconds'.format(t1 - t0)) wh = Warehouse() wh.load_warehouse(problem_file) t0 = time.time() result = solve_sokoban_elem(wh) t1 = time.time() print('Elem Solver took {:.6f} seconds\n'.format(t1 - t0))
def test_solve_weighted_sokoban_elem(): wh = Warehouse() wh.load_warehouse( "./warehouses/cab320_warehouse_8.txt") # first test answer=solve_weighted_sokoban_elem(wh, [1,9]) expected_answer = ['Up', 'Left', 'Up', 'Left', 'Left', 'Down', 'Left', 'Down', 'Right', 'Right', 'Right', 'Up', 'Left', 'Up', 'Left', 'Down', 'Right', 'Down', 'Left', 'Right', 'Right', 'Right', 'Right', 'Right', 'Right', 'Right'] fcn = test_solve_weighted_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer==expected_answer: print(fcn.__name__, ' answer as expected! :-)\n') else: print(fcn.__name__, ' different answer! :-(\n') print('Expected ');print(expected_answer) print('But, received ');print(answer) print('Your answer is different but it might still be correct') print('Check that you pushed the right box onto the left target!')
def test_solve_sokoban_elem(): puzzle_t1 = '#######\n#@ $. #\n#######' wh = Warehouse() wh.extract_locations(puzzle_t1.split(sep='\n')) # first test answer = solve_sokoban_elem(wh) expected_answer = ['Right', 'Right'] fcn = test_solve_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ') print(expected_answer) print('But, received ') print(answer) # second test puzzle_t2 = '#######\n#@ $ #.#\n#######' wh = Warehouse() wh.extract_locations(puzzle_t2.split(sep='\n')) answer = solve_sokoban_elem(wh) expected_answer = ['Impossible'] print('<< Second test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ') print(expected_answer) print('But, received ') print(answer) # third test wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_01.txt") answer = solve_sokoban_elem(wh) expected_answer = [ 'Down', 'Left', 'Up', 'Right', 'Right', 'Right', 'Down', 'Left', 'Up', 'Left', 'Left', 'Down', 'Down', 'Right', 'Up', 'Left', 'Up', 'Right', 'Up', 'Up', 'Left', 'Down', 'Right', 'Down', 'Down', 'Right', 'Right', 'Up', 'Left', 'Down', 'Left', 'Up', 'Up' ] fcn = test_solve_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') else: print(fcn.__name__, ' failed! :-(\n') print('Expected ') print(expected_answer) print('But, received ') print(answer) # 4 test wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_03.txt") answer = solve_sokoban_elem(wh) expected_answer = ['Right', 'Up', 'Up', 'Left', 'Left', 'Left', 'Up', \ 'Left', 'Down', 'Right', 'Right', 'Right', 'Right', \ 'Down', 'Down', 'Left', 'Up', 'Right', 'Up', 'Left', \ 'Left', 'Left', 'Down', 'Down', 'Left', 'Left', 'Left', \ 'Up', 'Up', 'Right', 'Right', 'Down', 'Right', 'Down', \ 'Left', 'Up', 'Up', 'Up', 'Right', 'Down', 'Down'] fcn = test_solve_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') print('Number of moves: ', len(expected_answer)) else: print(fcn.__name__, ' failed! :-(\n') print('Expected (' + str(len(expected_answer)) + ' moves)') print(expected_answer) print('But, received (' + str(len(answer)) + ' moves)') print(answer) wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_47.txt") answer = solve_sokoban_elem(wh) expected_answer = ['Right', 'Right', 'Right', 'Up', 'Up', 'Up', 'Left', \ 'Left', 'Down', 'Right', 'Right', 'Down', 'Down', 'Left', \ 'Left', 'Left', 'Left', 'Up', 'Up', 'Right', 'Right', \ 'Right', 'Up', 'Right', 'Down', 'Down', 'Up', 'Left', \ 'Left', 'Left', 'Left', 'Down', 'Down', 'Right', 'Right', \ 'Right', 'Right', 'Right', 'Right', 'Down', 'Right', \ 'Right', 'Up', 'Left', 'Left', 'Left', 'Left', 'Left', \ 'Left', 'Right', 'Right', 'Up', 'Up', 'Up', 'Right', \ 'Right', 'Down', 'Left', 'Up', 'Left', 'Down', 'Down', \ 'Up', 'Left', 'Left', 'Left', 'Left', 'Down', 'Down', \ 'Down', 'Right', 'Right', 'Up', 'Right', 'Right', 'Left', \ 'Left', 'Down', 'Left', 'Left', 'Up', 'Right', 'Right'] fcn = test_solve_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') print('Number of moves: ', len(expected_answer)) else: print(fcn.__name__, ' failed! :-(\n') print('Expected (' + str(len(expected_answer)) + ' moves)') print(expected_answer) print('But, received (' + str(len(answer)) + ' moves)') print(answer) wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_147.txt") answer = solve_sokoban_elem(wh) expected_answer = ['Left', 'Left', 'Left', 'Left', 'Left', 'Left', 'Down', \ 'Down', 'Down', 'Right', 'Right', 'Up', 'Left', 'Down', \ 'Left', 'Up', 'Up', 'Left', 'Up', 'Right', 'Right', \ 'Right', 'Right', 'Right', 'Right', 'Down', 'Right', 'Right', \ 'Right', 'Up', 'Up', 'Left', 'Left', 'Down', 'Left', \ 'Left', 'Left', 'Left', 'Left', 'Left', 'Down', 'Down', \ 'Right', 'Right', 'Right', 'Down', 'Right', 'Down', 'Down', \ 'Left', 'Up', 'Right', 'Up', 'Left', 'Left', 'Left', 'Right', \ 'Right', 'Down', 'Down', 'Down', 'Left', 'Left', 'Up', \ 'Up', 'Left', 'Up', 'Up', 'Up', 'Left', 'Up', 'Right', \ 'Right', 'Right', 'Right', 'Right', 'Right', 'Left', 'Left', \ 'Left', 'Left', 'Left', 'Down', 'Down', 'Right', 'Right', \ 'Down', 'Left', 'Down', 'Left', 'Up', 'Up', 'Up', 'Left', \ 'Up', 'Right', 'Right', 'Right', 'Right', 'Right', 'Down', \ 'Right', 'Down', 'Right', 'Right', 'Up', 'Left', 'Right', \ 'Right', 'Up', 'Up', 'Left', 'Left', 'Down', 'Left', 'Left', \ 'Left', 'Left', 'Left', 'Left', 'Right', 'Right', 'Right', \ 'Right', 'Right', 'Right', 'Up', 'Right', 'Right', 'Down', \ 'Down', 'Left', 'Down', 'Left', 'Left', 'Up', 'Right', 'Up', \ 'Left', 'Left', 'Down', 'Right', 'Right', 'Right', 'Down',\ 'Right', 'Up'] fcn = test_solve_sokoban_elem print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') print('Number of moves: ', len(expected_answer)) else: print(fcn.__name__, ' failed! :-(\n') print('Expected (' + str(len(expected_answer)) + ' moves)') print(expected_answer) print('But, received (' + str(len(answer)) + ' moves)') print(answer)
def test_solve_sokoban_macro(): # puzzle_t2 ='#######\n#@ $ .#\n#######' # wh = Warehouse() # wh.extract_locations(puzzle_t2.split(sep='\n')) # # first test # answer=solve_sokoban_macro(wh) # expected_answer = [((1, 3), 'Right'), ((1, 4), 'Right')] # fcn = test_solve_sokoban_macro # print('<< First test of {} >>'.format(fcn.__name__)) # if answer==expected_answer: # print(fcn.__name__, ' passed! :-)\n') # else: # print(fcn.__name__, ' failed! :-(\n') # print('Expected ');print(expected_answer) # print('But, received ');print(answer) # second test # wh = Warehouse() # wh.load_warehouse("./warehouses/warehouse_01.txt") # answer=solve_sokoban_macro(wh) # expected_answer = [((1, 3), 'Right'), ((1, 4), 'Right')] # fcn = test_solve_sokoban_macro # print('<< First test of {} >>'.format(fcn.__name__)) # if answer==expected_answer: # print(fcn.__name__, ' passed! :-)\n') # else: # print(fcn.__name__, ' failed! :-(\n') # print('Expected ');print(expected_answer) # print('But, received ');print(answer) # wh = Warehouse() # wh.load_warehouse("./warehouses/warehouse_03.txt") # answer=solve_sokoban_macro(wh) # expected_answer = [((2, 6), 'Left'), ((2, 5), 'Left'), ((2, 4), 'Left'), ((2, 3), 'Down'),\ # ((3, 6), 'Up'), ((2, 6), 'Left'), ((2, 5), 'Left'), ((2, 4), 'Left'), \ # ((2, 3), 'Right'), ((3, 3), 'Down'), ((4, 3), 'Left'), ((2, 4), 'Down'), ((3, 4), 'Down')] # # fcn = test_solve_sokoban_macro # print('<< First test of {} >>'.format(fcn.__name__)) # if answer==expected_answer: # print(fcn.__name__, ' passed! :-)\n') # print('Number of moves: ', len(expected_answer)) # else: # print(fcn.__name__, ' failed! :-(\n') # print('Expected ('+str(len(expected_answer))+' moves)');print(expected_answer) # print('But, received ('+str(len(answer))+' moves)');print(answer) wh = Warehouse() wh.load_warehouse("./warehouses/warehouse_47.txt") answer = solve_sokoban_macro(wh) expected_answer = [((2, 4), 'Right'), ((2, 5), 'Right'), ((2, 2), 'Right'), \ ((2, 3), 'Right'), ((2, 6), 'Left'), ((2, 5), 'Down'), \ ((3, 5), 'Down'), ((4, 5), 'Right'), ((2, 4), 'Right'), \ ((2, 5), 'Down'), ((4, 6), 'Right'), ((4, 7), 'Right'), \ ((4, 8), 'Left'), ((4, 7), 'Left'), ((4, 6), 'Left'), \ ((4, 5), 'Left'), ((4, 4), 'Left'), ((4, 3), 'Left'), \ ((3, 5), 'Down'), ((4, 5), 'Right'), ((4, 2), 'Right'), \ ((4, 3), 'Right')] fcn = test_solve_sokoban_macro print('<< First test of {} >>'.format(fcn.__name__)) if answer == expected_answer: print(fcn.__name__, ' passed! :-)\n') print('Number of moves: ', len(expected_answer)) else: print(fcn.__name__, ' failed! :-(\n') print('Expected (' + str(len(expected_answer)) + ' moves)') print(expected_answer) print('But, received (' + str(len(answer)) + ' moves)') print(answer)
class Application(tk.Frame): def __init__(self, master=None): tk.Frame.__init__(self, master) self.grid() self.configure(background="black") self.master.title("Sokoban v%s" % (__version__)) self.master.resizable(0,0) self.image_dict={'wall':tk.PhotoImage(file=os.path.join(_ROOT, 'images/wall.gif')), 'target':tk.PhotoImage(file=os.path.join(_ROOT, 'images/hole.gif')), 'box_on_target':tk.PhotoImage(file=os.path.join(_ROOT, 'images/crate-in-hole.gif')), 'box':tk.PhotoImage(file=os.path.join(_ROOT, 'images/crate.gif')), 'worker':tk.PhotoImage(file=os.path.join(_ROOT, 'images/player.gif')), 'smiley':tk.PhotoImage(file=os.path.join(_ROOT, 'images/smiley.gif')), 'worker_on_target':tk.PhotoImage(file=os.path.join(_ROOT, 'images/player-in-hole.gif')), } icon = self.image_dict['box'] self.warehouse_symbol = { 'wall':'#' , 'target':'.' , 'box_on_target': '*' , 'box':'$' , 'worker':'@', 'worker_on_target': '!', 'floor' : ' '} self.direction_offset = {'Left' :(-1,0), 'Right':(1,0) , 'Up':(0,-1), 'Down':(0,1)} # (x,y) = (column,row) self.master.tk.call('wm', 'iconphoto', self.master._w, icon) self.create_menu() self.DEFAULT_SIZE = 200 self.frame = tk.Frame(self, height=self.DEFAULT_SIZE, width=self.DEFAULT_SIZE) self.frame.grid() self.default_frame() self.cells={} # dict with key (x,y) and value Label widget to keep track of the Labels in the grid self.level_file_name = None self.warehouse = Warehouse() def key(self, event): if event.keysym in ('Left', 'Right', 'Up', 'Down'): self.move_player(event.keysym) if event.keysym in ('r','R'): self.restart_level() def create_menu(self): root = self.master menu = tk.Menu(root) user_menu = Menu(self) root.config(menu=menu) file_menu = tk.Menu(menu) menu.add_cascade(label="File", menu=file_menu) file_menu.add_command(label="Restart", command=self.restart_level) file_menu.add_command(label="Open...", command=user_menu.OpenFile) file_menu.add_separator() file_menu.add_command(label="Exit", command=menu.quit) help_menu = tk.Menu(menu) menu.add_cascade(label="Help", menu=help_menu) help_menu.add_command(label="About", command=user_menu.About) def default_frame(self): start_width = 50 start_label = tk.Label(self.frame, text="\n *** Welcome to Sokoban! ***\n", width=start_width) start_label.grid(row=0, column=0) start_label2 = tk.Label(self.frame, text="To play: File -> Open\n", width=start_width) start_label2.grid(row=1, column=0) start_label3 = tk.Label(self.frame, text="To reset current warehouse: press the 'r' key \n", width=start_width) start_label3.grid(row=3, column=0) def clear_level(self): self.frame.destroy() self.frame = tk.Frame(self) self.frame.grid() self.warehouse = Warehouse() # warehouse self.cells = {} def start_level(self): self.clear_level() self.warehouse.load_warehouse(self.level_file_name) self.master.title("Sokoban v%s - %s" % ( __version__, self.level_file_name.split("/")[-1])) self.fresh_display() def restart_level(self): if self.level_file_name: self.start_level() def fresh_display(self): ''' First display of the warehouse Setup the self.cells dictionary ''' for x,y in self.warehouse.walls: w = tk.Label(self.frame, image=self.image_dict['wall']) w.grid(row=y,column=x) self.cells[(x,y)] = w for x,y in self.warehouse.targets: w = tk.Label(self.frame, image=self.image_dict['target']) w.grid(row=y,column=x) self.cells[(x,y)] = w for x,y in self.warehouse.boxes: if (x,y) in self.warehouse.targets: w = self.cells[(x,y)] w['image'] = self.image_dict['box_on_target'] else: w = tk.Label(self.frame, image=self.image_dict['box']) w.grid(row=y,column=x) self.cells[(x,y)] = w x,y = self.warehouse.worker if (x,y) in self.warehouse.targets: w = self.cells[(x,y)] w['image'] = self.image_dict['worker_on_target'] else: w = tk.Label(self.frame, image=self.image_dict['worker']) w.grid(row=y,column=x) self.cells[(x,y)] = w self.pack() def move_player(self, direction): ''' direction in ['Left', 'Right', 'Up', 'Down']: Check whether the worker is pushing a box ''' x,y = self.warehouse.worker ## print 'worker x,y = ',x,y xy_offset = self.direction_offset[direction] ## print 'xy_offset = ', xy_offset next_x , next_y = x+xy_offset[0] , y+xy_offset[1] # where the player will go if possible ## print 'next_x , next_y = ', next_x , next_y # Let's find out if it is possible to move the player in this direction if (next_x,next_y) in self.warehouse.walls: return # impossible move if (next_x,next_y) in self.warehouse.boxes: if self.try_move_box( (next_x,next_y), (next_x+xy_offset[0],next_y+xy_offset[1]) ) == False: return # box next to the player could not be pushed # now, the cell next to the player must be empty # we still have to move the player ## print 'let s move the player! ' w = self.cells[(x,y)] # Label widget in the cell currently containing the player del self.cells[(x,y)] w.destroy() w = tk.Label(self.frame) #, image=self.image_dict['worker']) w.grid(row=next_y,column=next_x) # move it to the next cell self.cells[(next_x,next_y)] = w self.warehouse.worker = (next_x,next_y) # Test whether the appearance of the player need to change on the next cell if (next_x,next_y) in self.warehouse.targets: w['image'] = self.image_dict['worker_on_target'] else: w['image'] = self.image_dict['worker'] # update the cell where the player was if(x,y) in self.warehouse.targets: w = tk.Label(self.frame, image=self.image_dict['target']) w.grid(row=y,column=x) self.cells[(x,y)] = w puzzle_solved = all(z in self.warehouse.targets for z in self.warehouse.boxes) if puzzle_solved: x,y = self.warehouse.worker w = self.cells[(x,y)] # Label widget in the cell currently containing the player del self.cells[(x,y)] w.destroy() w = tk.Label(self.frame, image=self.image_dict['smiley']) w.grid(row=y,column=x) self.cells[(x,y)] = w self.pack() def try_move_box(self, location, next_location): ''' location and next_location are (x,y) tuples Move the box from 'location' to 'next_location' Note that we assume that there is a wall around the warehouse! Return True if the box was moved, return False if the box could not be moved Update the position and the image of the Label widget for this box ''' x, y = location next_x, next_y = next_location assert (x,y) in self.warehouse.boxes if (next_x, next_y) not in self.warehouse.walls and (next_x, next_y) not in self.warehouse.boxes: # can move the box! # clean cell (x,y) w = self.cells[(x,y)] del self.cells[(x,y)] w.destroy() # clean cell (next_x,next_y) if (next_x,next_y) in self.cells: assert (next_x,next_y) in self.warehouse.targets w = self.cells[(next_x,next_y)] del self.cells[(next_x,next_y)] w.destroy() # new Label for the moved box w = tk.Label(self.frame) if (next_x,next_y) in self.warehouse.targets: w['image'] = self.image_dict['box_on_target'] else: w['image'] = self.image_dict['box'] w.grid(row=next_y, column=next_x) self.cells[(next_x,next_y)] = w self.warehouse.boxes.remove((x,y)) self.warehouse.boxes.append((next_x,next_y)) # we don't have to update (x,y), this will be done while moving the player return True # move successful else: return False # box was blocked
import time import mySokobanSolver import time import csv from sokoban import Warehouse if __name__ == "__main__": num = int(input("Warehouse Num: ")) problem_file = "./warehouses/warehouse_{:02d}.txt".format(num) # Test marco solver wh = Warehouse() wh.load_warehouse(problem_file) print(wh) print("Macro Solver") t0 = time.time() result = mySokobanSolver.solve_sokoban_macro(wh) t1 = time.time() print('Macro Solver took {:.6f} seconds'.format(t1 - t0)) print("Solution: {0}".format(result)) print("Solution Len: {0} \n".format(len(result))) # Test element solver wh = Warehouse() wh.load_warehouse(problem_file) print("Element Solver")