def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' # warehouse is not always fully initialised warehouse.from_string(str(warehouse)) # swap coordinates dst = (dst[1], dst[0]) if dst in warehouse.walls or dst in warehouse.boxes: return False if dst == warehouse.worker: return True problem = CanGoThereProblem(warehouse.worker, warehouse, dst) node = search.astar_graph_search(problem) return node is not None
def solve_sokoban_macro(warehouse): """ Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return ['Impossible'] Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] """ if warehouse.boxes == warehouse.targets: return [] macroActions = SearchMacroActions(warehouse) #use A* graph search to move the box to the goal macroSolution = search.astar_graph_search(macroActions) final_macro_actions = macroActions.solution(macroSolution) return final_macro_actions
def solve_sokoban_elem(warehouse): ''' This function should solve using elementary actions the puzzle defined in a file. @param warehouse: a valid Warehouse object @return A list of strings. If puzzle cannot be solved return ['Impossible'] If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' #Implement check to see if impossible. puzzle = SokobanPuzzle(warehouse) solution = search.astar_graph_search(puzzle, puzzle.h)#lambda n:puzzle.h(n)) if solution == None: return 'Impossible' else: return search.Node.solution(solution)
def solve_sokoban_elem(warehouse): ''' This function should solve using A* algorithm and elementary actions the puzzle defined in the parameter 'warehouse'. In this scenario, the cost of all (elementary) actions is one unit. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' puzzle = SokobanPuzzle(warehouse, True, False) temp_warehouse = warehouse.copy() if (set(temp_warehouse.boxes) == set(temp_warehouse.targets)): return [] puzzle_ans = search.astar_graph_search(puzzle) step_move = [] if (puzzle_ans is None): return 'Impossible' else: for node in puzzle_ans.path(): step_move.append(node.action.__str__()) action_seq = step_move[1:] if check_elem_action_seq(temp_warehouse, action_seq) == 'Impossible': return 'Impossible' else: return action_seq
def solve_sokoban_macro(warehouse): """ Solve using using A* algorithm and macro actions the puzzle defined in the parameter 'warehouse'. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. In this scenario, the cost of all (macro) actions is one unit. @param warehouse: a valid Warehouse object @return If the puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] """ path = search.astar_graph_search(SokobanPuzzle(warehouse, macro=True)) if path is not None: return path.solution() return FAILED
def solve_weighted_sokoban_elem(warehouse, push_costs): """ In this scenario, we assign a pushing cost to each box, whereas for the functions 'solve_sokoban_elem' and 'solve_sokoban_macro', we were simply counting the number of actions (either elementary or macro) executed. When the worker is moving without pushing a box, we incur a cost of one unit per step. Pushing the ith box to an adjacent cell now costs 'push_costs[i]'. The ith box is initially at position 'warehouse.boxes[i]'. This function should solve using A* algorithm and elementary actions the puzzle 'warehouse' while minimizing the total cost described above. @param warehouse: a valid Warehouse object push_costs: list of the weights of the boxes (pushing cost) @return If puzzle cannot be solved return 'Impossible' If a solution exists, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] """ path = search.astar_graph_search( SokobanPuzzle(warehouse, push_costs=push_costs)) if path is not None: return path.solution() return FAILED
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' def heuristic(node): # Using Manhattan Distance for heuristics nodeState = node.state aSquared = (nodeState[0] - dst[0])**2 bSquared = (nodeState[1] - dst[1])**2 manhattanDistance = (aSquared + bSquared)**0.5 return manhattanDistance worker = warehouse.worker node = search.astar_graph_search(Pathing(worker, warehouse, dst), heuristic) return node is not None
def solve_sokoban_elem(warehouse): ''' This function should solve using elementary actions the puzzle defined in a file. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' puzzle = SokobanPuzzle(warehouse, True, False) t0 = time.time() # sol = greedy_best_first_graph_search(puzzle, puzzle.h) sol = astar_graph_search(puzzle, puzzle.h) # sol = search.depth_first_graph_search(puzzle) # sol = breadth_first_graph_search(puzzle) t1 = time.time() print(' elem took {:.6f} seconds'.format(t1 - t0)) if sol is None: return ['Impossible'] else: print("LENGTH", len(sol.solution())) print("SOLUTION", sol.solution()) return sol.solution()
def solve_weighted_sokoban_elem(warehouse, push_costs): ''' developing ''' # Set the empty list actions = [] new_state = [] problem = SokobanPuzzle(warehouse) copy_state = list(problem.state) new_state.append(copy_state[0]) # Put the push costs on the boxes for i in range(len(push_costs)): new_state.append(((copy_state[i+1]), push_costs[i])) # Set the new initial value with push costs problem.initial = tuple(new_state) p = search.astar_graph_search(problem) # Take and add the actions from path for n in path(p): actions.append(n.action) if actions is None: return 'Impossible' elif problem.goal_test(problem.state): # If the state is already on the goal return [] else: return actions[1:]
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' #flip the coordinates around so it works with can_go_there [a, b] = dst dst = (b, a) #define a heuristic that returns the manhattan distance between the player and the target def heuristic(n): state = n.state return manhattan_distance(state, dst) #define the puzzle, then apply the search algorithm to the puzzle puzzle = player_path(warehouse, dst, warehouse.worker) path = search.astar_graph_search(puzzle, heuristic) #return the results of the solver if path is None: return False else: return True
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' ## "INSERT YOUR CODE HERE" # def heuristic(position): # state=position.state # # print(state,'111') # return manhattan_distance(state,dst) node = search.astar_graph_search( WorkerPath(warehouse.worker, warehouse, dst)) if node is not None: return True else: return False raise NotImplementedError()
def solve_sokoban_elem(warehouse): ''' This function should solve using A* algorithm and elementary actions the puzzle defined in the parameter 'warehouse'. In this scenario, the cost of all (elementary) actions is one unit. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' # define the problem puzzle = SokobanPuzzle(warehouse) # set the macro bool to True puzzle.macro = False puzzle.allow_taboo_push = False puzzle.weighted = False # implement the algorithm we want to use sol = search.astar_graph_search(puzzle, puzzle.h) #return the results of the solver if sol is None: return 'Impossible' else: return sol.solution()
def solve_sokoban_macro(warehouse): ''' Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return ['Impossible'] Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' wh = warehouse sp = SokobanPuzzle(wh, elem=False) sol = search.astar_graph_search(sp) if sol is None: return ['Impossible'] else: M = [] for action in sol.solution(): M.append(((action[0][1], action[0][0]), action[1])) return M
def solve_sokoban_macro(warehouse): ''' Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return ['Impossible'] Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' if warehouse.targets == warehouse.boxes: return [] sokoban_macro = SokobanMacro(warehouse) sol = search.astar_graph_search(sokoban_macro) macro_xy = sokoban_macro.return_solution(sol) #convert (x,y) to (r,c) macro_rc = [] for action in macro_xy: macro_rc.append(((action[0][1], action[0][0]), action[1])) return macro_rc
def can_go_there(warehouse, dst): """ Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @param dst: (row, col) of the location to go to @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise """ # separate row, col for usage below (row, col) = dst # the player is only able to move to a space and a target square allowed_cells = {SPACE, TARGET_SQUARE} # convert the warehouse to a Array<Array<char>> warehouse_matrix = warehouse_to_matrix(warehouse) # check if the worker is allowed onto the given coordinates before checking if a valid path exists if warehouse_matrix[row][col] not in allowed_cells: return False # check if a valid path from the worker to the coordinate provided exists path = search.astar_graph_search(PathProblem(warehouse, (col, row))) return path is not None
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' def heuristic(n): state = n.state # distance formula heuristic (sqrt(xdiff^2 + ydiff^2). return math.sqrt(((state[1] - dst[1])**2) + ((state[0] - dst[0])**2)) dst = (dst[1], dst[0]) # destination is given in (row,col), not (x,y) # use an A* graph search on the using the find path problem search. cell = astar_graph_search( FindPathProblem(warehouse.worker, warehouse, dst), heuristic) # return the cell if it is valid return cell is not None
def solve_sokoban_macro(warehouse): ''' Solve using using A* algorithm and macro actions the puzzle defined in the parameter 'warehouse'. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. In this scenario, the cost of all (macro) actions is one unit. @param warehouse: a valid Warehouse object @return If the puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' ## "INSERT YOUR CODE HERE" str_warehouse = str(warehouse) goal = str_warehouse.replace("$", " ").replace(".", "*") # def heuristic(node): # # print(node) # # print(' ') # h=0 # warehouse=sokoban.Warehouse() # warehouse.extract_locations(node.state.splitlines()) # for target in warehouse.targets: # for box in warehouse.boxes: # h=manhattan_distance(box,target)+h # return h macros = search.astar_graph_search(SokobanPuzzle(str_warehouse, goal)) # print(M.path()) if macros is None or macros == 'Impossible': return str('Impossible') elif macros.path()[-1] == str_warehouse: return [] else: actions_list = [node.action for node in macros.path()] # print(actions_list) return actions_list raise NotImplementedError()
def solve_sokoban_macro(warehouse): ''' Solve using macro actions the puzzle defined in the warehouse passed as a parameter. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' # Heuristic for the search problem = SokobanPuzzle(warehouse) problem.macro = True def h(node): boxes = node.state[1:] goals = warehouse.targets total = 0 for box in boxes: shortest = 10000000 for goal in goals: xdist = abs(box[0] - goal[0]) ydist = abs(box[1] - goal[1]) distance = xdist + ydist if shortest == None or distance < shortest: shortest = distance total = total + shortest return total # Heuristic node = search.astar_graph_search(problem, h) #node = search.astar_tree_search(problem, h) #node = search.breadth_first_graph_search(problem) #node = search.breadth_first_tree_search(problem) #node = search.depth_first_graph_search(problem) #node = search.depth_first_tree_search(problem) #node = search.uniform_cost_search(problem) #node = search.depth_limited_search(problem) #node = search.iterative_deepening_search(problem) if node == None: return ["Impossible"] return node.solution()
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. ''' problem = SimpleAction(warehouse, dst) node = search.astar_graph_search(problem) # Return True if the A* search can determine path nodes return node is not None
def solve_sokoban_elem(warehouse): ''' This function should solve using elementary actions the puzzle defined in a file. @param warehouse: a valid Warehouse object @return If puzzle cannot be solved return the string 'Impossible' If a solution was found, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' problem = SokobanPuzzle(warehouse) # Heuristic for the search def h(node): boxes = node.state[1:] goals = warehouse.targets total = 0 for box in boxes: shortest = 10000000 for goal in goals: # uses the manhattan distance xdist = abs(box[0] - goal[0]) ydist = abs(box[1] - goal[1]) distance = xdist + ydist if shortest == None or distance < shortest: shortest = distance total = total + shortest return total # Heuristic node = search.astar_graph_search(problem, h) #node = search.astar_tree_search(problem, h) #node = search.breadth_first_graph_search(problem) #node = search.breadth_first_tree_search(problem) #node = search.depth_first_graph_search(problem) #node = search.depth_first_tree_search(problem) #node = search.uniform_cost_search(problem) #node = search.depth_limited_search(problem) #node = search.iterative_deepening_search(problem) if node == None: return ["Impossible"] return node.solution()
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,col) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,col) without pushing any box False otherwise ''' sp = SokobanPuzzle(warehouse, targetPos=(dst[1], dst[0])) sol = search.astar_graph_search(sp) return not sol == None
def solve_sokoban_macro(warehouse): ''' Solve using using A* algorithm and macro actions the puzzle defined in the parameter 'warehouse'. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. In this scenario, the cost of all (macro) actions is one unit. @param warehouse: a valid Warehouse object @return If the puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' problem = SokobanPuzzle(warehouse) problem.macro = True # heuristic - maybe unneeded def h(node): boxes = list(node.state[1]) goals = warehouse.targets total = 0 for box in boxes: shortest = 10000000 for goal in goals: distance = manhattan_distance(box, goal) if shortest == None or distance < shortest: shortest = distance total = total + shortest return total start = time.time() node = search.astar_graph_search(problem) end = time.time() print(end - start) results = problem.print_result(node) return results
def solve_weighted_sokoban_elem(warehouse, push_costs): ''' In this scenario, we assign a pushing cost to each box, whereas for the functions 'solve_sokoban_elem' and 'solve_sokoban_macro', we were simply counting the number of actions (either elementary or macro) executed. When the worker is moving without pushing a box, we incur a cost of one unit per step. Pushing the ith box to an adjacent cell now costs 'push_costs[i]'. The ith box is initially at position 'warehouse.boxes[i]'. This function should solve using A* algorithm and elementary actions the puzzle 'warehouse' while minimizing the total cost described above. @param warehouse: a valid Warehouse object push_costs: list of the weights of the boxes (pushing cost) @return If puzzle cannot be solved return 'Impossible' If a solution exists, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' puzzle = SokobanPuzzle(warehouse, True, False, push_costs) temp_warehouse = warehouse.copy() if (temp_warehouse.boxes == temp_warehouse.targets): return [] puzzle_ans = search.astar_graph_search(puzzle) # print(warehouse) step_move = [] if (puzzle_ans is None): return 'Impossible' else: for node in puzzle_ans.path(): step_move.append(node.action.__str__()) action_seq = step_move[1:] if check_elem_action_seq(temp_warehouse, action_seq) == 'Impossible': return 'Impossible' else: return action_seq
def solve_sokoban_macro_weight(warehouse, push_costs): str_warehouse = str(warehouse) goal = str_warehouse.replace("$", " ").replace(".", "*") macros = search.astar_graph_search( Weighted_sokoban(str_warehouse, goal, push_costs)) if macros is None: return str('Impossible') elif macros.path()[-1] == str_warehouse: return [] else: actions_list = [node.action for node in macros.path()] return actions_list
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise ''' destination = (dst[1], dst[0]) path = search.astar_graph_search( TempSokuban(warehouse.worker, destination, warehouse)) if path is None: return False else: return True
def solve_weighted_sokoban_elem(warehouse, push_costs): ''' In this scenario, we assign a pushing cost to each box, whereas for the functions 'solve_sokoban_elem' and 'solve_sokoban_macro', we were simply counting the number of actions (either elementary or macro) executed. When the worker is moving without pushing a box, we incur a cost of one unit per step. Pushing the ith box to an adjacent cell now costs 'push_costs[i]'. The ith box is initially at position 'warehouse.boxes[i]'. This function should solve using A* algorithm and elementary actions the puzzle 'warehouse' while minimizing the total cost described above. @param warehouse: a valid Warehouse object push_costs: list of the weights of the boxes (pushing cost) @return If puzzle cannot be solved return 'Impossible' If a solution exists, return a list of elementary actions that solves the given puzzle coded with 'Left', 'Right', 'Up', 'Down' For example, ['Left', 'Down', Down','Right', 'Up', 'Down'] If the puzzle is already in a goal state, simply return [] ''' # add the push costs to a global variable so the path costs can be used by the puzzle class for cost in push_costs: costs.append(cost) # define the problem puzzle = SokobanPuzzle(warehouse) # set the macro bool to True puzzle.macro = False puzzle.allow_taboo_push = False puzzle.weighted = True # implement the algorithm we want to use sol = search.astar_graph_search(puzzle, puzzle.h) #return the results of the solver if sol is None: return 'Impossible' else: return sol.solution()
def solve_sokoban_macro(warehouse): ''' Solve using using A* algorithm and macro actions the puzzle defined in the parameter 'warehouse'. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. In this scenario, the cost of all (macro) actions is one unit. @param warehouse: a valid Warehouse object @return If the puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' if warehouse.targets == warehouse.boxes: return [] # sokoban_macro = SokobanMacro(warehouse) results = search.astar_graph_search(warehouse) if results == None: return ['Impossible'] path = results.path() solution = [] for node in path: solution.append(node.action) solution.remove(None) #convert (x,y) to (r,c) macro_rc = [] for action in solution: macro_rc.append(((action[0][1], action[0][0]), action[1])) return macro_rc
def can_go_there(warehouse, dst): ''' Determine whether the worker can walk to the cell dst=(row,column) without pushing any box. @param warehouse: a valid Warehouse object @return True if the worker can walk to cell dst=(row,column) without pushing any box False otherwise RETURNS (X, Y) ''' def h(n): state = n.state return manhattan_distance(state, dst) puzzle = path_finder(warehouse, dst, warehouse.worker) path = astar_graph_search(puzzle, h) return path is not None
def solve_sokoban_elem(warehouse): ''' This function should solve using A* algorithm and elementary actions the puzzle defined in the parameter 'warehouse'. ''' # Set the empty list elem_action = [] problem = SokobanPuzzle(False, False, warehouse) elem_node = search.astar_graph_search(problem) # Take and add the actions of the nodes from the path for n in path(elem_node): elem_action.append(n.action) if not elem_action: return 'Impossible' elif problem.goal_test(problem.initial): return [] else: return elem_action[1:]
def run(self): global cache board = self.initial.board player = self.initial.player board_rep = str(board.pawns[player]) + str(board.horiz_walls) + str(board.verti_walls) + str(player) if board_rep in cache: return cache[board_rep] if len(cache) >= 10000: cache = {} node = search.astar_graph_search(self, h) if node == None: return -1 length = 0 while node.parent: node = node.parent length += 1 cache[board_rep] = length return length
def solve_sokoban_macro(warehouse): ''' Solve using using A* algorithm and macro actions the puzzle defined in the parameter 'warehouse'. A sequence of macro actions should be represented by a list M of the form [ ((r1,c1), a1), ((r2,c2), a2), ..., ((rn,cn), an) ] For example M = [ ((3,4),'Left') , ((5,2),'Up'), ((12,4),'Down') ] means that the worker first goes the box at row 3 and column 4 and pushes it left, then goes to the box at row 5 and column 2 and pushes it up, and finally goes the box at row 12 and column 4 and pushes it down. In this scenario, the cost of all (macro) actions is one unit. @param warehouse: a valid Warehouse object @return If the puzzle cannot be solved return the string 'Impossible' Otherwise return M a sequence of macro actions that solves the puzzle. If the puzzle is already in a goal state, simply return [] ''' puzzle = SokobanPuzzle(warehouse, True, True) temp_warehouse = warehouse.copy() if (temp_warehouse.boxes == temp_warehouse.targets): return [] puzzle_ans = search.astar_graph_search(puzzle) step_move = [] if (puzzle_ans is None): return 'Impossible' else: for node in puzzle_ans.path(): action = node.action if action is None: continue step_move.append( ((action[0][1], action[0][0]), action[1].__str__())) action_seq = step_move[:] return action_seq