def least_damage_spawn_location(self, game_state: GameState,
                                    location_options: List[List[int]]):
        """
        This function will help us guess which location is the safest to spawn moving units from.
        It gets the path the unit will take then checks locations on that path to 
        estimate the path's damage risk.
        """
        damages = []
        # Get the damage estimate each path will take
        for location in location_options:
            path = game_state.find_path_to_edge(location)
            damage = 0

            if path is None:
                debug_write('[DEBUG] Could not find path for location:',
                            location)
                continue

            for path_location in path:
                # Get number of enemy turrets that can attack each location and multiply by turret damage
                damage += len(
                    game_state.get_attackers(path_location, 0)) * GameUnit(
                        TURRET, game_state.config).damage_i
            damages.append(damage)

        # Now just return the location that takes the least damage
        return location_options[damages.index(min(damages))]
Example #2
0
    def repair(self,
               game_state: GameState,
               base=0.9,
               upgraded=0.97,
               locations=None):
        game_map = game_state.game_map

        to_build = self.memory["repair"]["to_build"]
        for unit in list(to_build):
            game_state.attempt_spawn(unit.unit_type, [unit.x, unit.y])
            if game_state.attempt_upgrade([unit.x, unit.y]):
                to_build.remove(unit)

        potentially_in_progress = set([(unit.x, unit.y) for unit in to_build])
        for x, y in locations or self._P1_POINTS:
            if game_map[x, y] and game_map[x, y][0].stationary:
                if not game_map[x, y][0].pending_removal:
                    unit = game_map[x, y][0]
                    repair = (unit.health / unit.max_health) < (
                        base if unit.upgraded else upgraded)
                    if repair and (unit.x,
                                   unit.y) not in potentially_in_progress:
                        if game_state.attempt_remove([x, y]):
                            to_build.add(unit)

        self.memory["repair"]["to_build"] = to_build
Example #3
0
    def attempt_actions(self, game_state: GameState):
        """
        Call on each turn to act on the finished action queue
        Takes care of adding the updated upgrade_all action
        """

        if self.change_flag:
            self.refresh_upgrade_all()

        for action in self.action_queue:
            if not action['upgrade']:
                game_state.attempt_spawn(action['unit_type'], action['locations'])
            else:
                game_state.attempt_upgrade(action['locations'])
    def mount_right_attack(self, game_state: GameState):
        # game_state.attempt_spawn(DEMOLISHER, [24, 10], num=4)

        # temp_sp = self.current_sp - 16
        # x = 13
        # y = 0
        # # by staggering like this, you prevent self destruct problems
        # debug_write("entering right attack while loop with temp_sp = " + str(temp_sp))
        # while (temp_sp > 0) and (y < self.factory_height):
        #     debug_write("iteration with x = " + str(x) + " and y = " + str(y))
        #     game_state.attempt_spawn(SCOUT, [x, y], num=20)
        #     temp_sp -= 20
        #     x -= 1
        #     y += 1
        game_state.attempt_spawn(SCOUT, [13, 0], num=1000)
 def filter_blocked_locations(self, locations: List[List[int]],
                              game_state: GameState):
     filtered = []
     for location in locations:
         if not game_state.contains_stationary_unit(location):
             filtered.append(location)
     return filtered
    def mount_left_attack(self, game_state: GameState):
        # might want to base this off of whether our wall will be intact or not; changes pathing
        # might want to make demolishers proportional to resources, rather than 4 flat
        # game_state.attempt_spawn(DEMOLISHER, [3, 10], num=4)

        # temp_sp = self.current_sp - 16
        # x = 14
        # y = 0
        # by staggering like this, you prevent self destruct problems
        # debug_write("entering left attack while loop with temp_sp = " + str(temp_sp))
        # while (temp_sp > 0) and (y < self.factory_height):
        #     debug_write("iteration with x = " + str(x) + " and y = " + str(y))
        #     game_state.attempt_spawn(SCOUT, [x, y], num=20)
        #     temp_sp -= 20
        #     x += 1
        #     y += 1
        game_state.attempt_spawn(SCOUT, [14, 0], num=1000)
Example #7
0
 def detect_own_unit(self, game_state: GameState, unit_type=None, valid_x = None, valid_y = None):
     total_units = 0
     for location in game_state.game_map:
         if game_state.contains_stationary_unit(location):
             for unit in game_state.game_map[location]:
                 if unit.player_index == 0 and (unit_type is None or unit.unit_type == unit_type) and (valid_x is None or location[0] in valid_x) and (valid_y is None or location[1] in valid_y):
                     total_units += 1
     return total_units
    def attempt_actions(self, game_state: GameState):
        """
        Call on each turn to act on the finished action queue
        Takes care of adding the updated upgrade_all action
        """

        if self.change_flag:
            self.refresh_upgrade_all(game_state)

        for action in self.action_queue:
            max_actions = action['max_num']
            taken_actions = 0
            for location in action['locations']:

                if not action['upgrade']:
                    taken_actions += game_state.attempt_spawn(
                        action['unit_type'], location)
                else:
                    taken_actions += game_state.attempt_upgrade(location)

                if taken_actions >= max_actions:
                    break
Example #9
0
    def on_turn(self, turn_state):
        """
        This function is called every turn with the game state wrapper as
        an argument. The wrapper stores the state of the arena and has methods
        for querying its state, allocating your current resources as planned
        unit deployments, and transmitting your intended deployments to the
        game engine.
        """
        game_state = GameState(self.config, turn_state)
        self.health = game_state.my_health
        if game_state.turn_number == 0:
            self.cached_health = self.health

        debug_write('Performing turn {} of your custom algo strategy'.format(game_state.turn_number))
        game_state.suppress_warnings(True)

        self.current_mp = game_state.get_resource(MP, 0)
        self.current_sp = game_state.get_resource(SP, 0)

        self.dynamic_strategy(game_state)
        self.cached_health = self.health

        game_state.submit_turn()
Example #10
0
 def send_initial_destructor(self, game_state: GameState):
     """
     Send out a demolisher to get enemy factories at the start
     """
     game_state.attempt_spawn(DEMOLISHER, [1, 12])
     game_state.attempt_spawn(INTERCEPTOR, [4, 9])
    def dynamic_strategy(self, game_state: GameState):
        """
        For defense we will use a spread out layout and some interceptors early on.
        We will place turrets near locations the opponent managed to score on.
        For offense we will use long range demolishers if they place stationary units near the enemy's front.
        If there are no stationary units to attack in the front, we will send Scouts to try and score quickly.
        """

        # initial strategy is highly dependent on expected units. Don't want to react until after we've built a little.
        if len(self.recent_scored_on_locations) and game_state.turn_number > 3:
            self.build_reactive_defense()

        # On the initial turn, try to get them with a destructor
        if game_state.turn_number == 0:
            self.send_initial_destructor(game_state)

        if game_state.turn_number == 1:
            self.utility.append_action('initial_turret_upgrades',
                                       TURRET, [[3, 13], [24, 13]],
                                       upgrade=True)
            self.utility.prioritize_action('initial_turret_upgrades')

        if game_state.turn_number == 2:
            # we want to manually manage and not upgrade these specific walls
            self.build_left_side_wall(game_state)
            # best attack we can do before having an actual structure; should have 12 mp here
            game_state.attempt_spawn(DEMOLISHER, [26, 12], num=2)
            game_state.attempt_spawn(SCOUT, [13, 0], num=100)

            self.utility.remove_action('initial_walls')
            self.utility.append_action('frontal_wall', WALL,
                                       self.get_frontal_wall())

            # put upgrades before spawns to upgrade before spawning more; these cover the rest of the game
            self.utility.append_action("upgrade_factories", '',
                                       self.factory_locations, True)
            self.utility.append_action("extra_factories", FACTORY,
                                       self.factory_locations)

        if game_state.turn_number == 3:
            # clean up from previous attack
            self.build_right_side_wall(game_state)

        if game_state.turn_number == 4:
            self.utility.remove_action('initial_turrets')
            self.utility.remove_action('initial_turret_upgrades')
            self.utility.append_action('frontal_turrets', TURRET,
                                       self.get_frontal_turrets())
            self.utility.append_action('frontal_turret_upgrades',
                                       TURRET,
                                       self.get_frontal_turrets(),
                                       upgrade=True)
            self.utility.prioritize_action('frontal_turrets')
            self.utility.prioritize_action('frontal_turret_upgrades')

        # attack logic; manually building to maintain walls if they are destroyed
        if game_state.turn_number >= 4:
            if game_state.turn_number % 6 == 4:
                self.destroy_left_side_wall(game_state)
                self.build_right_side_wall(game_state)
            if game_state.turn_number % 6 == 5:
                self.mount_left_attack(game_state)
                self.build_right_side_wall(game_state)
            if game_state.turn_number % 6 == 0:
                self.build_left_side_wall(game_state)
                self.build_right_side_wall(game_state)
            if game_state.turn_number % 6 == 1:
                self.destroy_right_side_wall(game_state)
                self.build_left_side_wall(game_state)
            if game_state.turn_number % 6 == 2:
                self.mount_right_attack(game_state)
                self.build_left_side_wall(game_state)
            if game_state.turn_number % 6 == 3:
                self.build_right_side_wall(game_state)
                self.build_left_side_wall(game_state)

        # always try to use more resources
        self.utility.attempt_actions(game_state)
Example #12
0
 def destroy_left_side_wall(self, game_state: GameState):
     game_state.attempt_remove([[1, 13]])
Example #13
0
 def destroy_right_side_wall(self, game_state: GameState):
     game_state.attempt_remove([[26, 13]])
Example #14
0
 def build_right_side_wall(self, game_state: GameState):
     game_state.attempt_spawn(WALL, [[26, 13]])
Example #15
0
 def build_left_side_wall(self, game_state: GameState):
     # game_state.attempt_spawn(WALL, [[0, 13], [1, 13], [2, 13]])
     game_state.attempt_spawn(WALL, [[1, 13]])
Example #16
0
    def dynamic_strategy(self, game_state: GameState):
        """
        For defense we will use a spread out layout and some interceptors early on.
        We will place turrets near locations the opponent managed to score on.
        For offense we will use long range demolishers if they place stationary units near the enemy's front.
        If there are no stationary units to attack in the front, we will send Scouts to try and score quickly.
        """

        # initial strategy is highly dependent on expected units. Don't want to react until after we've built a little.
        if len(self.recent_scored_on_locations) and game_state.turn_number > 3:
            self.build_reactive_defense()

        if game_state.turn_number - self.delay < 3:
            game_state.attempt_spawn(INTERCEPTOR, [3, 10], num=2)
            game_state.attempt_spawn(INTERCEPTOR, [24, 10], num=2)

        # On the initial turn, try to get them with a destructor
        if game_state.turn_number == 0:
            self.send_initial_destructor(game_state)

        if game_state.turn_number == 1:
            self.utility.append_action('initial_turret_upgrades', TURRET, [[3, 13], [24, 13]], upgrade=True)
            self.utility.prioritize_action('initial_turret_upgrades')


        if game_state.turn_number == 2:
            # we want to manually manage and not upgrade these specific walls
            self.build_left_side_wall(game_state)
            self.build_right_side_wall(game_state)

            self.utility.remove_action('initial_walls')
            self.utility.append_action('frontal_wall', WALL, self.get_frontal_wall())

            # put upgrades before spawns to upgrade before spawning more; these cover the rest of the game
            self.utility.append_action("upgrade_factories", '', self.factory_locations, True, max_num=1)
            self.utility.append_action("extra_factories", FACTORY, self.factory_locations, max_num=1)

        if game_state.turn_number == 4:
            self.utility.remove_action('initial_turrets')
            self.utility.remove_action('initial_turret_upgrades')
            self.utility.append_action('frontal_turrets', TURRET, self.get_frontal_turrets())
            self.utility.append_action('frontal_turret_upgrades', TURRET, self.get_frontal_turrets(), upgrade=True)
            self.utility.prioritize_action('frontal_turrets')
            self.utility.prioritize_action('frontal_turret_upgrades')


        if game_state.turn_number >= 5:
            game_state.attempt_spawn(TURRET, [[3, 12]])
            # game_state.attempt_spawn(WALL, [[1, 12], [2, 12], [2, 11]])

        if game_state.turn_number >= 7:
            game_state.attempt_spawn(TURRET, [[24, 12]])
            # game_state.attempt_spawn(WALL, [[26, 12], [25, 12], [25, 11]])

        if game_state.turn_number >= 12:
            # only do the following if the wall is intact; will assume we have that after turn 12
            game_state.attempt_upgrade([[3, 12], [24, 12]])
            # game_state.attempt_upgrade([[0, 13], [27, 13], [3, 12], [3, 11], [24, 12], [24, 11], [1, 12], [2, 12], [2, 11], [26, 12],
            #                             [25, 12], [25, 11]])

        if game_state.turn_number == 15:
            self.utility.append_action('secondary_wall', WALL, self.get_secondary_wall())
            self.utility.append_action('secondary_turrets', TURRET, self.get_secondary_turrets())
            self.utility.prioritize_action('secondary_wall')
            self.utility.prioritize_action('secondary_turrets')
            self.utility.prioritize_action('frontal_wall')
            self.utility.prioritize_action('frontal_turrets')

        # attack logic; manually building to maintain walls if they are destroyed
        if (game_state.turn_number % 6) == 4:
            self.attack_strategy = self.get_attack_strategy(game_state)

        if game_state.turn_number >= 4:
            self.attack_strategy(game_state)

        # always try to use more resources
        self.utility.attempt_actions(game_state)
        while game_state.get_resource(SP) >= 9:
            current_location = random.choice(self.factory_locations)
            game_state.attempt_spawn(FACTORY, current_location)
            game_state.attempt_upgrade(current_location)
 def mount_left_attack(self, game_state: GameState):
     # might want to base this off of whether our wall will be intact or not; changes pathing
     # might want to make demolishers proportional to resources, rather than 4 flat
     game_state.attempt_spawn(DEMOLISHER, [3, 10], num=4)
     game_state.attempt_spawn(SCOUT, [14, 0], num=1000)
 def mount_right_attack(self, game_state: GameState):
     game_state.attempt_spawn(DEMOLISHER, [24, 10], num=4)
     game_state.attempt_spawn(SCOUT, [13, 0], num=1000)