예제 #1
0
파일: simple_grid.py 프로젝트: Obeyed/AIMAS
    def swapable(self, box_cell, agent_cell, next_cell, agent_origin):
        """ Given box and agent position and we want to move towards next_cell,
        is it possible to perform a Pull and Push?

        Return first cell where the agent can Pull towards and Push from.
        If no swap is possible, return None.
        If box and agent are not neighbouring cells then return None.
        If agent and next cell are not neighbouring cells then return None.

        Keyword arguments:
        box_cell -- box's position
        agent_cell -- agent's position
        next_cell -- next cell to move towards
        agent_origin -- where did agent originate from
            grid thinks agent's start position is blocked.
        """
        # if box and agent or agent and next are not neighbours, return
        if cross_product(box_cell, agent_cell) is not 1: return None
        if cross_product(agent_cell, next_cell) is not 1: return None

        results = self.neighbours(agent_cell)
        if agent_cell != agent_origin and cross_product(agent_cell,
                agent_origin) is 1:
            results = [agent_origin] + results
        results = [c for c in results if c != box_cell and c != next_cell]
        return results[0] if len(results) > 0 else None
예제 #2
0
    def find_closest_box_for_goal(self, goal):
        """ Find closest box to goal.

        NOTE: Naive combination finder.
        We could find best combined box-movement-sum for each goal-letter.

        Keyword arguments:
        goal -- tuple of letter and cell
        """
        g_letter, g_cell = goal
        # box instance, (goal, cell), distance
        best_combination = (None, None, float('inf'))
        for box in self.grid.boxes:
            b_letter, b_cell = box.name, box.position
            if b_letter != g_letter.upper(): continue
            # if box already on correct goal
            if (b_cell in self.grid.goals and
                    b_letter == self.grid.goals[b_cell].upper()):
                continue
            # make sure a path exists!
            path, _ = a_star_search(self.grid, b_cell, g_cell, box=box)
            cost = cross_product(b_cell, g_cell) if path is not None else float('inf')
            if cost < best_combination[2]:
                best_combination = (box, goal, cost)
        return best_combination[0] # box instance
예제 #3
0
    def find_closest_box_for_goal(self, goal):
        """ Find closest box to goal.

        NOTE: Naive combination finder.
        We could find best combined box-movement-sum for each goal-letter.

        Keyword arguments:
        goal -- tuple of letter and cell
        """
        g_letter, g_cell = goal
        # box instance, (goal, cell), distance
        best_combination = (None, None, float('inf'))
        for box in self.grid.boxes:
            b_letter, b_cell = box.name, box.position
            if b_letter != g_letter.upper(): continue
            # if box already on correct goal
            if (b_cell in self.grid.goals
                    and b_letter == self.grid.goals[b_cell].upper()):
                continue
            # make sure a path exists!
            path, _ = a_star_search(self.grid, b_cell, g_cell, box=box)
            cost = cross_product(b_cell,
                                 g_cell) if path is not None else float('inf')
            if cost < best_combination[2]:
                best_combination = (box, goal, cost)
        return best_combination[0]  # box instance
예제 #4
0
def get_swap_positions_prioritized(grid, box):
    """ return priority queue of cells where swaps are possible """
    not_walls = grid.complete_grid - grid.walls
    free_swaps = [c for c in not_walls if len(grid.neighbours(c)) > 2]
    all_swaps = [c for c in not_walls if len(grid.neighbours(c, with_box=True,
        with_agent=True)) > 2]

    positions = free_swaps if len(free_swaps) else all_swaps
    swapables = queue.PriorityQueue()
    for pos in positions:
        swapables.put((cross_product(pos, box.position), pos))
    return swapables
예제 #5
0
 def find_closest_agent_for_box(self, box):
     """ return agent closest to box """
     agents = [agent for agent in self.grid.agent_info if
             box.name in self.grid.agent_info[agent]]
     best_combination = (None, float('inf'))
     for agent in agents:
         # make sure a path exists!
         path, _ = a_star_search(self.grid, agent.position, box.position,
                 box=box, agent=agent, backwards=True)
         cost = cross_product(box.position, agent.position) if path is not None else float('inf')
         if cost < best_combination[1]:
             best_combination = (agent, cost)
     return best_combination[0]
예제 #6
0
def get_swap_positions_prioritized(grid, box):
    """ return priority queue of cells where swaps are possible """
    not_walls = grid.complete_grid - grid.walls
    free_swaps = [c for c in not_walls if len(grid.neighbours(c)) > 2]
    all_swaps = [
        c for c in not_walls
        if len(grid.neighbours(c, with_box=True, with_agent=True)) > 2
    ]

    positions = free_swaps if len(free_swaps) else all_swaps
    swapables = queue.PriorityQueue()
    for pos in positions:
        swapables.put((cross_product(pos, box.position), pos))
    return swapables
예제 #7
0
 def find_closest_agent_for_box(self, box):
     """ return agent closest to box """
     agents = [
         agent for agent in self.grid.agent_info
         if box.name in self.grid.agent_info[agent]
     ]
     best_combination = (None, float('inf'))
     for agent in agents:
         # make sure a path exists!
         path, _ = a_star_search(self.grid,
                                 agent.position,
                                 box.position,
                                 box=box,
                                 agent=agent,
                                 backwards=True)
         cost = cross_product(
             box.position,
             agent.position) if path is not None else float('inf')
         if cost < best_combination[1]:
             best_combination = (agent, cost)
     return best_combination[0]