Example #1
0
def assign_to_quadrant(gc, unit, unit_loc):
    """
    Assigns knight to a quadrant in need of help. 
    """
    quadrant_battles = variables.quadrant_battle_locs
    assigned_knights = variables.assigned_knights

    if variables.curr_planet == bc.Planet.Earth:
        diagonal = (variables.earth_diagonal)
    else:
        diagonal = (variables.mars_diagonal)

    best_quadrant = (None, None)
    best_coeff = -float('inf')

    for quadrant in quadrant_battles:
        q_info = quadrant_battles[quadrant]
        if q_info.target_loc is not None:
            coeff = q_info.urgency_coeff("knight")
            bfs_array = variables.bfs_array
            our_coords_val = Ranger.get_coord_value(unit_loc)
            target_coords_val = Ranger.get_coord_value(q_info.target_loc)
            if bfs_array[our_coords_val, target_coords_val] != float('inf'):
                distance = bfs_array[our_coords_val, target_coords_val]
                coeff += 3 * (1 - distance / diagonal)
                if coeff > best_coeff:
                    best_quadrant = quadrant
                    best_coeff = coeff

    if best_coeff > 0:
        assigned_knights[unit.id] = quadrant_battles[best_quadrant].target_loc
        return True, assigned_knights[unit.id]
    return False, None
Example #2
0
def assign_to_quadrant(gc, unit, unit_loc):
    """
    Assigns knight to a quadrant in need of help.
    """
    quadrant_battles = variables.quadrant_battle_locs
    assigned_healers = variables.assigned_healers

    best_quadrant = (None, None)
    best_coeff = -float('inf')

    for quadrant in quadrant_battles:
        q_info = quadrant_battles[quadrant]
        coeff = q_info.urgency_coeff("healer")
        # distance =  ADD DISTANCE COEFF TOO
        if coeff > best_coeff and q_info.healer_loc is not None:
            bfs_array = variables.bfs_array
            our_coords_val = Ranger.get_coord_value(unit_loc)
            target_coords_val = Ranger.get_coord_value(q_info.healer_loc)
            if bfs_array[our_coords_val, target_coords_val] != float('inf'):
                best_quadrant = quadrant
                best_coeff = coeff

    if best_coeff > 0:
        assigned_healers[unit.id] = quadrant_battles[best_quadrant].healer_loc
        quadrant_battles[best_quadrant].assigned_healers.add(unit.id)
        return True, assigned_healers[unit.id]
    return False, None
Example #3
0
def is_accessible(unit_loc, target_loc):
    bfs_array = variables.bfs_array
    our_coords_val = Ranger.get_coord_value(unit_loc)
    target_coords_val = Ranger.get_coord_value(target_loc)
    if bfs_array[our_coords_val, target_coords_val] != float('inf'):
        return True
    return False
Example #4
0
def go_to_mars_sense(gc, unit, battle_locs, location, enemies,
                     direction_to_coord, bfs_array, targeting_units,
                     rocket_locs):
    # print('GOING TO MARS')
    signals = {}
    dir = None
    attack = None
    blink = None
    closest_enemy = None
    move_then_attack = False
    visible_enemies = False

    if len(enemies) > 0:
        visible_enemies = True
        attack = Ranger.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.mage_roles["go_to_mars"].remove(unit.id)
        return dir, attack, blink, 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.mage_roles["go_to_mars"].remove(unit.id)
        return dir, attack, blink, 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)
    else:
        target_coords = (target_loc.x, target_loc.y)
        start_coords_val = Ranger.get_coord_value(start_coords)
        target_coords_val = Ranger.get_coord_value(target_coords)
        # target_coords_thirds = (int(target_loc.x / bfs_fineness), int(target_loc.y / bfs_fineness))

        if bfs_array[start_coords_val, target_coords_val] != float('inf'):
            best_dirs = Ranger.use_dist_bfs(start_coords, target_coords,
                                            bfs_array)
            choice_of_dir = random.choice(best_dirs)
            shape = direction_to_coord[choice_of_dir]
            options = sense_util.get_best_option(shape)
            for option in options:
                if gc.can_move(unit.id, option):
                    dir = option
                    break
                    # print(dir)

    return dir, attack, blink, move_then_attack, visible_enemies, closest_enemy, signals
Example #5
0
def mage_sense(gc, unit, battle_locs, queued_paths):
    dir = None
    attack = None
    blink = None
    move_then_attack = False
    visible_enemies = False
    location = unit.location.map_location()
    enemies = gc.sense_nearby_units_by_team(location, unit.vision_range,
                                            sense_util.enemy_team(gc))
    if len(enemies) > 0:
        if unit.id in queued_paths:
            del queued_paths[unit.id]
        visible_enemies = True
        sorted_enemies = sorted(enemies,
                                key=lambda x: x.location.map_location().
                                distance_squared_to(location))
        closest_enemy = ranger.closest_among_ungarrisoned(sorted_enemies)
        print('closest enemy:', closest_enemy)
        attack = ranger.get_attack(gc, unit, location)
        print(attack)
        if attack is not None:
            print('found it here')
            if closest_enemy is not None:
                if (ranger.exists_bad_enemy(enemies) 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):
                    dir = sense_util.best_available_direction(
                        gc, unit, enemies)

        else:
            if gc.is_move_ready(unit.id):
                if closest_enemy is not None:
                    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)
                    if attack is not None:
                        move_then_attack = True
                else:
                    dir = ranger.get_explore_dir(gc, unit)

    else:
        if unit.id in queued_paths:
            if location != queued_paths[unit.id]:
                dir = ranger.optimal_direction_towards(gc, unit, location,
                                                       queued_paths[unit.id])
                return dir, attack, blink, move_then_attack, visible_enemies
            else:
                del queued_paths[unit.id]
        if len(battle_locs) > 0:
            dir, target = ranger.go_to_battle(gc, unit, battle_locs)
            queued_paths[unit.id] = target
        else:
            dir = ranger.get_explore_dir(gc, unit)

    return dir, attack, blink, move_then_attack, visible_enemies
Example #6
0
 def is_accessible_from_init_loc(self, coords):
     """
     Determines if location 'coords' is accessible from any of our initial locations. 
     """
     accessible = False
     if variables.curr_planet == bc.Planet.Earth:
         for init_loc in variables.our_init_locs:
             bfs_array = variables.bfs_array
             our_coords_val = Ranger.get_coord_value(
                 (init_loc.x, init_loc.y))
             target_coords_val = Ranger.get_coord_value(coords)
             if bfs_array[our_coords_val,
                          target_coords_val] != float('inf'):
                 accessible = True
     else:
         accessible = True
     return accessible
Example #7
0
def try_move_smartly(unit, map_loc1, map_loc2):
    if variables.gc.is_move_ready(unit.id):
        our_coords = map_loc1
        target_coords = map_loc2
        bfs_array = variables.bfs_array
        our_coords_val = Ranger.get_coord_value(our_coords)
        target_coords_val = Ranger.get_coord_value(target_coords)
        if bfs_array[our_coords_val, target_coords_val]!=float('inf'):
            best_dirs = Ranger.use_dist_bfs(our_coords, target_coords, bfs_array)
            choice_of_dir = random.choice(best_dirs)
            shape = variables.direction_to_coord[choice_of_dir]
            options = sense_util.get_best_option(shape)
            for option in options:
                if variables.gc.can_move(unit.id, option):
                    variables.gc.move_robot(unit.id, option)
                    add_new_location(unit.id, our_coords, option)
                    break
Example #8
0
    def update_healer_ideal_loc(self):
        if variables.curr_planet == bc.Planet.Earth:
            passable_locations = variables.passable_locations_earth
        else:
            passable_locations = variables.passable_locations_mars

        neighbor_quadrants = self.get_neighboring_quadrants()

        enemies = set()
        most_enemies = 0
        worst_quadrant = None
        for quadrant in neighbor_quadrants:
            if quadrant in variables.quadrant_battle_locs:
                q_enemies = variables.quadrant_battle_locs[quadrant].enemies
                enemies.update(q_enemies)
                if len(q_enemies) > most_enemies:
                    most_enemies = len(q_enemies)
                    worst_quadrant = quadrant

        if len(enemies) == 0:
            return

        worst_middle = variables.quadrant_battle_locs[worst_quadrant].middle
        furthest_away = sorted(
            list(self.quadrant_locs),
            key=lambda x: sense_util.distance_squared_between_coords(
                x, worst_middle),
            reverse=True)
        for loc in furthest_away:
            accessible = False
            if variables.curr_planet == bc.Planet.Earth:
                for init_loc in variables.our_init_locs:
                    bfs_array = variables.bfs_array
                    our_coords_val = Ranger.get_coord_value(
                        (init_loc.x, init_loc.y))
                    target_coords_val = Ranger.get_coord_value(loc)
                    if bfs_array[our_coords_val,
                                 target_coords_val] != float('inf'):
                        accessible = True
            else:
                accessible = True

            if passable_locations[loc] and accessible:
                self.healer_loc = loc
                break
Example #9
0
def get_attack(gc, unit, location, targeting_units, priority = knight_unit_priority):
    enemy_team = variables.enemy_team
    vuln_enemies = gc.sense_nearby_units_by_team(location, unit.attack_range(), enemy_team)
    if len(vuln_enemies)==0:
        return None
    #return vuln_enemies[0]
    best = None
    lowest_health = float('inf')
    for enemy in vuln_enemies:
        if enemy.id in targeting_units:
            if enemy.unit_type == variables.unit_types["knight"]:
                mult = 30 - enemy.knight_defense()
            else:
                mult = 30
            remaining_health = enemy.health - targeting_units[enemy.id] * mult
            if remaining_health > 0 and remaining_health < lowest_health:
                best = enemy
                lowest_health = remaining_health
    if best is not None:
        return best
    return max(vuln_enemies, key=lambda x: Ranger.coefficient_computation(gc, unit, x, x.location.map_location(), location))
Example #10
0
def timestep(unit):

    # last check to make sure the right unit type is running this
    if unit.unit_type != bc.UnitType.Healer:
        return
    # print('HEALER ID: ', unit.id)
    gc = variables.gc

    composition = variables.info
    direction_to_coord = variables.direction_to_coord
    bfs_array = variables.bfs_array
    enemy_team = variables.enemy_team
    my_team = variables.my_team

    assigned_healers = variables.assigned_healers  ## healer id: (cluster, best_healer_loc)
    assigned_overcharge = variables.assigned_overcharge
    overcharge_targets = variables.overcharge_targets

    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

    unit_locations = variables.unit_locations

    best_dir = None
    best_loc = None
    best_heal_target = None
    best_overcharge_target = None
    heal = False
    overcharge = False
    location = unit.location

    if location.is_on_map():
        #print(location.map_location())
        ## Add new ones to unit_locations, else just get the location
        if unit.id not in unit_locations:
            loc = unit.location.map_location()
            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, "healer")

        unit_loc = unit_locations[unit.id]

        ## Assign role
        if unit.id not in assigned_overcharge and unit.id not in assigned_healers:
            overcharge_to_total = 1
            total = len(assigned_healers) + len(assigned_overcharge)
            if total > 0:
                overcharge_to_total = len(assigned_overcharge) / total
            # Assign to overcharge if there are targets and ratio is good
            if variables.research.get_level(
                    variables.unit_types["healer"]
            ) == 3 and overcharge_to_total < 0.2 and len(
                    overcharge_targets) > 0:
                best_overcharge_target = gc.unit(overcharge_targets.pop())
                assigned_overcharge[unit.id] = best_overcharge_target
            best_heal_target = get_best_target(gc, unit, unit_loc, my_team)
            if best_heal_target is not None:
                heal = True
            assigned, best_loc = assign_to_quadrant(gc, unit, unit_loc)
            # print('assigned? ', assigned)
            # print('assigned loc: ', best_loc)
            if not assigned:
                nearby = gc.sense_nearby_units_by_team(
                    bc.MapLocation(variables.curr_planet, unit_loc[0],
                                   unit_loc[1]), 8, variables.my_team)
                best_dir = sense_util.best_available_direction(
                    gc, unit, nearby)

        ## Overcharge
        if unit.id in assigned_overcharge:
            ally = assigned_overcharge[unit.id]
            if gc.can_overcharge(unit.id, ally.id):
                overcharge = True
                best_overcharge_target = ally
        if best_heal_target is None:
            best_heal_target = get_best_target(gc, unit, unit_loc, my_team)
            if best_heal_target is not None:
                heal = True

        ## Movement
        # If sees enemies close enough then tries to move away from them
        loc = bc.MapLocation(variables.curr_planet, unit_loc[0], unit_loc[1])
        enemies = gc.sense_nearby_units_by_team(loc, unit.vision_range,
                                                enemy_team)
        if len(enemies) > 0:
            enemies = sorted(enemies,
                             key=lambda x: x.location.map_location().
                             distance_squared_to(loc))
            enemy_loc = enemies[0].location.map_location()
            best_dir = dir_away_from_enemy(gc, unit, loc, enemy_loc)
        elif variables.curr_round > 650:
            best_dir = Ranger.move_to_rocket(gc, unit, loc,
                                             variables.direction_to_coord,
                                             variables.bfs_array)
        # Otherwise, goes to locations in need of healers
        else:
            if unit.id in assigned_overcharge:
                ally = assigned_overcharge[unit.id]
                best_loc_map = ally.location.map_location()
                best_loc = (best_loc_map.x, best_loc_map.y)
            elif unit.id in assigned_healers:
                best_loc = assigned_healers[unit.id][1]

        ## Do shit
        #print(best_dir)
        #print(best_loc)
        if best_overcharge_target is not None:
            if overcharge and gc.is_overcharge_ready(unit.id):
                gc.overcharge(unit.id, best_overcharge_target.id)
                overcharged_unit = gc.unit(best_overcharge_target.id)
                if overcharged_unit.unit_type == variables.unit_types[
                        "ranger"]:
                    Ranger.timestep(overcharged_unit)
        if best_heal_target is not None:
            if heal and gc.is_heal_ready(unit.id) and gc.can_heal(
                    unit.id, best_heal_target.id):
                gc.heal(unit.id, best_heal_target.id)
        if best_dir is not None and gc.is_move_ready(unit.id) and gc.can_move(
                unit.id, best_dir):
            gc.move_robot(unit.id, best_dir)
            add_new_location(unit.id, unit_loc, best_dir)
        elif best_loc is not None and gc.is_move_ready(
                unit.id) and unit_loc != best_loc:
            try_move_smartly(unit, unit_loc, best_loc)
Example #11
0
     try:
         worker.timestep(gc, unit, info, karbonite_locations,
                         blueprinting_queue,
                         blueprinting_assignment,
                         building_assignment, current_worker_roles)
     except Exception as e:
         print('Error:', e)
         # use this to show where the error was
         traceback.print_exc()
 elif unit.unit_type == bc.UnitType.Knight:
     knight.timestep(gc, unit, info, knight_to_cluster,
                     seen_knights_ids, KNIGHT_CLUSTER_MIN,
                     constants)
 elif unit.unit_type == bc.UnitType.Ranger:
     ranger.timestep(gc, unit, info, last_turn_battle_locs,
                     next_turn_battle_locs, queued_paths,
                     ranger_roles, constants, direction_to_coord,
                     precomputed_bfs)
 elif unit.unit_type == bc.UnitType.Mage:
     mage.timestep(gc, unit, info, last_turn_battle_locs,
                   next_turn_battle_locs, queued_paths)
 elif unit.unit_type == bc.UnitType.Healer:
     healer.timestep(gc, unit, info, last_turn_battle_locs,
                     constants)
 elif unit.unit_type == bc.UnitType.Factory:
     factory.timestep(gc,
                      unit,
                      info,
                      building_assignment,
                      last_turn_battle_locs,
                      constants,
                      mining_rate=3 *
Example #12
0
def mage_sense(gc, unit, battle_locs, mage_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 mage_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
    blink = 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:
                start_time = time.time()
                if Ranger.check_radius_squares_factories(gc, location):
                    dir = Ranger.optimal_direction_towards(
                        gc, unit, location,
                        closest_enemy.location.map_location())
                elif (Ranger.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 = 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:
                    dir = Ranger.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(
        ) > 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, blink, 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, blink, move_then_attack, visible_enemies, closest_enemy, signals
Example #13
0
def timestep(unit):
    # last check to make sure the right unit type is running this
    if unit.unit_type != bc.UnitType.Knight:
        # prob should return some kind of error
        return

    gc = variables.gc

    assigned_knights = variables.assigned_knights
    quadrant_battles = variables.quadrant_battle_locs
    unit_locations = variables.unit_locations

    info = variables.info

    my_team = variables.my_team
    enemy_team = variables.enemy_team
    directions = variables.directions

    best_loc = None  ## (x,y)
    best_dir = None
    best_target = None
    location = unit.location

    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():
        if unit.id not in unit_locations:
            loc = unit.location.map_location()
            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, "knight")
            variables.knight_attacks[unit.id] = 0

        unit_loc = unit_locations[unit.id]

        ## Movement
        # If new knight assign to location
        if unit.id not in assigned_knights:
            assigned, best_loc = assign_to_quadrant(gc, unit, unit_loc)
            if not assigned:
                unit_loc_map = bc.MapLocation(variables.curr_planet,
                                              unit_loc[0], unit_loc[1])
                best_dir = Ranger.run_towards_init_loc_new(
                    gc, unit, unit_loc_map, variables.direction_to_coord)
                #nearby = gc.sense_nearby_units_by_team(bc.MapLocation(variables.curr_planet, unit_loc[0], unit_loc[1]), 8, variables.my_team)
                #best_dir = sense_util.best_available_direction(gc,unit,nearby)
        else:
            best_loc = assigned_knights[unit.id]

        ## Attack based on if in quadrant
        if best_loc is not None:
            curr_quadrant = (int(unit_loc[0] / quadrant_size),
                             int(unit_loc[1] / quadrant_size))
            best_loc_quadrant = (int(best_loc[0] / quadrant_size),
                                 int(best_loc[1] / quadrant_size))

            ## If in best quadrant already, then get best_loc towards the target
            if curr_quadrant == best_loc_quadrant:
                best_target, best_loc = get_best_target_in_quadrant(
                    gc, unit, unit_loc, knight_unit_priority)

            else:
                best_target = get_best_target(gc, unit, unit_loc,
                                              knight_unit_priority)

        ## Do shit
        # Attack
        if best_target is not None and gc.can_attack(
                unit.id, best_target.id
        ):  # checked if ready to attack in get best target
            gc.attack(unit.id, best_target.id)
            variables.knight_attacks[unit.id] += 1

        # Move
        if best_loc is not None and gc.is_move_ready(
                unit.id) and unit_loc != best_loc:
            try_move_smartly(unit, unit_loc, best_loc)
        elif best_dir is not None and gc.is_move_ready(
                unit.id) and gc.can_move(unit.id, best_dir):
            gc.move_robot(unit.id, best_dir)
            add_new_location(unit.id, unit_loc, best_dir)
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 % 3 == 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)
    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(factories)
    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()
Example #15
0
def timestep(unit):
    # last check to make sure the right unit type is running this
    if unit.unit_type != bc.UnitType.Mage:
        # prob should return some kind of error
        return
    # start_time = time.time()
    gc = variables.gc
    mage_roles = variables.mage_roles
    info = variables.info
    next_turn_battle_locs = variables.next_turn_battle_locs

    if unit.id in mage_roles["go_to_mars"] and info[6] == 0:
        mage_roles["go_to_mars"].remove(unit.id)
    if unit.id not in mage_roles["fighter"]:
        mage_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, "mage")

        # start_time = time.time()
        map_loc = location.map_location()
        if variables.curr_planet == bc.Planet.Earth and len(mage_roles["go_to_mars"]) < 14 and unit.id not in \
                mage_roles["go_to_mars"] and unit.id in mage_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)
                    mage_roles["go_to_mars"].append(unit.id)
                    mage_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 = mage_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
                Ranger.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
                Ranger.add_new_location(unit.id, (map_loc.x, map_loc.y), dir)
        """
Example #16
0
                    start_time = time.time()
                    worker.timestep(unit)
                    time_workers += (time.time() - start_time)

                except Exception as e:
                    print('Error:', e)
                    # use this to show where the error was
                    traceback.print_exc()
            elif unit.unit_type == unit_types["knight"]:
                #start_time = time.time()
                knight.timestep(unit)
                #time_knights+=(time.time()-start_time)
            elif unit.unit_type == unit_types["ranger"]:
                try:
                    start_time = time.time()
                    ranger.timestep(unit)
                    time_rangers += (time.time() - start_time)
                except Exception as e:
                    #print('RANGER ERROR.')
                    if ranger in variables.ranger_roles["go_to_mars"]:
                        variables.ranger_roles["go_to_mars"].remove(ranger)
                    elif ranger in variables.ranger_roles["fighter"]:
                        variables.ranger_roles["fighter"].remove(ranger)
                    elif ranger in variables.ranger_roles["sniper"]:
                        variables.ranger_roles["sniper"].remove(ranger)

                    traceback.print_exc()
            elif unit.unit_type == unit_types["mage"]:
                mage.timestep(unit)
            elif unit.unit_type == unit_types["healer"]:
                start_time = time.time()
Example #17
0
    #print("TIME LEFT:", gc.get_time_left_ms())
    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
    start_time = time.time()
    knight.update_battles()
    #if time.time()-start_time > 0.02:
    #    print('KNIGHT UPDATE BATTLES:', time.time()-start_time)

    start_time = time.time()
    healer.update_healers()
    #if time.time() - start_time > 0.02:
    #    print('HEALER UPDATE TIME:', time.time()-start_time)

    start_time = time.time()
    ranger.update_rangers()
    #if time.time() - start_time > 0.02:
    #    print('RANGER UPDATE TIME: ', time.time()-start_time)

    start_time = time.time()
    worker.designate_roles()
    #if time.time() - start_time > 0.02:
    #    print('DESIGNATING ROLES TIME:', time.time()-start_time)

    factory.evaluate_stockpile()
    #time_workers = 0
    #time_rangers = 0
    #time_healers = 0
    # time_factories = 0
    # time_knights = 0
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 = {}
    # 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

    # Update which ally unit id's are still alive & deaths per quadrant
    update_quadrants() # Updates enemies in quadrant & resets num dead allies

    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
    for unit in variables.my_units:
        if unit.unit_type == unit_types["worker"]:
            num_workers+=1
        elif unit.unit_type == unit_types["knight"]:
            num_knights+=1
        elif unit.unit_type == unit_types["ranger"]:
            num_rangers+=1
        elif unit.unit_type == unit_types["mage"]:
            num_mages+=1
        elif unit.unit_type == unit_types["healer"]:
            num_healers+=1
        elif unit.unit_type == unit_types["factory"]:
            num_factory+=1
        elif unit.unit_type == unit_types["rocket"]:
            num_rocket+=1
    variables.info = [num_workers, num_knights, num_rangers, num_mages, num_healers, num_factory, num_rocket]

    ## **************************************** UNITS **************************************** ## 

    ## Worker 
    variables.my_karbonite = gc.karbonite()
    variables.producing= [0, 0, 0, 0, 0]

    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

    worker.designate_roles()

    ## Rangers
    variables.targeting_units = {}
    ranger.update_rangers()

    ## Knights
    knight.update_battles()

    ## Healers
    healer.update_healers()

    # Rockets
    rocket.update_rockets()

    ## Mages


    ## Factories
    factory.evaluate_stockpile()
Example #19
0
 info = [
     num_workers, num_knights, num_rangers, num_mages, num_healers,
     num_factory, num_rocket
 ]
 for unit in gc.my_units():
     # resepective unit types execute their own AI
     if unit.unit_type == bc.UnitType.Worker:
         worker.timestep(gc, unit, info, karbonite_locations,
                         locs_next_to_terrain, blueprinting_queue,
                         building_assignment, current_worker_roles)
     elif unit.unit_type == bc.UnitType.Knight:
         knight.timestep(gc, unit, info, knight_to_cluster,
                         seen_knights_ids, KNIGHT_CLUSTER_MIN)
     elif unit.unit_type == bc.UnitType.Ranger:
         ranger.timestep(gc, unit, info, last_turn_battle_locs,
                         next_turn_battle_locs, queued_paths,
                         ranger_roles)
     elif unit.unit_type == bc.UnitType.Mage:
         mage.timestep(gc, unit, info, last_turn_battle_locs,
                       next_turn_battle_locs, queued_paths)
     elif unit.unit_type == bc.UnitType.Healer:
         healer.timestep(gc, unit, info, last_turn_battle_locs)
     elif unit.unit_type == bc.UnitType.Factory:
         factory.timestep(gc,
                          unit,
                          info,
                          building_assignment,
                          mining_rate=3 *
                          len(current_worker_roles["miner"]))
     elif unit.unit_type == bc.UnitType.Rocket:
         rocket.timestep(gc, unit, info)
Example #20
0
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
    # if variables.print_count < 10:
    #    print("Sensing nearby units:", time.time() - start_time)
    if len(enemies) > 0:
        visible_enemies = True
        closest_enemy = None
        closest_dist = -float('inf')
        for enemy in enemies:
            enemy_loc = enemy.location
            if enemy_loc.is_on_map():
                enemy_map_loc = enemy_loc.map_location()
                coeff = Ranger.coefficient_computation(gc, unit, enemy, enemy_map_loc, location)
                # dist = sense_util.distance_squared_between_maplocs(loc.map_location(), location)
                if coeff > closest_dist:
                    closest_dist = coeff
                    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, knight_unit_priority)

        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 = get_attack(gc, unit, next_turn_loc, targeting_units, knight_unit_priority)
                    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