def find_path_astar(world_map: List[str], src: Point, dst: Point, impassable: Optional[Union[str, Character]] = None, within: int = 0): if impassable is None: impassable = '' visited = [[VisitState() for x in range(len(world_map[0]))] for y in range(len(world_map))] visit(visited, src) fringe: PriorityQueue[Tuple[int, Point]] = PriorityQueue() fringe.put((0, src)) while not fringe.empty(): (_, pos) = fringe.get() if pdist(pos, dst) <= within: break succs = successors(world_map, pos, impassable) for succ in succs: if not visited[succ.y][succ.x].visited: visit(visited, succ, pos) hcost = visited[succ.y][succ.x].cost + \ pdist(succ, dst) fringe.put((hcost, succ)) if pdist(pos, dst) <= within: return reconstruct_path(visited, src, pos) else: return None
def test_pdist(self): p1 = Point(1, 2) p2 = Point(4, 6) assert pdist(p1, p2) == 5 p1 = Point(8, 3) p2 = Point(7, 4) assert pdist(p1, p2) == pytest.approx(math.sqrt(2))
def visit(visited: List[List[VisitState]], pos: Point, parent: Optional[Point] = None): visited[pos.y][pos.x] = VisitState(True, 0, parent) if parent is not None: visited[pos.y][pos.x].cost = visited[parent.y][parent.x].cost + \ pdist(parent, pos)
def visit(visited, pos, parent=None): visited[pos.y][pos.x] = {} visited[pos.y][pos.x]['cost'] = 0 visited[pos.y][pos.x]['parent'] = parent if parent is not None: visited[pos.y][pos.x]['cost'] = visited[parent.y][parent.x]['cost'] + \ pdist(parent, pos)
def find_path_astar(world, src, dst, impassable=None, within=0): if impassable is None: impassable = '' visited = [[False for x in range(world.WIDTH_TILES)] for y in range(world.HEIGHT_TILES)] visit(visited, src) fringe = PriorityQueue() fringe.put((0, src)) while not fringe.empty(): (_priority, pos) = fringe.get() if pdist(pos, dst) <= within: break succs = successors(world, pos, impassable) for succ in succs: if not visited[succ.y][succ.x]: visit(visited, succ, pos) hcost = visited[succ.y][succ.x]['cost'] + \ pdist(succ, dst) fringe.put((hcost, succ)) if pdist(pos, dst) <= within: return reconstruct_path(visited, src, pos) else: return None
def tick(self): # If we're moving in a cardinal direction, face that way if self.new_pos.x != self.world.squirrel.pos.x \ and self.new_pos.y == self.world.squirrel.pos.y: self.world.squirrel.facing = Direction.LEFT \ if self.new_pos.x < self.world.squirrel.pos.x \ else Direction.RIGHT elif self.new_pos.y != self.world.squirrel.pos.y \ and self.new_pos.x == self.world.squirrel.pos.x: self.world.squirrel.facing = Direction.UP \ if self.new_pos.y < self.world.squirrel.pos.y \ else Direction.DOWN if self.world.can_move_to(self.new_pos): energy_cost = pdist(self.new_pos, self.world.squirrel.pos) * \ self.ENERGY_LOSS_MULTIPLIER self.world.squirrel.set_energy( self.world.squirrel.energy - energy_cost) self.world.squirrel.pos = self.new_pos else: self.new_pos = self.world.squirrel.pos if self.world.squirrel.energy <= 0: self.over("You ran out of energy!")
def _within_attack_range(self): d = pdist(self.pos, self.game.world.squirrel.pos) return d <= Fox.ATTACK_DISTANCE \ and not self.game.world.is_tree(self.game.world.squirrel.pos)