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)
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
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
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
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)
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
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
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))
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)
def solve(self) -> list: search = astar.pathfinder(self.neighbors, self.distance, self.cost) return search((self.sy, self.sx), (self.ey, self.ex))
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
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
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)
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)