def try_orthogonal(gc, unit, location, closest_enemy): direction_between = location.direction_to(closest_enemy) poss_1 = direction_between.rotate_right().rotate_right() poss_2 = direction_between.rotate_left().rotate_left() posses = [poss_1, poss_2] which = random.choice([0, 1]) if gc.can_move(unit.id, posses[which]): new_loc = location.add(posses[which]) if sense_util.distance_squared_between_maplocs(new_loc, closest_enemy) <50: return posses[which] other = 1 - which if gc.can_move(unit.id, posses[other]): new_loc = location.add(posses[other]) if sense_util.distance_squared_between_maplocs(new_loc, closest_enemy) < 50: return posses[other] return None
def attack_coefficient(gc, our_unit, their_unit, location, priority): distance = sense_util.distance_squared_between_maplocs(their_unit.location.map_location(), location) coeff = priority[their_unit.unit_type] if distance < attack_range_non_robots(their_unit): coeff *= sense_util.can_attack_multiplier(their_unit) coeff *= sense_util.health_multiplier(their_unit) return coeff
def attack_coefficient(gc, our_unit, our_loc, their_unit, their_loc): # generic: how appealing is their_unit to attack distance = sense_util.distance_squared_between_maplocs(our_loc, their_loc) coeff = ranger_unit_priority[their_unit.unit_type] # if distance < attack_range_non_robots(their_unit): # coeff = coeff * sense_util.can_attack_multiplier(their_unit) coeff = coeff * sense_util.health_multiplier(their_unit) return coeff
def allies_grouped(self, gc): if self.grouping_location is None or len(self.allies) == 0: return False for ally_id in self.allies: if ally_id in variables.my_unit_ids: ally = gc.unit(ally_id) if sense_util.distance_squared_between_maplocs( ally.location.map_location(), self.grouping_location) > Cluster.GROUPING_RADIUS: return False self.grouped = True return True
def get_best_location(gc, unit, unit_loc, battle_locs, planet, diagonal): """ Chooses the battle location this knight should aim for """ most_urgent = None most_urgent_coeff = -1 ## 0 - 5 for loc in battle_locs: map_loc = bc.MapLocation(planet, loc[0], loc[1]) distance_coeff = 2 * (1 - (float( sense_util.distance_squared_between_maplocs(unit_loc, map_loc)) / diagonal)) coeff = battle_locs[loc].urgent if len(battle_locs[loc].enemies) > 0: coeff = 2 * (coeff + distance_coeff) else: coeff = coeff + distance_coeff if coeff > most_urgent_coeff: most_urgent_coeff = coeff most_urgent = map_loc return most_urgent
def ranger_sense(gc, unit, battle_locs, ranger_roles, location, direction_to_coord, bfs_array, targeting_units, rocket_locs): enemies = gc.sense_nearby_units_by_team(location, unit.vision_range, variables.enemy_team) if unit.id in ranger_roles["sniper"]: return snipe_sense(gc, unit, battle_locs, location, enemies, direction_to_coord, bfs_array, targeting_units) elif unit.id in ranger_roles["go_to_mars"]: return go_to_mars_sense(gc, unit, battle_locs, location, enemies, direction_to_coord, bfs_array, targeting_units, rocket_locs) signals = {} dir = None attack = None snipe = None closest_enemy = None move_then_attack = False visible_enemies = False start_time = time.time() # if variables.print_count < 10: # print("Sensing nearby units:", time.time() - start_time) if len(enemies) > 0: visible_enemies = True start_time = time.time() closest_enemy = None closest_dist = float('inf') for enemy in enemies: loc = enemy.location if loc.is_on_map(): dist = sense_util.distance_squared_between_maplocs( loc.map_location(), location) if dist < closest_dist: closest_dist = dist closest_enemy = enemy # if variables.print_count < 10: # print("Getting closest enemy:", time.time() - start_time) # sorted_enemies = sorted(enemies, key=lambda x: x.location.map_location().distance_squared_to(location)) # closest_enemy = closest_among_ungarrisoned(sorted_enemies) start_time = time.time() attack = get_attack(gc, unit, location, targeting_units) # if variables.print_count < 10: # print("Getting attack:", time.time() - start_time) if attack is not None: if closest_enemy is not None: start_time = time.time() if check_radius_squares_factories(gc, location): dir = optimal_direction_towards( gc, unit, location, closest_enemy.location.map_location()) elif (exists_bad_enemy(closest_enemy)) or not gc.can_attack( unit.id, closest_enemy.id): # if variables.print_count < 10: # print("Checking if condition:", time.time() - start_time) start_time = time.time() dir = sense_util.best_available_direction( gc, unit, [closest_enemy]) # if variables.print_count < 10: # print("Getting best available direction:", time.time() - start_time) # and (closest_enemy.location.map_location().distance_squared_to(location)) ** ( # 0.5) + 2 < unit.attack_range() ** (0.5)) or not gc.can_attack(unit.id, attack.id): else: if gc.is_move_ready(unit.id): if closest_enemy is not None: dir = optimal_direction_towards( gc, unit, location, closest_enemy.location.map_location()) next_turn_loc = location.add(dir) attack = get_attack(gc, unit, next_turn_loc, targeting_units) if attack is not None: move_then_attack = True else: dir = run_towards_init_loc_new(gc, unit, location, direction_to_coord) # if variables.print_count < 10: # print("Getting direction:", time.time() - start_time) else: # if there are no enemies in sight, check if there is an ongoing battle. If so, go there. if len(rocket_locs) > 0 and gc.round( ) > 600 and variables.curr_planet == bc.Planet.Earth: dir = move_to_rocket(gc, unit, location, direction_to_coord, bfs_array) if dir is not None: return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals if len(battle_locs) > 0: # print('IS GOING TO BATTLE') dir = go_to_battle_new(gc, unit, battle_locs, location, direction_to_coord) # queued_paths[unit.id] = target else: # dir = move_away(gc, unit, battle_locs) if variables.curr_planet == bc.Planet.Earth: # print('IS RUNNING TOWARDS INIT LOC') dir = run_towards_init_loc_new(gc, unit, location, direction_to_coord) else: # print('EXPLORING') dir = get_explore_dir(gc, unit, location) """ elif unit.id in queued_paths: if location!=queued_paths[unit.id]: dir = optimal_direction_towards(gc, unit, location, queued_paths[unit.id]) return dir, attack, snipe, move_then_attack, visible_enemies, signals else: del queued_paths[unit.id] """ # if variables.print_count < 10: # print("regular movement:", time.time() - start_time) return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals """
def timestep(unit): # last check to make sure the right unit type is running this if unit.unit_type != bc.UnitType.Ranger: # prob should return some kind of error return #start_time = time.time() gc = variables.gc ranger_roles = variables.ranger_roles info = variables.info next_turn_battle_locs = variables.next_turn_battle_locs if unit.id in ranger_roles["go_to_mars"] and info[6] == 0: ranger_roles["go_to_mars"].remove(unit.id) if unit.id not in ranger_roles["fighter"] and unit.id not in ranger_roles[ "sniper"]: c = 13 #if info[6]>0 and len(ranger_roles["go_to_mars"]) < 4*info[6]: # ranger_roles["go_to_mars"].append(unit.id) if False and len(ranger_roles["fighter"]) > c * len( ranger_roles["sniper"]) and variables.research.get_level( bc.UnitType.Ranger) == 3: ranger_roles["sniper"].append(unit.id) else: ranger_roles["fighter"].append(unit.id) #if variables.print_count<10: #print("Preprocessing:", time.time()-start_time) location = unit.location my_team = variables.my_team targeting_units = variables.targeting_units quadrant_battles = variables.quadrant_battle_locs if variables.curr_planet == bc.Planet.Earth: quadrant_size = variables.earth_quadrant_size else: quadrant_size = variables.mars_quadrant_size if location.is_on_map(): ## Add new ones to unit_locations, else just get the location if unit.id not in variables.unit_locations: loc = unit.location.map_location() variables.unit_locations[unit.id] = (loc.x, loc.y) f_f_quad = (int(loc.x / quadrant_size), int(loc.y / quadrant_size)) quadrant_battles[f_f_quad].add_ally(unit.id, "ranger") #start_time = time.time() map_loc = location.map_location() if variables.curr_planet == bc.Planet.Earth and len( ranger_roles["go_to_mars"] ) < 14 and unit.id not in ranger_roles[ "go_to_mars"] and unit.id in ranger_roles["fighter"]: for rocket in variables.rocket_locs: target_loc = variables.rocket_locs[rocket] if sense_util.distance_squared_between_maplocs( map_loc, target_loc) < 150: variables.which_rocket[unit.id] = (target_loc, rocket) ranger_roles["go_to_mars"].append(unit.id) ranger_roles["fighter"].remove(unit.id) break #if variables.print_count < 10: # print("Preprocessing inside:", time.time() - start_time) #start_time = time.time() dir, attack_target, snipe, move_then_attack, visible_enemies, closest_enemy, signals = ranger_sense( gc, unit, variables.last_turn_battle_locs, ranger_roles, map_loc, variables.direction_to_coord, variables.bfs_array, targeting_units, variables.rocket_locs) #print("middlepart",time.time() - start_coord) #if variables.print_count < 10: # print("Sensing:", time.time() - start_time) #start_time = time.time() if visible_enemies and closest_enemy is not None: enemy_loc = closest_enemy.location.map_location() f_f_quad = (int(enemy_loc.x / 5), int(enemy_loc.y / 5)) if f_f_quad not in next_turn_battle_locs: next_turn_battle_locs[f_f_quad] = (map_loc, 1) else: next_turn_battle_locs[f_f_quad] = ( next_turn_battle_locs[f_f_quad][0], next_turn_battle_locs[f_f_quad][1] + 1) if move_then_attack: if dir != None and gc.is_move_ready(unit.id) and gc.can_move( unit.id, dir): gc.move_robot(unit.id, dir) ## CHANGE LOC IN NEW DATA STRUCTURE add_new_location(unit.id, (map_loc.x, map_loc.y), dir) if attack_target is not None and gc.is_attack_ready( unit.id) and gc.can_attack(unit.id, attack_target.id): if attack_target.id not in targeting_units: targeting_units[attack_target.id] = 1 else: targeting_units[attack_target.id] += 1 gc.attack(unit.id, attack_target.id) else: if attack_target is not None and gc.is_attack_ready( unit.id) and gc.can_attack(unit.id, attack_target.id): if attack_target.id not in targeting_units: targeting_units[attack_target.id] = 1 else: targeting_units[attack_target.id] += 1 gc.attack(unit.id, attack_target.id) if dir != None and gc.is_move_ready(unit.id) and gc.can_move( unit.id, dir): gc.move_robot(unit.id, dir) ## CHANGE LOC IN NEW DATA STRUCTURE add_new_location(unit.id, (map_loc.x, map_loc.y), dir) """
def timestep(unit): # last check to make sure the right unit type is running this if unit.unit_type != bc.UnitType.Healer: return gc = variables.gc planet = gc.planet() if planet == bc.Planet.Earth: battle_locs = variables.earth_battles diagonal = variables.earth_diagonal else: battle_locs = variables.mars_battles diagonal = variables.mars_diagonal composition = variables.info direction_to_coord = variables.direction_to_coord precomputed_bfs = variables.precomputed_bfs bfs_fineness = variables.bfs_fineness enemy_team = variables.enemy_team my_team = variables.my_team directions = variables.directions assigned_healers = variables.assigned_healers target_locs = variables.healer_target_locs best_dir = None best_loc = None best_target = None location = unit.location if location.is_on_map(): unit_loc = location.map_location() ## Healing best_target = get_best_target(gc, unit, unit_loc, my_team) #if best_target is not None: # heal_target_loc = best_target.location.map_location() # add_healer_target(gc, target_loc) # assigned_healers[unit.id] = target_loc ## Movement # If sees enemies close enough then tries to move away from them enemies = gc.sense_nearby_units_by_team(unit_loc, unit.vision_range, enemy_team) if len(enemies) > 0: enemies = sorted(enemies, key=lambda x: x.location.map_location(). distance_squared_to(unit_loc)) enemy_loc = enemies[0].location.map_location() best_dir = dir_away_from_enemy(gc, unit, unit_loc, enemy_loc) add_location = evaluate_battle_location(gc, enemy_loc, battle_locs) if add_location: battle_locs[(enemy_loc.x, enemy_loc.y)] = clusters.Cluster( allies=set(), enemies=set([enemies[0].id])) # Otherwise, goes to battle locations where they are in need of healers elif unit.id in assigned_healers: best_loc = assigned_healers[unit.id] if not sense_util.distance_squared_between_maplocs( best_loc, unit_loc) > 4: best_loc = get_best_target_loc(gc, unit, unit_loc, target_locs, planet, diagonal) ## MapLocation assigned_healers[unit.id] = best_loc elif len(target_locs) > 0: best_loc = get_best_target_loc(gc, unit, unit_loc, target_locs, planet, diagonal) ## MapLocation assigned_healers[unit.id] = best_loc # elif len(battle_locs) > 0: # best_loc = get_best_location(gc, unit, unit_loc, battle_locs, planet, diagonal) else: best_dir = get_explore_dir(gc, unit, unit_loc, directions) ## Do shit if best_target is not None and gc.is_heal_ready(unit.id): gc.heal(unit.id, best_target.id) if best_dir is not None and gc.is_move_ready(unit.id): gc.move_robot(unit.id, best_dir) elif best_loc is not None and gc.is_move_ready(unit.id): #print('GETTING BEST DIRECTION') #print(best_loc) best_dir = get_best_direction(gc, unit.id, unit_loc, best_loc, direction_to_coord, precomputed_bfs, bfs_fineness) if best_dir is not None: gc.move_robot(unit.id, best_dir)
def go_to_mars_sense(gc, unit, battle_locs, location, enemies, direction_to_coord, precomputed_bfs, targeting_units, bfs_fineness, rocket_locs): #print('GOING TO MARS') signals = {} dir = None attack = None snipe = None closest_enemy = None move_then_attack = False visible_enemies = False if len(enemies) > 0: visible_enemies = True attack = get_attack(gc, unit, location, targeting_units) start_coords = (location.x, location.y) # # rocket was launched if unit.id not in variables.which_rocket or variables.which_rocket[unit.id][1] not in variables.rocket_locs: variables.ranger_roles["go_to_mars"].remove(unit.id) return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals target_loc = variables.which_rocket[unit.id][0] # # rocket was destroyed # if not gc.has_unit_at_location(target_loc): # variables.ranger_roles["go_to_mars"].remove(unit.id) # return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals #print(unit.id) #print('MY LOCATION:', start_coords) #print('GOING TO:', target_loc) if max(abs(target_loc.x - start_coords[0]), abs(target_loc.y-start_coords[1])) == 1: rocket = gc.sense_unit_at_location(target_loc) if gc.can_load(rocket.id, unit.id): gc.load(rocket.id, unit.id) elif sense_util.distance_squared_between_maplocs(location, target_loc) < 17: #print('REALLY CLOSE') poss_dir = location.direction_to(target_loc) shape = variables.direction_to_coord[poss_dir] options = sense_util.get_best_option(shape) for option in options: if gc.can_move(unit.id, option): # print(time.time() - start_time) dir = option break if dir is None: dir = directions[8] """ result = explore.bfs_with_destination((target_loc.x, target_loc.y), start_coords, variables.gc, variables.curr_planet, variables.passable_locations_earth, variables.coord_to_direction) if result is None: variables.ranger_roles["go_to_mars"].remove(unit.id) dir = None else: dir = result """ else: start_coords = (location.x, location.y) target_coords_thirds = (int(target_loc.x / bfs_fineness), int(target_loc.y / bfs_fineness)) if (start_coords, target_coords_thirds) not in precomputed_bfs: poss_dir = location.direction_to(target_loc) shape = variables.direction_to_coord[poss_dir] options = sense_util.get_best_option(shape) for option in options: if gc.can_move(unit.id, option): # print(time.time() - start_time) dir = option break if dir is None: dir = directions[8] else: shape = direction_to_coord[precomputed_bfs[(start_coords, target_coords_thirds)]] options = sense_util.get_best_option(shape) for option in options: if gc.can_move(unit.id, option): # print(time.time() - start_time) dir = option break if dir is None: dir = directions[8] #print(dir) return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals
def ranger_sense(gc, unit, battle_locs, ranger_roles, location, direction_to_coord, bfs_array, targeting_units, rocket_locs): signals = {} dir = None attack = None snipe = None closest_enemy = None move_then_attack = False visible_enemies = False if not unit.ranger_is_sniping(): if unit.id in variables.is_sniping: del variables.is_sniping[unit.id] enemies = gc.sense_nearby_units_by_team(location, unit.vision_range, variables.enemy_team) if unit.id in ranger_roles["go_to_mars"]: return go_to_mars_sense(gc, unit, battle_locs, location, enemies, direction_to_coord, bfs_array, targeting_units, rocket_locs) # if variables.print_count < 10: # print("Sensing nearby units:", time.time() - start_time) if len(enemies) > 0: visible_enemies = True start_time = time.time() closest_enemy = None closest_dist = float('inf') for enemy in enemies: loc = enemy.location if loc.is_on_map(): dist = sense_util.distance_squared_between_maplocs( loc.map_location(), location) if dist < closest_dist: closest_dist = dist closest_enemy = enemy # if variables.print_count < 10: # print("Getting closest enemy:", time.time() - start_time) # sorted_enemies = sorted(enemies, key=lambda x: x.location.map_location().distance_squared_to(location)) # closest_enemy = closest_among_ungarrisoned(sorted_enemies) attack = get_attack(gc, unit, location, targeting_units) # if variables.print_count < 10: # print("Getting attack:", time.time() - start_time) if attack is not None: #visible_enemies = True if closest_enemy is not None: closest_enemy_loc = closest_enemy.location.map_location() if check_radius_squares_factories( gc, location ) and closest_enemy.unit_type != variables.unit_types[ "knight"]: dir = optimal_direction_towards( gc, unit, location, closest_enemy_loc) elif closest_enemy.unit_type == variables.unit_types[ "knight"] or not gc.can_attack( unit.id, closest_enemy.id): # if variables.print_count < 10: # print("Checking if condition:", time.time() - start_time) #start_time = time.time() dir = sense_util.best_available_direction( gc, unit, [closest_enemy]) # if variables.print_count < 10: # print("Getting best available direction:", time.time() - start_time) # and (closest_enemy.location.map_location().distance_squared_to(location)) ** ( # 0.5) + 2 < unit.attack_range() ** (0.5)) or not gc.can_attack(unit.id, attack.id): elif variables.num_enemies > 0.9 * variables.info[2]: #dir = None dir = sense_util.best_available_direction( gc, unit, [closest_enemy]) else: dir = None #dir = sense_util.best_available_direction(gc, unit, [closest_enemy]) #dir = try_orthogonal(gc, unit, location, closest_enemy_loc) else: num_sniping = len(variables.is_sniping) if gc.research_info().get_level( variables.unit_types["ranger"] ) == 3 and gc.is_begin_snipe_ready( unit.id) and num_sniping < 10: best_unit = None best_priority = -float("inf") for poss_enemy in variables.units: if poss_enemy.location.is_on_map( ) and poss_enemy.team != gc.team() and snipe_priority( poss_enemy) > best_priority: best_unit = poss_enemy best_priority = snipe_priority(poss_enemy) # temporary always target factories if best_priority == 5: break snipe = best_unit elif gc.is_move_ready(unit.id): if closest_enemy is not None: dir = go_to_loc( unit, location, closest_enemy.location.map_location() ) #optimal_direction_towards(gc, unit, location, closest_enemy.location.map_location()) if dir is None or dir == variables.directions[8]: dir = optimal_direction_towards( gc, unit, location, closest_enemy.location.map_location()) next_turn_loc = location.add(dir) attack = get_attack(gc, unit, next_turn_loc, targeting_units) if attack is not None: move_then_attack = True else: if variables.curr_planet == bc.Planet.Earth: # print('IS RUNNING TOWARDS INIT LOC') dir = run_towards_init_loc_new( gc, unit, location, direction_to_coord) else: # print('EXPLORING') dir = get_explore_dir(gc, unit, location) # if variables.print_count < 10: # print("Getting direction:", time.time() - start_time) else: # if there are no enemies in sight, check if there is an ongoing battle. If so, go there. if len(rocket_locs ) > 0 and variables.curr_planet == bc.Planet.Earth and ( gc.round() > 600 or (variables.num_enemies < 5 and gc.round() > 275)): dir = move_to_rocket(gc, unit, location, direction_to_coord, bfs_array) if dir is not None: return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals if len(battle_locs) > 0: # print('IS GOING TO BATTLE') dir = go_to_battle_new(gc, unit, battle_locs, location, direction_to_coord) # queued_paths[unit.id] = target else: # dir = move_away(gc, unit, battle_locs) if variables.curr_planet == bc.Planet.Earth: # print('IS RUNNING TOWARDS INIT LOC') dir = run_towards_init_loc_new(gc, unit, location, direction_to_coord) else: # print('EXPLORING') dir = get_explore_dir(gc, unit, location) """ elif unit.id in queued_paths: if location!=queued_paths[unit.id]: dir = optimal_direction_towards(gc, unit, location, queued_paths[unit.id]) return dir, attack, snipe, move_then_attack, visible_enemies, signals else: del queued_paths[unit.id] """ # if variables.print_count < 10: # print("regular movement:", time.time() - start_time) return dir, attack, snipe, move_then_attack, visible_enemies, closest_enemy, signals """
def update_variables(): gc = variables.gc ## **************************************** GENERAL **************************************** ## ## Constants variables.curr_round = gc.round() variables.num_enemies = 0 variables.print_count = 0 variables.research = gc.research_info() ## Battle locations variables.last_turn_battle_locs = variables.next_turn_battle_locs.copy() variables.next_turn_battle_locs = {} if variables.curr_round % 2 == 0: variables.update_quadrant_healer_loc = True else: variables.update_quadrant_healer_loc = False # variables.quadrant_battle_locs = {} ## Units variables.my_units = gc.my_units() variables.my_unit_ids = set([unit.id for unit in variables.my_units]) variables.units = gc.units() num_workers = num_knights = num_rangers = num_mages = num_healers = num_factory = num_rocket = 0 if variables.ranged_enemies >= 5: variables.ranged_enemies = 5 else: variables.ranged_enemies = 0 if variables.switch_to_rangers: current = gc.research_info() if current.get_level(variables.unit_types["knight"]) < 2: gc.reset_research() if variables.curr_planet == bc.Planet.Earth and len( variables.dists) == 0: gc.queue_research(bc.UnitType.Rocket) if current.get_level(variables.unit_types["worker"]) != 1: gc.queue_research(bc.UnitType.Worker) if current.get_level(variables.unit_types["ranger"]) != 1: gc.queue_research(bc.UnitType.Ranger) # 25: 50 gc.queue_research(bc.UnitType.Healer) # 25: 75 if current.get_level(variables.unit_types["rocket"]) != 1: gc.queue_research(bc.UnitType.Rocket) # 50: 125 gc.queue_research(bc.UnitType.Healer) # 100: 225 gc.queue_research(bc.UnitType.Healer) # 100: 325 gc.queue_research(bc.UnitType.Ranger) # 100: 425 gc.queue_research(bc.UnitType.Ranger) # 200: 625 gc.queue_research(bc.UnitType.Worker) # 75: 700 variables.switch_to_rangers = False # Update which ally unit id's are still alive & deaths per quadrant # start_time = time.time() update_quadrants() # Updates enemies in quadrant & resets num dead allies # print('update quadrants time: ', time.time()-start_time) if variables.curr_planet == bc.Planet.Earth: quadrant_size = variables.earth_quadrant_size else: quadrant_size = variables.mars_quadrant_size remove = set() for unit_id in variables.unit_locations: if unit_id not in variables.my_unit_ids: remove.add(unit_id) for unit_id in remove: loc = variables.unit_locations[unit_id] del variables.unit_locations[unit_id] f_f_quad = (int(loc[0] / quadrant_size), int(loc[1] / quadrant_size)) variables.quadrant_battle_locs[f_f_quad].remove_ally(unit_id) # Update % health of fighting allies in quadrant for quadrant in variables.quadrant_battle_locs: q_info = variables.quadrant_battle_locs[quadrant] q_info.update_ally_health_coefficient(gc) # Something something enemies for poss_enemy in variables.units: if poss_enemy.team != variables.my_team and poss_enemy.unit_type in variables.attacker: variables.num_enemies += 1 # Update num of ally units of each type unit_types = variables.unit_types variables.producing = [0, 0, 0, 0, 0] variables.in_order_units = [] workers = [] rangers = [] knights = [] mages = [] healers = [] factories = [] rockets = [] for unit in variables.my_units: if unit.unit_type == unit_types["worker"]: num_workers += 1 workers.append(unit) elif unit.unit_type == unit_types["knight"]: num_knights += 1 rangers.append(unit) elif unit.unit_type == unit_types["ranger"]: num_rangers += 1 knights.append(unit) elif unit.unit_type == unit_types["mage"]: num_mages += 1 mages.append(unit) elif unit.unit_type == unit_types["healer"]: num_healers += 1 healers.append(unit) elif unit.unit_type == unit_types["factory"]: num_factory += 1 factories.append(unit) if unit.is_factory_producing(): type = unit.factory_unit_type() if type == variables.unit_types["worker"]: variables.producing[0] += 1 elif type == variables.unit_types["knight"]: variables.producing[1] += 1 elif type == variables.unit_types["ranger"]: variables.producing[2] += 1 elif type == variables.unit_types["mage"]: variables.producing[3] += 1 else: variables.producing[4] += 1 elif unit.unit_type == unit_types["rocket"]: num_rocket += 1 rockets.append(unit) # process factories in order of unit production already_producing = [] not_producing = [] for fact in factories: if fact.is_factory_producing(): already_producing.append(fact) else: not_producing.append(fact) proxy = None battle_locs = variables.last_turn_battle_locs if len(battle_locs) > 0: random_choice = random.choice(list(battle_locs.keys())) corr_loc = battle_locs[random_choice][0] else: corr_loc = random.choice(variables.init_enemy_locs) not_producing.sort( key=lambda x: sense_util.distance_squared_between_maplocs( x.location.map_location(), corr_loc)) variables.info = [ num_workers, num_knights, num_rangers, num_mages, num_healers, num_factory, num_rocket ] variables.in_order_units.extend(rangers) variables.in_order_units.extend(workers) variables.in_order_units.extend(knights) variables.in_order_units.extend(mages) variables.in_order_units.extend(healers) variables.in_order_units.extend(not_producing) variables.in_order_units.extend(already_producing) variables.in_order_units.extend(rockets) ## **************************************** UNITS **************************************** ## ## Worker variables.my_karbonite = gc.karbonite() ## Income variables.worker_harvest_amount = 0 variables.past_karbonite_gain = variables.current_karbonite_gain + max( 0, 10 - int(variables.my_karbonite / 40)) variables.current_karbonite_gain = 0 # reset counter if not worker.check_if_saviour_died(): variables.saviour_worker_id = None variables.saviour_worker = False variables.saviour_blueprinted = False variables.saviour_blueprinted_id = None variables.num_unsuccessful_savior = 0 variables.saviour_time_between = 0 # start_time = time.time() worker.designate_roles() # print("designating roles time: ",time.time() - start_time) ## Rangers variables.targeting_units = {} ranger.update_rangers() ## Knights knight.update_battles() ## Healers healer.update_healers() ## Rockets rocket.update_rockets() ## Factories factory.evaluate_stockpile()
def knight_sense(gc, unit, battle_locs, knight_roles, location, direction_to_coord, bfs_array, targeting_units, rocket_locs): enemies = gc.sense_nearby_units_by_team(location, unit.vision_range, variables.enemy_team) if unit.id in knight_roles["go_to_mars"]: return go_to_mars_sense(gc, unit, battle_locs, location, enemies, direction_to_coord, bfs_array, targeting_units, rocket_locs) signals = {} dir = None attack = None javelin = None closest_enemy = None move_then_attack = False visible_enemies = False start_time = time.time() # if variables.print_count < 10: # print("Sensing nearby units:", time.time() - start_time) if len(enemies) > 0: visible_enemies = True start_time = time.time() closest_enemy = None closest_dist = float('inf') for enemy in enemies: loc = enemy.location if loc.is_on_map(): dist = sense_util.distance_squared_between_maplocs( loc.map_location(), location) if dist < closest_dist: closest_dist = dist closest_enemy = enemy # if variables.print_count < 10: # print("Getting closest enemy:", time.time() - start_time) # sorted_enemies = sorted(enemies, key=lambda x: x.location.map_location().distance_squared_to(location)) # closest_enemy = closest_among_ungarrisoned(sorted_enemies) start_time = time.time() attack = Ranger.get_attack(gc, unit, location, targeting_units) # if variables.print_count < 10: # print("Getting attack:", time.time() - start_time) if attack is not None: if closest_enemy is not None: dir = Ranger.go_to_loc( unit, location, closest_enemy.location.map_location() ) # optimal_direction_towards(gc, unit, location, closest_enemy.location.map_location()) else: if gc.is_move_ready(unit.id): if closest_enemy is not None: dir = Ranger.go_to_loc( unit, location, closest_enemy.location.map_location() ) # optimal_direction_towards(gc, unit, location, closest_enemy.location.map_location()) if dir is None or dir == variables.directions[8]: dir = Ranger.optimal_direction_towards( gc, unit, location, closest_enemy.location.map_location()) next_turn_loc = location.add(dir) attack = Ranger.get_attack(gc, unit, next_turn_loc, targeting_units) if attack is not None: move_then_attack = True else: if variables.curr_planet == bc.Planet.Earth: # print('IS RUNNING TOWARDS INIT LOC') dir = Ranger.run_towards_init_loc_new( gc, unit, location, direction_to_coord) else: # print('EXPLORING') dir = Ranger.get_explore_dir(gc, unit, location) # if variables.print_count < 10: # print("Getting direction:", time.time() - start_time) else: # if there are no enemies in sight, check if there is an ongoing battle. If so, go there. if len(rocket_locs) > 0 and gc.round( ) > 660 and variables.curr_planet == bc.Planet.Earth: dir = Ranger.move_to_rocket(gc, unit, location, direction_to_coord, bfs_array) if dir is not None: return dir, attack, javelin, move_then_attack, visible_enemies, closest_enemy, signals if len(battle_locs) > 0: # print('IS GOING TO BATTLE') dir = Ranger.go_to_battle_new(gc, unit, battle_locs, location, direction_to_coord) # queued_paths[unit.id] = target else: # dir = move_away(gc, unit, battle_locs) if variables.curr_planet == bc.Planet.Earth: # print('IS RUNNING TOWARDS INIT LOC') dir = Ranger.run_towards_init_loc_new(gc, unit, location, direction_to_coord) else: # print('EXPLORING') dir = Ranger.get_explore_dir(gc, unit, location) # if variables.print_count < 10: # print("regular movement:", time.time() - start_time) return dir, attack, javelin, move_then_attack, visible_enemies, closest_enemy, signals