def get_exit_paths(instance): start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] enemy_base = Vector2(start.x, start.y) instance.graph.add_node("enemy_base", position = (start.x, start.y), weight = 0.0) instance.graph.node["enemy_base"]["exit_path"] = 0.0 instance.graph.node["enemy_base"]["camp_target"] = 0.0 instance.graph.node["enemy_base"]["camp_location"] = 0.0 for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): instance.graph.add_edge("enemy_base", instance.terrain[j][i], weight = 1.0) our_flag_node = regressions2.get_node_index(instance, instance.game.team.flag.position) enemy_score_node = regressions2.get_node_index(instance, instance.game.enemyTeam.flagScoreLocation) enemy_flag_node = regressions2.get_node_index(instance, instance.game.enemyTeam.flag.position) our_score_node = regressions2.get_node_index(instance, instance.game.team.flagScoreLocation) b_to_flag = nx.shortest_path(instance.graph, source="enemy_base", target = our_flag_node) b_to_def = nx.shortest_path(instance.graph, source="enemy_base", target = enemy_flag_node) b_to_def2 = nx.shortest_path(instance.graph, source="enemy_base", target = our_score_node) #Calculate how the enemy is exiting from their base. exit_paths = [(b_to_flag, 10), (b_to_def, 6), (b_to_def2, 2)] for x in range(50): position = instance.level.findRandomFreePositionInBox(instance.level.area) base_seperation = position - enemy_base base_seperation = base_seperation*15/base_seperation.length() close_pos = enemy_base + base_seperation x, y = regressions2.sanitize_position(instance, close_pos) close_pos = Vector2(x, y) node_index = regressions2.get_node_index(instance, close_pos) path = nx.shortest_path(instance.graph, source="enemy_base", target = node_index) exit_paths.append((path, 4)) return exit_paths
def register_waypoints(self, bot, waypoints): edges = [] edges.append((bot.position, waypoints[0])) for waypoint_index in range(len(waypoints) - 1): edges.append( (waypoints[waypoint_index], waypoints[waypoint_index + 1])) total_nodes = set() for edge in edges: source_node = regressions2.get_node_index(self, edge[0]) target_node = regressions2.get_node_index(self, edge[1]) path = nx.shortest_path(self.graph, source=source_node, target=target_node) for node in path: total_nodes.add(node) for node_index in total_nodes: self.graph.node[node_index]["pheremone"] += 1 neighbors = self.graph.neighbors(node_index) if neighbors is not None: for neighbor_index in neighbors: self.graph.node[neighbor_index]["pheremone"] += .5 neighbors2 = self.graph.neighbors(neighbor_index) if neighbors2 is not None: for neighbor_index2 in neighbors2: self.graph.node[neighbor_index]["pheremone"] += .2
def calculate_nodes_in_range(instance, last_position, time_since, enemy_speed): max_distance = time_since * enemy_speed #used for inaccesible calculations. real_max_distance = max_distance if max_distance > instance.MAX_ENEMY_DISTANCE: max_distance = instance.MAX_ENEMY_DISTANCE if max_distance == 0.0: return set([regressions2.get_node_index(instance, last_position)]) #Get bounds for the inital square of nodes to search. left_bound = int(max(1, last_position.x - max_distance)) right_bound = int(min(88, last_position.x + max_distance)) top_bound = int(min(50, last_position.y + max_distance)) lower_bound = int(max(1, last_position.y - max_distance)) #Find nodes in initial square, and prune those that are out of range. (The square's corners.) possible_nodes = set() for x in range(left_bound, right_bound): for y in range(lower_bound, top_bound): distance_vector = Vector2(x, y) - last_position if distance_vector.length() > max_distance: continue elif instance.level.blockHeights[int(x)][int(y)] > 0: continue node_index = regressions2.get_node_index(instance, Vector2(x, y)) possible_nodes.add(node_index) if len(possible_nodes) == 0.0: return set([regressions2.get_node_index(instance, last_position)]) return possible_nodes
def get_chokes(instance, choke_candidates): #prevent writing over base space. used_set = set() start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): node_index = regressions2.get_node_index(instance, Vector2(i,j)) used_set.add(node_index) choke_dict = {} master_chokes = set() flag_node = regressions2.get_node_index(instance, instance.game.team.flag.position) spawn_node = regressions2.get_node_index(instance, get_enemy_base(instance)) shortest_length = nx.shortest_path_length(instance.graph, source=spawn_node, target=flag_node, weight="choke_covered") choke_count = 0 while shortest_length == 0.0: if len(choke_candidates) == 0.0: print "RAN OUT OF CANDIDATES!" break choke_count += 1 one_choke = set() choke_center = choke_candidates.pop() choke_vector = regressions2.get_node_vector(instance, choke_center) #Ignore potential chokes too far from their spawn. while (choke_vector.distance((get_enemy_base(instance))) > 5.0 or choke_center in used_set) and len(choke_candidates) > 0: choke_vector = regressions2.get_node_vector(instance, choke_center) choke_center = choke_candidates.pop() if len(choke_candidates) == 0: print "RAN OUT OF CANDIDATES!" return choke_dict, master_chokes if choke_vector.distance((get_enemy_base(instance))) > 5.0: print "RAN OUT OF CANDIDATES, LAST CANDIDATE DIDN'T WORK!" return choke_dict, master_chokes one_choke.add(choke_center) for x in range(4): neighbors = set() for node in one_choke: neighbors2 = instance.graph.neighbors(node) if neighbors2 is not None: for neighbor2 in neighbors2: if neighbor2 not in used_set: neighbors.add(neighbor2) one_choke = one_choke.union(neighbors) used_set = used_set.union(one_choke) for node in one_choke: instance.graph.node[node]["choke_covered"] = 1.0 neighbors = instance.graph.neighbors(node) for neighbor in neighbors: instance.graph.edge[node][neighbor]["choke_covered"] = 1.0 choke_dict[choke_center] = { "nodes": one_choke, "redundancy": 0} master_chokes = master_chokes.union(one_choke) shortest_length = nx.shortest_path_length(instance.graph, source=spawn_node, target=flag_node, weight="choke_covered") return choke_dict, master_chokes
def get_exit_paths(instance): start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] enemy_base = Vector2(start.x, start.y) instance.graph.add_node("enemy_base", position=(start.x, start.y), weight=0.0) instance.graph.node["enemy_base"]["exit_path"] = 0.0 instance.graph.node["enemy_base"]["camp_target"] = 0.0 instance.graph.node["enemy_base"]["camp_location"] = 0.0 for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): instance.graph.add_edge("enemy_base", instance.terrain[j][i], weight=1.0) our_flag_node = regressions2.get_node_index( instance, instance.game.team.flag.position) enemy_score_node = regressions2.get_node_index( instance, instance.game.enemyTeam.flagScoreLocation) enemy_flag_node = regressions2.get_node_index( instance, instance.game.enemyTeam.flag.position) our_score_node = regressions2.get_node_index( instance, instance.game.team.flagScoreLocation) b_to_flag = nx.shortest_path(instance.graph, source="enemy_base", target=our_flag_node) b_to_def = nx.shortest_path(instance.graph, source="enemy_base", target=enemy_flag_node) b_to_def2 = nx.shortest_path(instance.graph, source="enemy_base", target=our_score_node) #Calculate how the enemy is exiting from their base. exit_paths = [(b_to_flag, 10), (b_to_def, 6), (b_to_def2, 2)] for x in range(50): position = instance.level.findRandomFreePositionInBox( instance.level.area) base_seperation = position - enemy_base base_seperation = base_seperation * 15 / base_seperation.length() close_pos = enemy_base + base_seperation x, y = regressions2.sanitize_position(instance, close_pos) close_pos = Vector2(x, y) node_index = regressions2.get_node_index(instance, close_pos) path = nx.shortest_path(instance.graph, source="enemy_base", target=node_index) exit_paths.append((path, 4)) return exit_paths
def remove_spawn_nodes(instance, close_nodes): start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): node_index = regressions2.get_node_index(instance, Vector2(i,j)) if node_index in close_nodes: close_nodes.remove(node_index) return close_nodes
def weight_camp_locations_by_sight(instance, close_nodes): #Calculate the weight of all squares close to the enemy base relying on how many of the exit squares can be shot. enemy_base = get_enemy_base(instance) for node_index in close_nodes: node_position = regressions2.get_node_vector(instance, node_index) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x, y))) w.compute(node_position) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index( instance, cell_position) if node_position.distance( cell_position) < instance.level.firingDistance: #Edges don't work with our functions, and are unlikely to be actual optimum. #TODO fully debug rather than hack. if not (node_position.x < 1.0 or node_position.x > 87.0 or node_position.y < 1.0 or node_position.y > 47.0): camp_value = instance.graph.node[cell_node_index][ "camp_target"] / (cell_position.distance(enemy_base) + 3) instance.graph.node[node_index][ "camp_location"] += camp_value
def avoid_suicide_and_trades(self): #New orders for all charging bots about to suicide. if self.counter%self.COMMAND_RATE != 0 and self.counter%self.AVAIL_RATE !=0 and self.counter%self.HOLD_RATE != 0: bots = [] for bot in self.game.team.members: if bot.health > 0 and self.bots[bot.name]["command"] != None: if type(self.bots[bot.name]["command"]) == commands.Charge or type(self.bots[bot.name]["command"]) == commands.Attack: continue_command = regressions2.get_continue_command(self, bot, self.bots[bot.name]["command"]) if len(continue_command.target) == 1: if self.graph.node[regressions2.get_node_index(self, continue_command.target[0])]["p_enemy_fire"] > .4: bots.append(bot) else: for position in continue_command.target[0:int(len(continue_command.target)/2)]: if self.graph.node[regressions2.get_node_index(self, position)]["p_enemy_fire"] > .4: bots.append(bot) self.command_routine(bots)
def calculate_nodes_in_range(instance, last_position, time_since, enemy_speed): max_distance = time_since * enemy_speed if max_distance > 55: max_distance = 55 #Get bounds for the inital square of nodes to search. left_bound = int(max(1, last_position.x - max_distance)) right_bound = int(min(88, last_position.x + max_distance)) top_bound = int(min(50, last_position.y + max_distance)) lower_bound = int(max(1, last_position.y - max_distance)) ## print "enemy_speed: ", enemy_speed ## print "time_since: ", time_since ## print "left_bound: ", left_bound ## print "right_bound: " , right_bound ## print "top_bound: ", top_bound ## print "lower_bound: ", lower_bound #Find nodes in initial square, and prune those that are out of range. (The square's corners.) possible_nodes = set() for x in range(left_bound, right_bound): for y in range(lower_bound, top_bound): distance_vector = Vector2(x, y) - last_position if distance_vector.length() > max_distance: continue elif instance.level.blockHeights[int(x)][int(y)] > 0: continue #@terrain node_index = regressions2.get_node_index(instance, Vector2(x, y)) possible_nodes.add(node_index) return possible_nodes
def score_flanking_position(self, position, bot): #Score possible positions node_index = regressions2.get_node_index(self, position) they_can_shoot = self.graph.node[node_index]["p_enemy_fire"] far_from_friendlies = 0 for friendly in self.game.team.members: if friendly.health > 0.0: command = self.bots[friendly.name]["command"] if command != None and type(command) != commands.Defend: far_from_friendlies += position.distance( command.target[-1]) far_from_friendlies /= len(self.game.team.members) rough_enemy_dist = 0.0 living = 0.0 for enemy_bot in self.game.enemyTeam.members: if enemy_bot.health > 0.0: living += 1 rough_enemy_dist += position.distance(enemy_bot.position) rough_enemy_dist /= living + 1 goto_flank_brink = 0.0 try: minimum_distance = min([ position.distance(enemy_bot.position) for enemy_bot in self.game.enemyTeam.members if enemy_bot.health > 0.0 ]) except ValueError: #If the enemy are all dead, set their position is far away. minimum_distance = 100 dist_from_flank_range = abs((self.level.firingDistance) - minimum_distance) if dist_from_flank_range > -1: goto_flank_brink = 50 / (dist_from_flank_range**1.5 + 1) average_friendly_dist = 0.0 friendlies = 0.0 for friendly in self.game.team.members: if friendly.health > 0.0 and friendly != bot: friendlies += 1 average_friendly_dist += position.distance(friendly.position) average_friendly_dist /= (friendlies + 1) if average_friendly_dist > rough_enemy_dist: past_enemy = 50 else: past_enemy = 0.0 a, b, c, d, e = far_from_friendlies * 20, goto_flank_brink * 50, they_can_shoot * -500, rough_enemy_dist * -20, past_enemy * -50 ## print "far_from_friendlies: ", a ## print "goto_flank_brink: ", b ## print "they_can_shoot: ", c ## print "rough_enemy_dist: ", d ## print "distance: ", e ## print score = a + b + c + d + e return score
def remove_spawn_nodes(instance, close_nodes): start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): node_index = regressions2.get_node_index(instance, Vector2(i, j)) if node_index in close_nodes: close_nodes.remove(node_index) return close_nodes
def extrapolate(instance): points = [] bot_extraps = {} for enemy_bot in instance.enemies.keys(): if enemy_bot.health > 0.0: #Get enemy heading. extrapolation = enemy_bot.position - instance.enemies[enemy_bot] #If we have no new data on enemy location, assume they are heading in direction of flag. #TODO account for pin bots, hunt bots, and defend bots. #TODO account for probable pathing... pheremone? if extrapolation.length() == 0.0: extrapolation = instance.game.team.flag.position - enemy_bot.position if extrapolation.length() == 0.0: extrapolation = instance.game.enemyTeam.flagScoreLocation - enemy_bot.position extrapolation.normalize() #Calculate point enemy should have ran to. TODO make realistic with level speed. #TODO use visualizer to simultaneously show with visualization via circle drawings. enemy_speed = get_enemy_bot_speed(instance, enemy_bot)*.8 #.8 because not straight running lines. #Resolve points going off map by having the bot calculated as at map edge. if extrapolation.x > enemy_bot.position.x: x_bound = 87 else: x_bound = 2 if extrapolation.y > enemy_bot.position.y: y_bound = 49 else: y_bound = 2 if enemy_bot.seenlast != None: extrapolated_change = extrapolation * enemy_speed * (enemy_bot.seenlast + 1.5) else: extrapolated_change = extrapolation * enemy_speed * 1.5 if extrapolated_change.x > abs(enemy_bot.position.x - x_bound): extrapolated_change.x = x_bound if extrapolated_change.y > abs(enemy_bot.position.y - y_bound): extrapolated_change.y = y_bound final_position = enemy_bot.position + extrapolated_change x, y = regressions2.sanitize_position(instance, final_position) final_position = Vector2(x, y) node_index = regressions2.get_node_index(instance, final_position) vector = regressions2.get_node_vector(instance, node_index) points.append(vector) bot_extraps[enemy_bot] = vector if instance.DRAW_POINTS == "extrap": instance.points = points return bot_extraps
def score_flanking_position(self, position, bot): #Score possible positions node_index = regressions2.get_node_index(self, position) they_can_shoot = self.graph.node[node_index]["p_enemy_fire"] far_from_friendlies = 0 for friendly in self.game.team.members: if friendly.health > 0.0: command = self.bots[friendly.name]["command"] if command != None and type(command) != commands.Defend: far_from_friendlies += position.distance(command.target[-1]) far_from_friendlies /= len(self.game.team.members) rough_enemy_dist = 0.0 living = 0.0 for enemy_bot in self.game.enemyTeam.members: if enemy_bot.health > 0.0: living += 1 rough_enemy_dist += position.distance(enemy_bot.position) rough_enemy_dist /= living+1 goto_flank_brink = 0.0 try: minimum_distance = min([position.distance(enemy_bot.position) for enemy_bot in self.game.enemyTeam.members if enemy_bot.health > 0.0]) except ValueError: #If the enemy are all dead, set their position is far away. minimum_distance = 100 dist_from_flank_range = abs((self.level.firingDistance) - minimum_distance) if dist_from_flank_range > -1: goto_flank_brink = 50/(dist_from_flank_range**1.5+1) average_friendly_dist = 0.0 friendlies = 0.0 for friendly in self.game.team.members: if friendly.health > 0.0 and friendly != bot: friendlies += 1 average_friendly_dist += position.distance(friendly.position) average_friendly_dist /= (friendlies+1) if average_friendly_dist > rough_enemy_dist: past_enemy = 50 else: past_enemy = 0.0 a, b, c, d, e = far_from_friendlies*20, goto_flank_brink*50, they_can_shoot*-500, rough_enemy_dist*-20, past_enemy*-50 ## print "far_from_friendlies: ", a ## print "goto_flank_brink: ", b ## print "they_can_shoot: ", c ## print "rough_enemy_dist: ", d ## print "distance: ", e ## print score = a + b + c + d + e return score
def weight_camp_locations_by_choke_exposure(instance): for node in instance.choke_dict.keys(): enemy_base_square = regressions2.get_node_vector(instance, node) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x,y))) w.compute(enemy_base_square) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index(instance, cell_position) if cell_position.distance(enemy_base_square) < instance.level.firingDistance + 3: instance.graph.node[cell_node_index]["camp_location"] *= .8
def get_nodes_for_one_enemy(instance, enemy_bot): if enemy_bot.seenlast == 0.0: return set(regressions2.get_node_index(instance, enemy_bot.position)) else: #Calculate all possible squares the enemy_bot could have reached in the elapsed time. enemy_speed = get_enemy_bot_speed(instance, enemy_bot) candidates = calculate_nodes_in_range(instance, enemy_bot.position, enemy_bot.seenlast, enemy_speed) #Refresh the graph's knowledge of which squares your bots can see. update_friendly_sight(instance) #Remove candidate notes that we can already see candidates = remove_sighted_squares(instance, candidates) return candidates
def register_waypoints(self, bot, waypoints): edges = [] edges.append((bot.position, waypoints[0])) for waypoint_index in range(len(waypoints)-1): edges.append((waypoints[waypoint_index], waypoints[waypoint_index+1])) total_nodes = set() for edge in edges: source_node = regressions2.get_node_index(self, edge[0]) target_node = regressions2.get_node_index(self, edge[1]) path = nx.shortest_path(self.graph, source=source_node, target=target_node) for node in path: total_nodes.add(node) for node_index in total_nodes: self.graph.node[node_index]["pheremone"] += 1 neighbors = self.graph.neighbors(node_index) if neighbors is not None: for neighbor_index in neighbors: self.graph.node[neighbor_index]["pheremone"] += .5 neighbors2 = self.graph.neighbors(neighbor_index) if neighbors2 is not None: for neighbor_index2 in neighbors2: self.graph.node[neighbor_index]["pheremone"] += .2
def weight_camp_locations_by_base_exposure(instance): #Adjust the weight based on what squares can be seen from the enemy base. start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): enemy_base_square = Vector2(i, j) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x,y))) w.compute(enemy_base_square) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index(instance, cell_position) if cell_position.distance(enemy_base_square) < instance.level.firingDistance + 3: instance.graph.node[cell_node_index]["camp_location"] *= .8 instance.graph.node["enemy_base"]["camp_location"] = 0.0
def avoid_suicide_and_trades(self): #New orders for all charging bots about to suicide. if self.counter % self.COMMAND_RATE != 0 and self.counter % self.AVAIL_RATE != 0 and self.counter % self.HOLD_RATE != 0: bots = [] for bot in self.game.team.members: if bot.health > 0 and self.bots[bot.name]["command"] != None: if type( self.bots[bot.name] ["command"]) == commands.Charge or type( self.bots[bot.name]["command"]) == commands.Attack: continue_command = regressions2.get_continue_command( self, bot, self.bots[bot.name]["command"]) if len(continue_command.target) == 1: if self.graph.node[regressions2.get_node_index( self, continue_command.target[0] )]["p_enemy_fire"] > .4: bots.append(bot) else: for position in continue_command.target[ 0:int(len(continue_command.target) / 2)]: if self.graph.node[regressions2.get_node_index( self, position)]["p_enemy_fire"] > .4: bots.append(bot) self.command_routine(bots)
def weight_camp_locations_by_choke_exposure(instance): for node in instance.choke_dict.keys(): enemy_base_square = regressions2.get_node_vector(instance, node) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x, y))) w.compute(enemy_base_square) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index( instance, cell_position) if cell_position.distance( enemy_base_square) < instance.level.firingDistance + 3: instance.graph.node[cell_node_index]["camp_location"] *= .8
def put_exit_paths_in_graph(instance, exit_paths): enemy_base = get_enemy_base(instance) for path, weight in exit_paths: edgesinpath=zip(path[0:],path[1:]) for vt, vf in edgesinpath[:-1]: if "position" not in instance.graph.node[vf]: continue position = Vector2(*instance.graph.node[vf]["position"]) if "position" not in instance.graph.node[vt]: continue next_position = Vector2(*instance.graph.node[vt]["position"]) if position == next_position: continue x = position.x y = position.y instance.graph.node[regressions2.get_node_index(instance, Vector2(x,y))]["exit_path"] += 5.0*weight/(position.distance(enemy_base)**3+1) instance.graph.node["enemy_base"]["exit_path"] = 0.0
def get_close_nodes(instance): enemy_base = get_enemy_base(instance) close_nodes = set() enemy_base_normal_node = regressions2.get_node_index(instance, enemy_base) close_nodes.add(enemy_base_normal_node) #Calculate the weight of enemy exit squares. for x in range(25): addition_set = set() for node_index1 in close_nodes: neighbors = instance.graph.neighbors(node_index1) for node_index2 in neighbors: if node_index2 != None: addition_set.add(node_index2) close_nodes = close_nodes.union(addition_set) return close_nodes
def weight_camp_locations_by_sight(instance, close_nodes): #Calculate the weight of all squares close to the enemy base relying on how many of the exit squares can be shot. enemy_base = get_enemy_base(instance) for node_index in close_nodes: node_position = regressions2.get_node_vector(instance, node_index) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x,y))) w.compute(node_position) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index(instance, cell_position) if node_position.distance(cell_position) < instance.level.firingDistance: #Edges don't work with our functions, and are unlikely to be actual optimum. #TODO fully debug rather than hack. if not (node_position.x < 1.0 or node_position.x > 87.0 or node_position.y < 1.0 or node_position.y > 47.0): camp_value = instance.graph.node[cell_node_index]["camp_target"]/(cell_position.distance(enemy_base)+3) instance.graph.node[node_index]["camp_location"] += camp_value
def weight_camp_locations_by_base_exposure(instance): #Adjust the weight based on what squares can be seen from the enemy base. start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): enemy_base_square = Vector2(i, j) cells = [] w = visibility.Wave((88, 50), lambda x, y: instance.level.blockHeights[x][y] > 1, lambda x, y: cells.append((x, y))) w.compute(enemy_base_square) for x, y in cells: cell_position = Vector2(x, y) cell_node_index = regressions2.get_node_index( instance, cell_position) if cell_position.distance( enemy_base_square) < instance.level.firingDistance + 3: instance.graph.node[cell_node_index]["camp_location"] *= .8 instance.graph.node["enemy_base"]["camp_location"] = 0.0
def put_exit_paths_in_graph(instance, exit_paths): enemy_base = get_enemy_base(instance) for path, weight in exit_paths: edgesinpath = zip(path[0:], path[1:]) for vt, vf in edgesinpath[:-1]: if "position" not in instance.graph.node[vf]: continue position = Vector2(*instance.graph.node[vf]["position"]) if "position" not in instance.graph.node[vt]: continue next_position = Vector2(*instance.graph.node[vt]["position"]) if position == next_position: continue x = position.x y = position.y instance.graph.node[regressions2.get_node_index( instance, Vector2(x, y))]["exit_path"] += 5.0 * weight / ( position.distance(enemy_base)**3 + 1) instance.graph.node["enemy_base"]["exit_path"] = 0.0
def update_enemy_graph(instance): """Updates each node with probability of enemy presence.""" regressions2.reset_graph(instance) known_enemies = get_known_enemies(instance) at_large_enemies = get_at_large_enemies(instance, known_enemies) #Find last known whereabouts and condition of each enemy bots at_large_enemies = account_for_spawns(instance, at_large_enemies) #Account for at large enemies list complete with last seen positions and times of all unseen enemies. bot_nodes_list = [] # Stores info on which bot accounted for which nodes. for enemy_bot_info in at_large_enemies: enemy_bot = enemy_bot_info[0] last_position = enemy_bot_info[1] time_of_position = enemy_bot_info[2] #Skip if the information is very stale. if instance.game.match.timePassed - time_of_position > 20.0: print "SKIPPING DATA THAT IS OUTDATED ON BOT %s" % enemy_bot.name continue #Based on these variables, calculate nodes that the bot could occupy. nodes = get_nodes_for_one_enemy(instance, enemy_bot, last_position, time_of_position) set_probability_density(instance, nodes, last_position, enemy_bot) bot_nodes_list.append((enemy_bot, nodes)) #Account for position and probability of all definitively known enemies. known_enemy_nodes = set() for enemy_bot in known_enemies: node_index = regressions2.get_node_index(instance, enemy_bot.position) known_enemy_nodes.add(node_index) instance.graph.node[node_index]["friendly_sight"] = True instance.graph.node[node_index]["p_enemy"] = 1.0 nodes = [node_index] bot_nodes_list.append((enemy_bot, nodes)) #Set sight and cone of fire data based on all nodes enemy_bots could be present in. #TODO - counts double for overlap squares... for enemy_bot, nodes in bot_nodes_list: set_fs_density(instance, nodes, enemy_bot)
def update_enemy_graph(instance): regressions2.reset_graph(instance) known_enemies = get_known_enemies(instance) #Find last known whereabouts and condition of each enemy bots at_large_enemies = get_at_large_enemies(instance, known_enemies) #Get linear extrapolations of enemy movement bot_extraps = extrapolate(instance) store_enemy_positions(instance) #Account for at large enemies list complete with last seen positions and times of all unseen enemies. bot_nodes_list = [] # Stores info on which bot accounted for which nodes. for enemy_bot in at_large_enemies: #Skip if the information is very stale. if enemy_bot.seenlast > 25.0: continue #Based on these variables, calculate nodes that the bot could occupy. nodes = get_nodes_for_one_enemy(instance, enemy_bot) set_probability_density(instance, nodes, enemy_bot.position, enemy_bot, bot_extraps) bot_nodes_list.append((enemy_bot, nodes)) #Account for position and probability of all definitively known enemies. known_enemy_nodes = set() for enemy_bot in known_enemies: #Enemy could be at start of game. node_index = regressions2.get_node_index(instance, enemy_bot.position) known_enemy_nodes.add(node_index) instance.graph.node[node_index]["friendly_sight"] = True instance.graph.node[node_index]["p_enemy"] = 1.0 nodes = [node_index] bot_nodes_list.append((enemy_bot, nodes)) #Set sight and cone of fire data based on all nodes enemy_bots could be present in. for enemy_bot, nodes in bot_nodes_list: set_fs_density(instance, nodes, enemy_bot) print "DONE UPDATING ENEMY GRAPH"
def get_chokes(instance, choke_candidates): #prevent writing over base space. used_set = set() start, finish = instance.level.botSpawnAreas[instance.game.enemyTeam.name] for i, j in itertools.product(range(int(start.x), int(finish.x)), range(int(start.y), int(finish.y))): node_index = regressions2.get_node_index(instance, Vector2(i, j)) used_set.add(node_index) choke_dict = {} master_chokes = set() flag_node = regressions2.get_node_index(instance, instance.game.team.flag.position) spawn_node = regressions2.get_node_index(instance, get_enemy_base(instance)) shortest_length = nx.shortest_path_length(instance.graph, source=spawn_node, target=flag_node, weight="choke_covered") choke_count = 0 while shortest_length == 0.0: if len(choke_candidates) == 0.0: print "RAN OUT OF CANDIDATES!" break choke_count += 1 one_choke = set() choke_center = choke_candidates.pop() choke_vector = regressions2.get_node_vector(instance, choke_center) #Ignore potential chokes too far from their spawn. while (choke_vector.distance((get_enemy_base(instance))) > 5.0 or choke_center in used_set) and len(choke_candidates) > 0: choke_vector = regressions2.get_node_vector(instance, choke_center) choke_center = choke_candidates.pop() if len(choke_candidates) == 0: print "RAN OUT OF CANDIDATES!" return choke_dict, master_chokes if choke_vector.distance((get_enemy_base(instance))) > 5.0: print "RAN OUT OF CANDIDATES, LAST CANDIDATE DIDN'T WORK!" return choke_dict, master_chokes one_choke.add(choke_center) for x in range(4): neighbors = set() for node in one_choke: neighbors2 = instance.graph.neighbors(node) if neighbors2 is not None: for neighbor2 in neighbors2: if neighbor2 not in used_set: neighbors.add(neighbor2) one_choke = one_choke.union(neighbors) used_set = used_set.union(one_choke) for node in one_choke: instance.graph.node[node]["choke_covered"] = 1.0 neighbors = instance.graph.neighbors(node) for neighbor in neighbors: instance.graph.edge[node][neighbor]["choke_covered"] = 1.0 choke_dict[choke_center] = {"nodes": one_choke, "redundancy": 0} master_chokes = master_chokes.union(one_choke) shortest_length = nx.shortest_path_length(instance.graph, source=spawn_node, target=flag_node, weight="choke_covered") return choke_dict, master_chokes