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
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
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
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]
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
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]