Example #1
0
def test_pypaths():
    finder = astar.pathfinder(cost=get_cost)
    p = finder(
        (0, 9), (9, 0)
    )
    print(p)
    finder = astar.pathfinder()
    p = finder(
        (0, 9), (9, 0)
    )
    print(p)
Example #2
0
def compute_length(data, dest=(31, 39)):
    finder = astar.pathfinder(neighbors=CubicleMap(
        data))  # Calculate the list of neighbors for a given node

    length, path = finder((1, 1), dest)

    return length
Example #3
0
def get_distances(ds):
    two_points_paths = ds.get_locations_permutations()
    distances = {}
    for two_points_path in two_points_paths:
        finder = astar.pathfinder(neighbors=ds.get_neighbors)
        length, path = finder(ds.locations[two_points_path[0]], ds.locations[two_points_path[1]])
        distances[two_points_path] = length
    return distances
Example #4
0
def a_star(board, start, finish):
    start_x, start_y = start
    finish_x, finish_y = finish

    finder = astar.pathfinder(neighbors=get_neighbours_builder(board),
                              cost=costConstructor(board))
    path = finder((start_x, start_y), (finish_x, finish_y))
    return path
Example #5
0
    def move_towards_target(self, target_x, target_y):
        """ Move towards the given target co-ordinates

        Args:
            target_x (int): The x position of the target
            target_y (int): The y position of the target
        """
        finder = astar.pathfinder()
        path = finder((self.player.x, self.player.y), (target_x, target_y))
        self.player.move(path[1][1][0], path[1][1][1])
    def _get_astar_pathfinder(self):
        # Used by the astar algorithm to evaluate node costs
        def cost_func(node1, node2):
            return self.get_cost(node1, node2)

        # Used by the astar algorithm to evaluate path nodes
        def neighbors_func(node):
            return self.get_valid_neighbors(node)

        # Create the astar path finder
        return astar.pathfinder(neighbors=neighbors_func, cost=cost_func)
Example #7
0
def compute2(data):
    neighbors = defaultdict(list)
    for l in data.strip().splitlines():
        obj, sat = l.split(')')
        neighbors[obj].append(sat)
        neighbors[sat].append(obj)

    finder = astar.pathfinder(neighbors=lambda c: neighbors[c],
                              distance=lambda *_: 1,
                              cost=astar.fixed_cost(1))

    length, path = finder('YOU', 'SAN')

    return length - 2
Example #8
0
    def move(self):
        start = self.pos

        def reading_order_cost(current, neighbor):
            if current == start:
                try:
                    if current.direction_to(neighbor) == Directions.UP:
                        return 1
                    elif current.direction_to(neighbor) == Directions.LEFT:
                        return 2
                    elif current.direction_to(neighbor) == Directions.RIGHT:
                        return 3
                    elif current.direction_to(neighbor) == Directions.DOWN:
                        return 4
                except ValueError:
                    pass

            return 10

        targets = []
        has_an_enemy = False
        for fighter in self.game.fighters:
            if fighter.team != self.team:
                has_an_enemy = True

                def get_free_neighbors(point):
                    for neighbor in self.game.get_neighbors(point):
                        if neighbor == fighter.pos or self.game.grid[
                                neighbor.tuple()] is None:
                            yield neighbor

                find_path = astar.pathfinder(
                    neighbors=get_free_neighbors,
                    distance=lambda start, end: start.manhattan_dist(end),
                    cost=reading_order_cost)

                length, path = find_path(self.pos, fighter.pos)
                if length is not None:
                    targets.append((length, path))

        if len(targets) > 0:
            targets = sorted(targets)
            length, path = targets[0]
            self.game.move(self, path[1])

        if not has_an_enemy:
            raise NoMoreEnemies

        return True
Example #9
0
    def init_astar(self):
        """Initialize a-star resources so that it doesn't have to calculated for each robot.

        Initialized in such a way that:
            * A diagonal paths are allowed.
            * The path calculated takes into account all obstacles in the grid.
        """
        def get_empty_neighborhood(pos):
            """A sub function to calculate empty neighbors of a point for a-star."""
            neighbors = self.grid.get_neighborhood(pos=pos, moore=True)
            return [n for n in neighbors if self.grid.is_cell_empty(n)]
        # Initialize a path finder object once for the entire factory.
        self.path_finder = astar.pathfinder(neighbors=get_empty_neighborhood,
                                            distance=astar.absolute_distance,
                                            cost=astar.fixed_cost(1))
Example #10
0
    def get_food_options(self):
        path_finder = astar.pathfinder(neighbors=self.get_neighbors)
        my_head = self.world_state.me.body[0]

        def get_path_to_food():
            # Calculate the path to each piece of food on the map
            food_paths = map(lambda food: path_finder(my_head, food),
                             self.world_state.food)

            # remove dead paths
            valid_path = filter(lambda path: path[0] is not None, food_paths)

            if len(valid_path) == 0:
                return None

            # All we care about is how long is this path and
            # what is my first step on it
            # Notice we are not passing the first point returned, that is the head of our snake
            return map(
                lambda path: FoodOption(distance=path[0],
                                        first_step=path[1][1]), valid_path)

        def get_random_path():

            while True:
                x = random.randint(0, self.world_state.map_width - 1)
                y = random.randint(0, self.world_state.map_height - 1)

                new_path = path_finder(my_head, (x, y))
                if new_path[0] is not None:
                    return new_path

                print "Testing new random path"

        food_optins = get_path_to_food()

        if food_optins is None:
            new_path = get_random_path()
            return [
                FoodOption(distance=new_path[0], first_step=new_path[1][1])
            ]

        return food_optins
 def _add_weighted_predator_actions(self, predator_pos, prey_pos,
                                    weighted_actions):
     # Only when the distance is within the partially observable range
     if not self._is_distance_in_po(predator_pos, prey_pos):
         return
     finder = astar.pathfinder(distance=astar.absolute_distance,
                               cost=self._pathfinder_weighted_cost(),
                               neighbors=self._pathfinder_grid_neighbors())
     # Find the shortest path
     cost, path = finder(tuple(predator_pos), tuple(prey_pos))
     # Get the next position in the path
     if len(path) > 1:
         next_pos = path[1]
     else:
         next_pos = path[0]
     # Get the action that leads to the next position
     action_index = self._get_pos_action(predator_pos, next_pos)
     # Add the weighted action
     weighted_actions[action_index] += 1 / (cost + 1)
Example #12
0
 def solve(self) -> list:
     search = astar.pathfinder(self.neighbors, self.distance, self.cost)
     return search((self.sy, self.sx), (self.ey, self.ex))
Example #13
0
 def shortest_path_astar(self, start, goal):
     from pypaths import astar
     finder = astar.pathfinder(cost=manhattan_dist,
                               neighbors=self.getNeighbours)
     result = finder(start, goal)
     return result
Example #14
0
def move():
    data = dict(bottle.request.json)
    width = data['width']
    height = data['height']
    grid = [[0 for x in range(width)] for y in range(height)]
    snakes = data['snakes']['data']
    food = [ptoc(x) for x in data['food']['data']]
    snake = data['you']

    # Add this snake to grid
    for idx, point in enumerate(snake['body']['data']):
        x = point['x']
        y = point['y']
        if grid[x][y] != 0:
            # Stops snake bodies from overwriting heads at the beginning
            continue
        # If this is the forst coordinate, it's the head
        if idx == 0:
            grid[x][y] = YOU_HEAD
        else:
            grid[x][y] = YOU_BODY
    # Add other snakes to grid
    for s in snakes:
        # Skip snake if dead
        if(s['health'] < 1):
            continue
        for idx, point in enumerate(s['body']['data']):
            x = point['x']
            y = point['y']
            if grid[x][y] != 0:
                # Stops snake bodies from overwriting heads at the beginning
                continue
            # If this is the forst coordinate, it's the head
            if idx == 0:
                grid[x][y] = SNAKE_HEAD
            else:
                grid[x][y] = SNAKE_BODY
    for c in food:
        x, y = c
        grid[x][y] = FOOD

    head = ptoc(snake['body']['data'][0])

    # Simple macros for each direction
    c_north = [head[0], head[1] - 1]
    c_south = [head[0], head[1] + 1]
    c_east = [head[0] + 1, head[1]]
    c_west = [head[0] - 1, head[1]]

    def find_neighbours(coord):
        x, y = coord
        neighbors = []

        if coords_safe([x-1, y], width, height, grid):
            neighbors.append((x-1, y))
        if coords_safe([x, y-1], width, height, grid):
            neighbors.append((x, y-1))
        if coords_safe([x+1, y], width, height, grid):
            neighbors.append((x+1, y))
        if coords_safe([x, y+1], width, height, grid):
            neighbors.append((x, y+1))

        return neighbors

    finder = astar.pathfinder(neighbors=find_neighbours)

    # Find nearest food
    closest_food = None
    for f in food:
        # Skip food if it's too close to the wall, unless we're desperate
        if(snake['health'] >= HEALTH_CUTOFF and (
           f[0] == 0 or
           f[0] == width - 1 or
           f[1] == 0 or
           f[1] == height - 1)):
            continue
        p = finder((head[0], head[1]), (f[0], f[1]))
        # Skip if no path to food
        if(p[0] is None):
            continue
        # Update best path if this path is better
        if(p and (closest_food is None or p[0] < len(closest_food))):
            closest_food = p[1]

    path = closest_food

    direction = ""

    if(path is not None and len(path) > 1):
        next_coord = path[1]
        if next_coord[1] < head[1]:
            direction = "up"
        elif next_coord[1] > head[1]:
            direction = "down"
        elif next_coord[0] > head[0]:
            direction = "right"
        else:
            direction = "left"

    # Fallback to safe execution
    if(not direction):
        if coords_safe(c_north, width, height, grid):
            direction = "up"
        elif coords_safe(c_south, width, height, grid):
            direction = "down"
        elif coords_safe(c_east, width, height, grid):
            direction = "right"
        else:
            direction = "left"

    result = {
        'move': direction,
        'taunt': random.choice(TAUNTS)
    }
    return result
Example #15
0
    def _generate_routes(self):
        self.paths.clear()
        self.route_elements.clear()
        edge_tiles = list(
            set([
                x for x in self.tiles
                if x[0] == 0 or x[0] == self.tile_count - 1 or x[1] == 0
            ]))
        generate_count = random.randint(self.min_route_count,
                                        self.max_route_count)
        start_tiles = random.sample(edge_tiles, generate_count)
        tile_pairs = []
        for start_tile in start_tiles:
            end_tile = random.choice([
                x for x in edge_tiles
                if x != start_tile and x[0] != start_tile[0]
                and not (x[1] == 0 and start_tile[1] == 0) and
                abs(x[0] - start_tile[0]) > 3 and abs(x[1] - start_tile[1]) > 3
            ])
            tile_pairs.append((start_tile, end_tile))
        for start, end in tile_pairs:
            while True:
                self.enabled_tiles = \
                    [x for x in random.sample(self.tiles, len(self.tiles)) if x == start or x == end or random.uniform(0, 1) > 0.3]

                finder = astar.pathfinder(neighbors=self._neighbors)
                path = finder(start, end)[1]
                if not path:
                    continue
                if start[0] == 0:
                    actual_start = (start[0] - 1, start[1])
                elif start[0] == self.tile_count - 1:
                    actual_start = (start[0] + 1, start[1])
                else:
                    actual_start = (start[0], start[1] - 1)
                path.insert(0, actual_start)
                if end[0] == 0:
                    actual_end = (end[0] - 1, end[1])
                elif end[0] == self.tile_count - 1:
                    actual_end = (end[0] + 1, end[1])
                else:
                    actual_end = (end[0], end[1] - 1)
                path.append(actual_end)
                self.paths.append(path)
                break
        for i, path in enumerate(self.paths):
            group_element = etree.Element('objectgroup')
            group_element.attrib['name'] = 'route{0:02d}'.format(i)
            id_element = etree.Element('property')
            id_element.attrib['name'] = 'id'
            id_element.attrib['value'] = str(i)
            properties_element = etree.Element('properties')
            properties_element.append(id_element)
            group_element.append(properties_element)
            tmp_path = []
            for index, waypoint in enumerate(path):
                if index == 0:
                    tmp_path.append(waypoint)
                elif index >= len(path) - 1:
                    tmp_path.append(waypoint)
                else:
                    c = path[index]
                    p = path[index - 1]
                    n = path[index + 1]
                    if p[0] == c[0] and c[0] == n[0] or p[1] == c[1] and c[
                            1] == n[1]:
                        continue
                    tmp_path.append(waypoint)
            for index, waypoint in enumerate(tmp_path):
                object_element = etree.Element('object')
                object_element.attrib['id'] = str(self.id)
                object_element.attrib['name'] = str(index)
                object_element.attrib['x'] = str(waypoint[0] * self.tile_size +
                                                 self.tile_size / 2)
                object_element.attrib['y'] = str(waypoint[1] * self.tile_size +
                                                 self.tile_size / 2)
                index_element = etree.Element('property')
                index_element.attrib['name'] = 'index'
                index_element.attrib['value'] = str(index)
                properties_element = etree.Element('properties')
                properties_element.append(index_element)
                point_element = etree.Element('point')
                object_element.append(properties_element)
                object_element.append(point_element)
                group_element.append(object_element)
                self.id += 1
            self.route_elements.append(group_element)
Example #16
0
def move():
    data = bottle.request.json
    snakes = data['board']['snakes']
    food = data['board']['food']
    height = data['board']['height']
    width = data['board']['width']
    health = data["you"]['health']
    grid = [[0 for x in range(width)] for y in range(height)]
    snake = []
    nearestfood = {'dist': -1, 'x': 0, 'y': 0}
    for i in snakes:
        snake.append(i['body'])
    """
    TODO: Using the data from the endpoint request object, your
            snake AI must choose a direction to move in.
    """
    #print(snakes)
    #print(json.dumps(data))

    directions = ['up', 'down', 'left', 'right']
    #direction = random.choice(directions)

    for s in snakes:
        you = False
        if s['id'] == data['you']['id']:
            you = True
        for idx, val in enumerate(s['body']):
            x = val['x']
            y = val['y']
            if grid[x][y] != 0:
                continue  # Stops snake bodies from overwriting heads at the beginning
            # If this is the first coordinate, it's the head
            if idx == 0:
                if you is True:
                    grid[x][y] = 11
                else:
                    grid[x][y] = 21

                    try:
                        grid[x + 1][y] = 21
                    except IndexError:
                        pass
                    try:
                        grid[x][y + 1] = 21
                    except IndexError:
                        pass
                    try:
                        grid[x - 1][y] = 21
                    except IndexError:
                        pass
                    try:
                        grid[x][y - 1] = 21
                    except IndexError:
                        pass

            elif idx == (len(data['you']['body']) - 1):
                if you is True:
                    grid[x][y] = 12
                else:
                    grid[x][y] = 22
            else:
                if you is True:
                    grid[x][y] = 10
                else:
                    grid[x][y] = 20

    head = data['you']['body'][0]

    for coords in food:
        x = coords['x']
        y = coords['y']
        grid[x][y] = 2
        hx = abs(head['x'] - x)
        hy = abs(head['y'] - y)
        xy = hx + hy
        if nearestfood['dist'] > xy or nearestfood['dist'] is -1:
            nearestfood['dist'] = xy
            nearestfood['x'] = x
            nearestfood['y'] = y
            print("closest food: " + str(nearestfood))

    print(data['turn'])

    # Simple macros for each direction
    c_north = [head['x'], head['y'] - 1]
    c_south = [head['x'], head['y'] + 1]
    c_east = [head['x'] + 1, head['y']]
    c_west = [head['x'] - 1, head['y']]

    #Check if a given coordiante is safe
    def coords_safe(coords):
        x, y = coords
        if x < 0 or x > width - 1:
            return False  # Check if coordinate is inside horizontal bounds
        if y < 0 or y > height - 1:
            return False  # Check if coordinate is inside vertical bounds
        if grid[x][y] not in [0, 2, 12]:
            return False  # Check if coordinate matches a snake body
        return True

    def find_neighbours(coords):
        x, y = coords
        neighbors = []

        if coords_safe([x - 1, y]):
            neighbors.append((x - 1, y))
        if coords_safe([x, y - 1]):
            neighbors.append((x, y - 1))
        if coords_safe([x + 1, y]):
            neighbors.append((x + 1, y))
        if coords_safe([x, y + 1]):
            neighbors.append((x, y + 1))

        return neighbors

    tail = data['you']['body'][-1]

    if health < 70:
        finder = astar.pathfinder(neighbors=find_neighbours)
        path = finder((head['x'], head['y']),
                      (nearestfood['x'], nearestfood['y']))[1]
    else:
        finder = astar.pathfinder(neighbors=find_neighbours)
        path = finder((head['x'], head['y']), (tail['x'], tail['y']))[1]

    if len(path) < 2:
        finder = astar.pathfinder(neighbors=find_neighbours)
        path = finder((head['x'], head['y']), (tail['x'], tail['y']))[1]

        if len(path) < 2:
            if coords_safe(c_north):
                direction = "up"
            elif coords_safe(c_south):
                direction = "down"
            elif coords_safe(c_east):
                direction = "right"
            else:
                direction = "left"
        else:
            next_coord = path[1]
            if next_coord[1] < head['y']:
                direction = "up"
            elif next_coord[1] > head['y']:
                direction = "down"
            elif next_coord[0] > head['x']:
                direction = "right"
            else:
                direction = "left"
    else:
        next_coord = path[1]
        if next_coord[1] < head['y']:
            direction = "up"
        elif next_coord[1] > head['y']:
            direction = "down"
        elif next_coord[0] > head['x']:
            direction = "right"
        else:
            direction = "left"

    print(direction)
    return move_response(direction)