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 find_swapable_position(self, agent_to_box, box, agent, goal=None): swapables = get_swap_positions_prioritized(self.grid, box) # must create new path from box to swap position # get nearest swapable position swap_pos = swapables.get()[1] # path for box to goal # 1. push box to swap_pos (which is a cell with at least two neighbours) box_to_swap, block_info = a_star_search(grid=self.grid, start=box.position, goal=swap_pos, box=box, agent=agent) # 2. push box to random neighbour of swap_pos swap_cells = self.grid.neighbours(swap_pos, with_box=True, with_agent=True) # do not move backwards swap_cells = [n for n in swap_cells if n != box_to_swap[-2]] # add cell to pushing action box_to_swap.append(swap_cells[0]) self.update_block_info(block_info, swap_cells[0], box, agent) # 3. pull box to random neighbour of swap_pos that was not on box_to_swap box_pre_end, box_end = box_to_swap[-1], box_to_swap[-2] box_pull_for_swap = movement_with_box([box_pre_end, box_end]) # now add agent end pos to pull movement box_pull_for_swap.append(swap_cells[1]) self.update_block_info(block_info, swap_cells[1], box, agent) # finalize box_to_swap cells with agent end pos agent_end_pos = box_end box_to_swap = movement_with_box(box_to_swap) box_to_swap.append(agent_end_pos) path = agent_to_box + box_to_swap + box_pull_for_swap if goal: # find new (maybe improved) movement to goal revised_box_to_goal, b_info = (a_star_search(grid=self.grid, start=box_end, goal=goal[1], box=box, agent=agent)) block_info.update(b_info) path += movement_with_box(revised_box_to_goal) # if by some chance an object is still blocking, remove it block_cell = self.detect_blocking_objects(path, block_info, agent, box) if block_cell is not None: return self.find_next_resolving_path(block_cell, path, block_info) return path
def find_path_to_remove_blocking_object(self, original_path, block_cell, agent, box): """ We wish to find path to first free cell not in original path """ def ignore_heuristic(n, g): return 0 return a_star_search(self.grid, start=block_cell, agent=agent, box=box, clearing_path=original_path, heuristic=ignore_heuristic)
def shortest_path_to_box(self, agent, box): a_cell, b_cell = agent.position, box.position return a_star_search(self.grid, a_cell, b_cell, backwards=True, agent=agent, box=box)
def find_swapable_position(self, agent_to_box, box, agent, goal=None): swapables = get_swap_positions_prioritized(self.grid, box) # must create new path from box to swap position # get nearest swapable position swap_pos = swapables.get()[1] # path for box to goal # 1. push box to swap_pos (which is a cell with at least two neighbours) box_to_swap, block_info = a_star_search(grid=self.grid, start=box.position, goal=swap_pos, box=box, agent=agent) # 2. push box to random neighbour of swap_pos swap_cells = self.grid.neighbours(swap_pos, with_box=True, with_agent=True) # do not move backwards swap_cells = [n for n in swap_cells if n != box_to_swap[-2]] # add cell to pushing action box_to_swap.append(swap_cells[0]) self.update_block_info(block_info, swap_cells[0], box, agent) # 3. pull box to random neighbour of swap_pos that was not on box_to_swap box_pre_end, box_end = box_to_swap[-1], box_to_swap[-2] box_pull_for_swap = movement_with_box([box_pre_end, box_end]) # now add agent end pos to pull movement box_pull_for_swap.append(swap_cells[1]) self.update_block_info(block_info, swap_cells[1], box, agent) # finalize box_to_swap cells with agent end pos agent_end_pos = box_end box_to_swap = movement_with_box(box_to_swap) box_to_swap.append(agent_end_pos) path = agent_to_box + box_to_swap + box_pull_for_swap if goal: # find new (maybe improved) movement to goal revised_box_to_goal, b_info = ( a_star_search(grid=self.grid, start=box_end, goal=goal[1], box=box, agent=agent) ) block_info.update(b_info) path += movement_with_box(revised_box_to_goal) # if by some chance an object is still blocking, remove it block_cell = self.detect_blocking_objects(path, block_info, agent, box) if block_cell is not None: return self.find_next_resolving_path(block_cell, path, block_info) return path
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 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 shortest_path_to_goal_with_agent(self, box, goal, agent): b_cell, g_cell = box.position, goal[1] return a_star_search(self.grid, b_cell, g_cell, box=box, agent=agent)