예제 #1
0
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
예제 #2
0
    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))
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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
예제 #6
0
    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!")
예제 #7
0
 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)