예제 #1
0
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
예제 #3
0
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)
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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()
예제 #9
0
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:]
예제 #10
0
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()
예제 #12
0
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()
예제 #13
0
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
예제 #15
0
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
예제 #16
0
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()
예제 #18
0
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()
예제 #19
0
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
예제 #20
0
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()
예제 #21
0
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
예제 #22
0
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
예제 #23
0
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
예제 #25
0
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
예제 #26
0
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()
예제 #27
0
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
예제 #28
0
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
예제 #29
0
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:]
예제 #30
0
	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
예제 #31
0
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