Exemple #1
0
    def build_tech_lab_barracks(self, obs):
        """
            Builds a tech lab addon at a barracks.
        """
        new_action = [actions.FUNCTIONS.no_op()]
        barracks = HelperClass.get_units(self, obs, units.Terran.Barracks)

        if self.reqSteps == 0:
            self.reqSteps = 4

        elif self.reqSteps == 4:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        elif self.reqSteps == 3:
            if len(barracks) > 0 and HelperClass.not_in_progress(
                    self, obs, units.Terran.Barracks):
                new_action = [
                    actions.FUNCTIONS.select_point(
                        "select", (HelperClass.sigma(
                            barracks[0].x), HelperClass.sigma(barracks[0].y)))
                ]
        elif self.reqSteps == 2:
            if len(barracks) > 0:
                if HelperClass.is_unit_selected(self, obs,
                                                units.Terran.Barracks):
                    if HelperClass.do_action(
                            self, obs,
                            actions.FUNCTIONS.Build_TechLab_Barracks_quick.id):
                        new_action = [
                            actions.FUNCTIONS.Build_TechLab_Barracks_quick(
                                "now")
                        ]
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
    def build_reaper(self, obs):
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            new_action = HelperClass.select_all_buildings(obs)

        if self.reqSteps == 3:
            if len(obs.observation.multi_select > 0):
                for i in range(len(obs.observation.multi_select)):
                    if obs.observation.multi_select[i].unit_type == units.Terran.Barracks or \
                            obs.observation.multi_select[i].unit_type == units.Terran.BarracksTechLab or \
                            obs.observation.multi_select[i].unit_type == units.Terran.BarracksReactor:
                        new_action = [
                            actions.FUNCTIONS.select_unit(
                                "select_all_type", i)
                        ]
                        break

        if self.reqSteps == 2:
            if HelperClass.is_unit_selected(self, obs, units.Terran.Barracks) or \
                    HelperClass.is_unit_selected(self, obs, units.Terran.BarracksTechLab) or \
                    HelperClass.is_unit_selected(self, obs, units.Terran.BarracksReactor):
                if HelperClass.do_action(
                        self, obs, actions.FUNCTIONS.Train_Reaper_quick.id):
                    new_action = [actions.FUNCTIONS.Train_Reaper_quick("now")]

        # One step is being intentionally left blank.
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #3
0
    def build_starport(self, obs):
        """
            Builds a starport.
        """
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        elif self.reqSteps == 3:
            new_action = HelperClass.select_scv(self, obs)

        elif self.reqSteps == 2:  # Moves camera twice because select_scv can also move camera
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        elif self.reqSteps == 1:
            coordinates = BuildOrders.find_placement(self,
                                                     obs,
                                                     building_radius=6,
                                                     maximum_searches=10,
                                                     sampling_size=9)

            if coordinates is not None:
                new_action = HelperClass.place_building(
                    self, obs, units.Terran.Starport, coordinates[0],
                    coordinates[1])

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
        """
Exemple #4
0
    def count_army(self, obs):
        """Selects all army units and counts them. Currently only counts marines.
                :param obs: The observer.
        """
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 2

        if self.reqSteps == 2:
            self.reqSteps = 1
            if actions.FUNCTIONS.select_army.id in obs.observation.available_actions:
                new_action = [actions.FUNCTIONS.select_army("select")]
            else:
                # Fulhack, men detta gör så att attack selector alltid kan göra detta först.
                self.reqSteps = -1

        elif self.reqSteps == 1:
            if HelperClass.is_unit_selected(self, obs, units.Terran.Marine):
                self.marine_count = 0
                for i in range(len(obs.observation.multi_select)):
                    if obs.observation.multi_select[
                            i].unit_type == units.Terran.Marine:
                        self.marine_count += 1

            # Fulhack, men detta gör så att attack selector alltid kan göra detta först.
            self.reqSteps = -1

        ActionSingleton().set_action(new_action)
    def find_all_command_centers(self, obs, expo_locations):

        if len(self.command_centers_pos) == 0:
            for camera_coord in expo_locations:
                if HelperClass.check_minimap_for_units(self, obs, camera_coord):
                    self.command_centers_pos.append(camera_coord)

        if len(self.command_centers_pos) != self.num_command_centers:

            if self.camera_moved:
                if len(HelperClass.get_units(self, obs, units.Terran.CommandCenter)) == 0:
                    del self.command_centers_pos[self.command_center_counting_index]
                else:
                    self.command_center_counting_index += 1

            if not self.camera_moved:
                self.camera_moved = True

            if len(self.command_centers_pos) == self.num_command_centers \
                    or self.command_center_counting_index >= len(self.command_centers_pos):
                self.all_command_centers_found = True
                self.camera_moved = False

            else:
                camera_coord = self.command_centers_pos[self.command_center_counting_index]

                new_action = [actions.FUNCTIONS.move_camera(camera_coord)]
                ActionSingleton().set_action(new_action)

        else:
            self.all_command_centers_found = True

        return
Exemple #6
0
    def retreat(self, obs, location=None):
        """Selects all army units and issues a move order.

                :param obs: The observer.
                :param location: The desired location to move to [y, x] in minimap coordinates.
                                   If None, it defaults to base_location.
                """
        new_action = [actions.FUNCTIONS.no_op()]

        if location is None:
            location = [32, 32]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 3:
            if actions.FUNCTIONS.select_army.id in obs.observation.available_actions:
                new_action = [actions.FUNCTIONS.select_army("select")]

        if self.reqSteps == 2:
            if actions.FUNCTIONS.Move_minimap.id in obs.observation.available_actions:
                self.action_finished = True
                new_action = [
                    actions.FUNCTIONS.Move_minimap("now",
                                                   [location[0], location[1]])
                ]

        # One step is being intentionally left blank.
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
    def no_op(self, obs):

        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #8
0
    def build_barracks(self, obs, build_location):
        """
            Builds a barracks.
        """
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        elif self.reqSteps == 3:
            new_action = HelperClass.select_scv(self, obs)

        elif self.reqSteps == 2:  # Moves camera twice because select_scv can also move camera
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        elif self.reqSteps == 1:

            place_location = BuildOrders.find_placement_buildplacment \
                (self, obs, building_radius=7, build_locations=build_location)
            if place_location is not None:
                new_action = HelperClass.place_building(
                    self, obs, units.Terran.Barracks, place_location[0],
                    place_location[1])
                self.reqSteps -= 1
                ActionSingleton().set_action(new_action)
                return
            coordinates = BuildOrders.find_placement(self,
                                                     obs,
                                                     building_radius=6,
                                                     maximum_searches=1000,
                                                     sampling_size=1)

            if coordinates is not None:
                new_action = HelperClass.place_building(
                    self, obs, units.Terran.Barracks, coordinates[0],
                    coordinates[1])

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #9
0
    def build_supply_depot(self, obs, build_location):
        """
            Builds a supply depot.
        """
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        if self.reqSteps == 3:
            HelperClass.get_current_minimap_location(obs)
            new_action = HelperClass.select_scv(self, obs)

        if self.reqSteps == 2:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        if self.reqSteps == 1:
            place_location = BuildOrders.find_placement_buildplacment \
                (self, obs, building_radius=2, build_locations=build_location)
            if place_location is not None:
                new_action = HelperClass.place_building(
                    self, obs, units.Terran.SupplyDepot, place_location[0],
                    place_location[1])
                ActionSingleton().set_action(new_action)
                self.reqSteps -= 1
                return

            for loop in range(20):
                x = random.randint(2, 82)
                y = random.randint(2, 82)
                if BuildOrders.is_valid_placement(self,
                                                  obs, (x, y),
                                                  building_radius=2):
                    new_action = HelperClass.place_building(
                        self, obs, units.Terran.SupplyDepot, x, y)
                break

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
    def update_state(self, bot_obj, obs):
        """
        Updates the state and adds up to 1 production facility to control group. Always takes 4 steps to execute.
        :param bot_obj: The agent
        :param obs: The observation
        :return: Actions
        """
        new_action = [actions.FUNCTIONS.no_op()]  # No action by default

        if bot_obj.reqSteps == 0:
            bot_obj.reqSteps = 3
            new_action = [actions.FUNCTIONS.select_control_group("recall", 9)]

        # Section for adding unselected production building to control group 9.
        # It only adds one building per state update to keep state update lengths consistent.
        # When at this stage, control group 9 should be selected.
        # This section should be ran even when the control group is correct.
        elif bot_obj.reqSteps == 3:
            unselected_production = self.get_unselected_production_buildings(obs, on_screen=False)
            if len(unselected_production) > 0:
                unit = random.choice(unselected_production)
                new_action = HelperClass.move_screen(obs, (unit.x, unit.y))
            bot_obj.reqSteps = 2

        elif bot_obj.reqSteps == 2:
            unselected_production = self.get_unselected_production_buildings(obs, on_screen=True)
            if len(unselected_production) > 0:
                unit = random.choice(unselected_production)
                new_action = [actions.FUNCTIONS.select_point(
                    "select",
                    (HelperClass.sigma(unit.x+random.randint(0, 3)),
                     HelperClass.sigma(unit.y+random.randint(0, 3))))]
            bot_obj.reqSteps = 1

        elif bot_obj.reqSteps == 1:
            # single_select is an array of zeros if nothing is selected.
            # The following line checks for when hp > 0 (i.e. a unit is actually selected)
            if obs.observation.single_select[0][2] > 0:
                if (obs.observation.single_select[0].unit_type == units.Terran.CommandCenter or
                        obs.observation.single_select[0].unit_type == units.Terran.Barracks or
                        obs.observation.single_select[0].unit_type == units.Terran.Factory or
                        obs.observation.single_select[0].unit_type == units.Terran.Starport):
                    new_action = [actions.FUNCTIONS.select_control_group("append", 9)]
            bot_obj.reqSteps = 0

            # Update the score and reward

            bot_obj.game_state_updated = True

        ActionSingleton().set_action(new_action)
Exemple #11
0
    def scout(self, obs):
        """Selects a random SCV and issues a move order to an enemy base.
                :param obs: The observer.
        """
        new_action = [actions.FUNCTIONS.no_op()]
        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            if obs.observation.player.idle_worker_count > 0:
                new_action = [
                    actions.FUNCTIONS.select_idle_worker(
                        "select", obs, units.Terran.SCV)
                ]
            elif actions.FUNCTIONS.move_camera.id in obs.observation.available_actions:
                new_action = [
                    HelperClass.move_camera_to_base_location(self, obs)
                ]

        if self.reqSteps == 3:
            if not HelperClass.is_unit_selected(self, obs, units.Terran.SCV):
                new_action = HelperClass.select_scv(self, obs)

        if self.reqSteps == 2:
            if HelperClass.is_unit_selected(self, obs, units.Terran.SCV):
                if actions.FUNCTIONS.Move_minimap.id in obs.observation.available_actions:
                    if self.start_top:
                        self.scout_loc = random.choice(
                            Coordinates.EXPO_LOCATIONS2 +
                            [Coordinates.START_LOCATIONS[1]])
                    else:
                        self.scout_loc = random.choice(
                            Coordinates.EXPO_LOCATIONS2 +
                            [Coordinates.START_LOCATIONS[0]])

                    self.last_scout = self.steps
                    self.action_finished = True
                    new_action = [
                        actions.FUNCTIONS.Move_minimap("now", self.scout_loc)
                    ]

        # One step is being intentionally left blank.
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #12
0
    def transform_vikings_to_air(self, obs):
        """ Transforms all available Vikings to their air mode (Fighter mode)
                :param obs: The observer.
        """
        new_action = [actions.FUNCTIONS.no_op()]
        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            if actions.FUNCTIONS.select_army.id in obs.observation.available_actions:
                new_action = [actions.FUNCTIONS.select_army("select")]

        if self.reqSteps == 3:
            vikings_ground = [
                vikings for vikings in obs.observation.multi_select
                if vikings.unit_type == units.Terran.VikingAssault
            ]
            if len(vikings_ground) > 0:
                if HelperClass.do_action(self, obs,
                                         actions.FUNCTIONS.select_unit.id):
                    for i in range(len(obs.observation.multi_select)):
                        if obs.observation.multi_select[
                                i].unit_type == units.Terran.VikingAssault:
                            new_action = [
                                actions.FUNCTIONS.select_unit(
                                    "select_all_type", i)
                            ]
                            break

        if self.reqSteps == 2:
            if HelperClass.do_action(
                    self, obs,
                    actions.FUNCTIONS.Morph_VikingFighterMode_quick.id):
                new_action = [
                    actions.FUNCTIONS.Morph_VikingFighterMode_quick("now")
                ]
                self.action_finished = True

        # One step is being intentionally left blank.
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
    def step(self, obs):
        super(TestAttack, self).step(obs)
        action = actions.FUNCTIONS.no_op()
        if obs.first():
            start_y, start_x = (obs.observation.feature_minimap.player_relative
                                == features.PlayerRelative.SELF).nonzero()
            xmean = start_x.mean()
            ymean = start_y.mean()

            self.base_location = (xmean, ymean)

        if self.reqSteps == 0 and self.has_attacked:
            self.attacking = False

        if self.reqSteps == 0 and not self.has_attacked:
            self.attacking = True
            self.has_attacked = True

        if self.attacking:
            ArmyControlController.attack(self, obs)
            action = ActionSingleton().get_action()

        return action
    def step(self, obs, epsilon, episode):
        super(AiBot, self).step(obs)
        self.epsilon = epsilon
        self.episode = episode

        # first step
        if obs.first():
            # Räknaren resettas inte mellan games/episoder. Vet ej om detta är en bra lösning.
            self.steps = 0
            start_y, start_x = (obs.observation.feature_minimap.player_relative
                                == features.PlayerRelative.SELF).nonzero()
            xmean = start_x.mean()
            ymean = start_y.mean()

            self.base_location = (xmean, ymean)

            if xmean <= 31 and ymean <= 31:
                self.start_top = True
                self.attack_coordinates = Coordinates.START_LOCATIONS[1]
                self.base_location = Coordinates.START_LOCATIONS[0]
            else:
                self.start_top = False
                self.attack_coordinates = Coordinates.START_LOCATIONS[0]
                self.base_location = Coordinates.START_LOCATIONS[1]

            self.game_state = State(self)

        HelperClass.find_the_camera_postion(self, obs)

        if HelperClass.check_building_at_position(
                self, obs,
                Buildsingelton().get_location()):
            HelperClass.move_camera_to_base_location(self, obs)
            self.build_States = BuildFacade.set_up(self, obs,
                                                   self.base_location)

            self.build_state_reward = self.build_States[0][0]
            self.build_state = self.build_States[0][1]
            Buildsingelton().set_location(self.build_state)

            self.action_state = self.build_States[0][2]

            self.old_score = self.build_States[1]

            self.build_state = self.build_States[2]
            self.build_space = len(self.build_state)

            #self.build_network = BuildNetwork(self.build_state_reward,self.build_state, self.action_state, epsilon)

            #BuildNetwork.predict_neural_network(self.build_network, self.build_States)

        self.build_location = Buildsingelton().get_location()

        action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0 or self.reqSteps == -1:
            self.earlier_action = self.next_action
            self.next_action = Selector.selector(self, obs)

        if self.next_action == "updateState":
            self.game_state.update_state(self, obs)
            action = ActionSingleton().get_action()

        if self.next_action == "expand":
            BuildOrdersController.build_expand(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_scv":  # build scv
            UnitBuildOrdersController.build_scv(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "distribute_scv":  # Har inte gjort någon controller än
            if self.reqSteps == 0:
                self.DistributeSCVInstance = DistributeSCV()
            self.DistributeSCVInstance.distribute_scv(self, obs,
                                                      self.base_location)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_supply_depot":  # build supply depot
            BuildOrdersController.build_supply_depot(self, obs,
                                                     self.build_location)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_barracks":
            BuildOrdersController.build_barracks(self, obs,
                                                 self.build_location)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_refinery":
            BuildOrdersController.build_refinery(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "return_scv":
            BuildOrdersController.return_scv(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_marine":
            UnitBuildOrdersController.train_marines(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_marauder":
            UnitBuildOrdersController.train_marauder(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_reaper":
            UnitBuildOrdersController.train_reaper(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_hellion":
            UnitBuildOrdersController.train_hellion(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_medivac":
            UnitBuildOrdersController.train_medivac(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_viking":
            UnitBuildOrdersController.train_viking(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "army_count":
            ArmyControlController.count_army(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "attack":
            ArmyControlController.attack(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_factory":
            BuildOrdersController.build_factory(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_starport":
            BuildOrdersController.build_starport(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "build_tech_lab_barracks":
            BuildOrdersController.build_tech_lab_barracks(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "retreat":
            ArmyControlController.retreat(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "scout":
            ArmyControlController.scout(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "transform_vikings_to_ground":
            ArmyControlController.transform_vikings_to_ground(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "transform_vikings_to_air":
            ArmyControlController.transform_vikings_to_air(self, obs)
            action = ActionSingleton().get_action()

        elif self.next_action == "no_op":
            HelperClass.no_op(self, obs)
            action = ActionSingleton().get_action()

        return action[0]
Exemple #15
0
    def build_refinery(self, obs):
        """
            Builds a refinery in any base with a command center.
        """
        # TODO: Maybe should check for depleted geysers
        # TODO: Once stumbled upon a bug where it started to build refineries in the middle of the map. Haven't tried
        # to fix it.
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            new_action = [actions.FUNCTIONS.move_camera(self.base_location)]

        if self.reqSteps == 3:
            new_action = HelperClass.select_scv(self, obs)

        # This step finds a vacant vespene geyser near a command center and moves the camera there.
        # The center of a Command Center must be about 8 in-game units away from a geyser.
        # The feature screen is 24x24 in-game units or 84x84 screen units.
        # With a margin, a geyser will be less than 9.5 * 84/24 screen units from its Command Center (or half a screen)
        # That's how this code judges if a geyser belongs to a base.
        if self.reqSteps == 2:
            geyser_distance = (9.5 * 84 / 24)**2
            all_geysers = [
                u for u in obs.observation.raw_units
                if u.unit_type == units.Neutral.VespeneGeyser
            ]
            all_refineries = [
                u for u in obs.observation.raw_units
                if u.unit_type == units.Terran.Refinery and u.alliance == 1
            ]
            all_command_centers = [
                u for u in obs.observation.raw_units if
                u.unit_type == units.Terran.CommandCenter and u.alliance == 1
            ]
            selected_geyser = []

            if len(all_command_centers) > 0:
                cc_pos = [(cc.x, cc.y) for cc in all_command_centers]
                if len(all_refineries) > 0:
                    refinery_pos = [(ref.x, ref.y) for ref in all_refineries]
                    # Find CCs with at least one vacant geyser
                    for i in range(len(all_command_centers)):
                        cc = cc_pos[i]
                        base_refineries = 0
                        # Finds the number of refineries belonging to a CC
                        for j in range(len(all_refineries)):
                            if (cc[0] - refinery_pos[j][0])**2 + (
                                    cc[1] -
                                    refinery_pos[j][1])**2 < geyser_distance:
                                base_refineries += 1
                                if base_refineries == 2:
                                    break
                        # Equivalent to there being a vacant geyser near the CC
                        if base_refineries < 2:
                            geyser_pos = [(geyser.x, geyser.y)
                                          for geyser in all_geysers]
                            for j in range(len(all_geysers)):
                                if (cc[0] - geyser_pos[j][0])**2 + (
                                        cc[1] -
                                        geyser_pos[j][1])**2 < geyser_distance:
                                    selected_geyser = geyser_pos[j]
                                    break
                        if selected_geyser:
                            break

                # Trivial case: there are no refineries so just pick any suitable geyser
                else:
                    cc = random.choice(cc_pos)
                    if len(all_geysers) > 0:
                        geyser_pos = [(geyser.x, geyser.y)
                                      for geyser in all_geysers]
                        for i in range(len(all_geysers)):
                            if (cc[0] - geyser_pos[i][0])**2 + (
                                    cc[1] -
                                    geyser_pos[i][1])**2 < geyser_distance:
                                selected_geyser = geyser_pos[i]

            if selected_geyser:
                new_action = HelperClass.move_screen(obs, selected_geyser)

        # At this point there should be a vacant geyser on the screen (or none at all if last step failed).
        if self.reqSteps == 1:
            geysers = [
                u for u in obs.observation.feature_units
                if u.unit_type == units.Neutral.VespeneGeyser
            ]
            refineries = [
                u for u in obs.observation.feature_units
                if u.unit_type == units.Terran.Refinery and u.alliance == 1
            ]
            if len(refineries) == 0 and len(geysers) > 0:
                new_action = HelperClass.place_building(
                    self, obs, units.Terran.Refinery, geysers[0].x,
                    geysers[0].y)
            elif len(refineries) == 1 and len(geysers) == 2:
                geyser_loc_1 = (geysers[0].x, geysers[0].y)
                geyser_loc_2 = (geysers[1].x, geysers[1].y)
                if geyser_loc_1[0] == refineries[0].x and geyser_loc_1[
                        1] == refineries[0].y:
                    new_action = HelperClass.place_building(
                        self, obs, units.Terran.Refinery, geyser_loc_2[0],
                        geyser_loc_2[1])
                else:
                    new_action = HelperClass.place_building(
                        self, obs, units.Terran.Refinery, geyser_loc_1[0],
                        geyser_loc_1[1])

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #16
0
    def attack(self, obs, location=None):
        """Selects all army units and issues an attack order on the closest enemy.
                It checks for enemies using the minimap. It also counts the army.

                :param obs: The observer.
                :param location: The desired location to attack [x, y] in minimap coordinates.
                                   If None, it attacks the closest enemy
                """
        new_action = [actions.FUNCTIONS.no_op()]

        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            if actions.FUNCTIONS.select_army.id in obs.observation.available_actions:
                new_action = [actions.FUNCTIONS.select_army("select")]

        if self.reqSteps == 3:
            if location is None:
                distance = []

                enemy_y, enemy_x = (
                    obs.observation.feature_minimap.player_relative ==
                    features.PlayerRelative.ENEMY).nonzero()
                if len(enemy_y) > 0:
                    for i in range(len(enemy_y)):
                        distance.append(
                            np.power(enemy_x[i] - self.base_location[1], 2) +
                            np.power(enemy_y[i] - self.base_location[0], 2))

                    index_min = min(range(len(distance)),
                                    key=distance.__getitem__)
                    location = [enemy_x[index_min], enemy_y[index_min]]

                else:
                    location = self.attack_coordinates

            if actions.FUNCTIONS.move_camera.id in obs.observation.available_actions:
                new_action = [actions.FUNCTIONS.move_camera(location)]

        if self.reqSteps == 2:
            has_attack_point = False
            screen_location = [0, 0]

            while not has_attack_point:
                x = random.randint(20, 60)
                y = random.randint(20, 60)
                if obs.observation.feature_screen[5][y][
                        x] == 0:  # Finds a point without any units
                    screen_location = [x, y]
                    has_attack_point = True

            if actions.FUNCTIONS.Attack_screen.id in obs.observation.available_actions:
                self.action_finished = True
                new_action = [
                    actions.FUNCTIONS.Attack_screen("now", screen_location)
                ]

        # One step is being intentionally left blank.
        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
Exemple #17
0
    def return_scv(self, obs):
        """
            Returns an idle SCV to mining. It tries to populate refineries first. Checks other bases if the main base
            has depleted its resources.
        """
        new_action = [actions.FUNCTIONS.no_op()]
        if self.reqSteps == 0:
            self.reqSteps = 4

        if self.reqSteps == 4:
            if obs.observation.player.idle_worker_count > 0:
                new_action = [
                    actions.FUNCTIONS.select_idle_worker(
                        "select", obs, units.Terran.SCV)
                ]

        # Finds a suitable base to send the SCV to.
        if self.reqSteps == 3:
            command_centers = [
                u for u in obs.observation.raw_units if u.alliance == 1
                and u.unit_type == units.Terran.CommandCenter
                and u.build_progress == 100 and u.ideal_harvesters > 0
            ]
            undermanned_command_centers = [
                u for u in command_centers
                if u.assigned_harvesters / u.ideal_harvesters < 0
            ]
            undermanned_refineries = [
                u for u in obs.observation.raw_units
                if u.alliance == 1 and u.unit_type == units.Terran.Refinery
                and u.build_progress == 100 and u.assigned_harvesters < 3
            ]
            if len(undermanned_refineries) > 0:
                refinery = random.choice(undermanned_refineries)
                new_action = HelperClass.move_screen(obs,
                                                     (refinery.x, refinery.y))
            elif len(undermanned_command_centers) > 0:
                command_center = random.choice(undermanned_command_centers)
                new_action = HelperClass.move_screen(
                    obs, (command_center.x, command_center.y))
            elif len(command_centers) > 0:
                command_center = random.choice(command_centers)
                new_action = HelperClass.move_screen(
                    obs, (command_center.x, command_center.y))

        # Should be at a base now.
        if self.reqSteps == 2:
            undermanned_refineries = [
                u for u in obs.observation.feature_units
                if u.alliance == 1 and u.unit_type == units.Terran.Refinery
                and u.build_progress == 100 and u.assigned_harvesters < 3
            ]
            minerals = [
                u for u in obs.observation.feature_units
                if (u.unit_type == units.Neutral.MineralField
                    or u.unit_type == units.Neutral.MineralField750
                    or u.unit_type == units.Neutral.RichMineralField
                    or u.unit_type == units.Neutral.RichMineralField750)
            ]
            if len(undermanned_refineries) > 0:
                refinery = undermanned_refineries[0]
                if HelperClass.do_action(
                        self, obs, actions.FUNCTIONS.Harvest_Gather_screen.id):
                    new_action = [
                        actions.FUNCTIONS.Harvest_Gather_screen(
                            "now", (HelperClass.sigma(
                                refinery.x), HelperClass.sigma(refinery.y)))
                    ]
                    self.action_finished = True
            elif len(minerals) > 0:
                mineral = minerals[0]
                if HelperClass.do_action(
                        self, obs, actions.FUNCTIONS.Harvest_Gather_screen.id):
                    new_action = [
                        actions.FUNCTIONS.Harvest_Gather_screen(
                            "now", (HelperClass.sigma(
                                mineral.x), HelperClass.sigma(mineral.y)))
                    ]
                    self.action_finished = True

        # There's one step left (reqSteps == 1) that's intentionally being left blank.
        self.reqSteps -= 1

        ActionSingleton().set_action(new_action)
Exemple #18
0
    def expand(self, obs):
        """
            Builds a command center at a suitable, empty base. Doesn't build in the main bases.
        """
        new_action = [actions.FUNCTIONS.no_op()]
        if self.reqSteps == 0:
            self.expo_loc = 0
            self.reqSteps = 4

        if self.reqSteps == 4:  # move to base
            new_action = [HelperClass.move_camera_to_base_location(self, obs)]

        if self.reqSteps == 3:  # select scv
            command_scv = HelperClass.get_units(self, obs, units.Terran.SCV)
            if len(command_scv) > 0 and not HelperClass.is_unit_selected(
                    self, obs, units.Terran.SCV):
                if (obs.observation.player.idle_worker_count > 0):
                    new_action = [
                        actions.FUNCTIONS.select_idle_worker(
                            "select", obs, units.Terran.SCV)
                    ]
                else:
                    command = random.choice(command_scv)
                    new_action = [
                        actions.FUNCTIONS.select_point(
                            "select", (HelperClass.sigma(
                                command.x), HelperClass.sigma(command.y)))
                    ]

        # This part finds a vacant expansion location
        if self.reqSteps == 2:
            camera_pos = HelperClass.get_current_minimap_location(obs)
            if self.start_top is not None and not self.start_top:
                expansions_minimap = Coordinates.EXPO_LOCATIONS2
                expansions_screen = Coordinates.CC_LOCATIONS2
            else:
                expansions_minimap = Coordinates.EXPO_LOCATIONS
                expansions_screen = Coordinates.CC_LOCATIONS
            # This should be compatible with the coordinates gotten from raw_units
            expansions_relative_screen = [
                ((a[0][0] - camera_pos[0]) * (200 * 84 / (24 * 64)) + a[1][0],
                 (a[0][1] - camera_pos[1]) * (200 * 84 / (24 * 64)) + a[1][1])
                for a in list(zip(expansions_minimap, expansions_screen))
            ]

            cc = [
                u for u in obs.observation.raw_units
                if (u.unit_type == units.Terran.CommandCenter
                    or u.unit_type == units.Terran.OrbitalCommand
                    or u.unit_type == units.Terran.PlanetaryFortress)
            ]

            for i in range(len(expansions_relative_screen)):
                if len(cc) > 0:
                    vacant = True
                    for j in range(len(cc)):
                        # 10 is an arbitrary screen length.
                        if (abs(cc[j].x - expansions_relative_screen[i][0]) <
                                10 and
                                abs(cc[j].y - expansions_relative_screen[i][1])
                                < 10):
                            vacant = False
                            break
                    if vacant:
                        new_action = [
                            actions.FUNCTIONS.move_camera(
                                expansions_minimap[i])
                        ]
                        self.expo_loc = i
                        break

        if self.reqSteps == 1:
            if self.expo_loc is not None:
                if self.start_top:
                    t = Coordinates.CC_LOCATIONS[self.expo_loc]
                else:
                    t = Coordinates.CC_LOCATIONS2[self.expo_loc]
                if HelperClass.do_action(
                        self, obs,
                        actions.FUNCTIONS.Build_CommandCenter_screen.id):
                    new_action = HelperClass.place_building(
                        self, obs, units.Terran.CommandCenter, t[0], t[1])

                self.expo_loc = None

        self.reqSteps -= 1
        ActionSingleton().set_action(new_action)
    def distribute_scv(self, obj, obs, base_location):  # Use State class to get num expansions later

        new_action = [actions.FUNCTIONS.no_op()]  # No action by default
        steps_needed = 2  # Actions needed at each Command Center

        if obj.reqSteps == 0:
            obj.reqSteps = 1

        self.num_command_centers = obj.game_state.units_amount[units.Terran.CommandCenter.value]

        if not self.all_command_centers_found:
            all_expo_locations = [base_location] + Coordinates.EXPO_LOCATIONS

            self.find_all_command_centers(obs, all_expo_locations)

            if not self.all_command_centers_found:
                return

        pos = self.command_centers_pos[self.curr_CC]

        if self.curr_step % steps_needed == 0:  # If all actions for this Command Center are performed, move the
            if not self.camera_moved:               # camera and increment/reset required variables
                new_action = [actions.FUNCTIONS.move_camera(pos)]
                self.curr_step -= 1
                self.curr_CC -= 1
                self.camera_moved = True
                self.num_CC_minerals_incremented = False
                if not self.all_refineries_checked:
                    self.first_scv_selected = False
            elif self.camera_moved:
                self.camera_moved = False
                #  If on the first loop through expo locations and there is a command center, add this to the total num
                # if self.curr_step < 2*len(command_centers_pos) and len(command_centers) > 0:
                #self.num_command_centers += 1

        elif self.curr_step % steps_needed == 1:  #

            command_centers = self.get_units_by_type(obs, units.Terran.CommandCenter)

            if len(command_centers) > 0:  # Check that command center exists
                command_center = command_centers[0]

                if not self.all_refineries_checked:

                    refineries = self.get_units_by_type(obs, units.Terran.Refinery)

                    refineries_not_ideal = [refinery for refinery in refineries  # Get refineries with non-desired amount of SCV:s
                                            if refinery.assigned_harvesters != self.refinery_desired_harvesters
                                            and refinery.build_progress == 100]

                    if len(refineries_not_ideal) > 0:

                        refinery = refineries_not_ideal[0]  # Pick one of the refineries

                        #  Calculate the difference between the current amount of SCV:s and the desired amount
                        refinery_scv_ideal_diff = refinery.assigned_harvesters - self.refinery_desired_harvesters

                        #  Check how many units are selected currently
                        units_selected = [
                            unit for unit in obs.observation.feature_units if unit.is_selected]
                        num_units_selected = len(units_selected)

                        #  Check if this refinery has too few SCV:s
                        if refinery_scv_ideal_diff < 0 and command_center.assigned_harvesters > self.min_num_mineral_harvesters:

                            #  If fewer than the number of SCV:s missing are selected, select from mineral line
                            if num_units_selected < abs(refinery_scv_ideal_diff) or not self.first_scv_selected:

                                #  Check if first SCV for this refinery has been selected.
                                #  If so, use "toggle", otherwise "select".
                                if not self.first_scv_selected:
                                    action_type = "select"
                                    self.first_scv_selected = True
                                else:
                                    action_type = "toggle"

                                new_action = self.select_single_scv_at_minerals(
                                    obs, action_type, (refinery.x, refinery.y))

                            #  If more than the number of SCV:s missing are selected, deselect at index 0 (first position)
                            elif num_units_selected > abs(refinery_scv_ideal_diff):
                                new_action = self.deselect_at_index(obs, 0)
                                self.first_scv_selected = False

                            #  If the right amount of SCV:s are selected, assign these to harvest at the refinery
                            elif num_units_selected == abs(refinery_scv_ideal_diff):
                                if refinery.x > 0 and refinery.y > 0 and refinery.x < 84 and refinery.y < 84:
                                    new_action = [actions.FUNCTIONS.Harvest_Gather_screen(
                                        "now", (refinery.x, refinery.y))]
                                    self.first_scv_selected = False

                        #  Check if this refinery has too many SCV:s
                        elif refinery_scv_ideal_diff > 0:

                            #  Check if the number of SCV:s selected is fewer than the amount too many.
                            #  Also check if the first SCV from this refinery has been selected, otherwise select it.
                            if num_units_selected < refinery_scv_ideal_diff or self.first_scv_selected:

                                #  To make sure SCV:s harvesting at the refinery are selected, select the closest SCV
                                scvs_on_screen = self.get_units_by_type(obs, units.Terran.SCV)
                                min_dist = 100
                                scv_selected = None
                                for scv in scvs_on_screen:
                                    dist = (scv.x - refinery.x) ** 2 + (scv.y - refinery.y) ** 2
                                    if dist < min_dist:
                                        min_dist = dist
                                        scv_selected = scv

                                #  Check if first SCV for this refinery has been selected.
                                #  If so, use "toggle", otherwise "select".
                                if not self.first_scv_selected:
                                    action_type = "select"
                                    self.first_scv_selected = True
                                else:
                                    action_type = "toggle"
                                new_action = [actions.FUNCTIONS.select_point(
                                    action_type, (scv_selected.x, scv_selected.y))]
                            # Check if the number of SCV:s selected is more than the amount too many. If so, deselect.
                            elif num_units_selected > refinery_scv_ideal_diff:
                                new_action = self.deselect_at_index(obs, 0)
                                self.first_scv_selected = False
                            #  Check if the number of SCV:s selected is the amount too many. If so, send to harvest minerals
                            elif num_units_selected == refinery_scv_ideal_diff:
                                minerals_on_screen = self.get_units_by_type(
                                    obs, units.Neutral.MineralField)
                                if len(minerals_on_screen) > 0:
                                    mineral = random.choice(minerals_on_screen)
                                    new_action = [actions.FUNCTIONS.Harvest_Gather_screen(
                                        "now", (mineral.x, mineral.y))]
                                    self.first_scv_selected = False
                        #  If refinery has the right amount of SCV:s, reset the first selected variable
                        else:
                            self.first_scv_selected = False

                        #  If code gets here, this section needs to be repeated at least one more time, so subtract 1
                        #  from the iteration variable
                        if refinery_scv_ideal_diff > 0 or command_center.assigned_harvesters > self.min_num_mineral_harvesters:
                            self.curr_step -= 1

                    #  Check if all refineries are checked for the current Command Center
                    if (len(refineries_not_ideal) == 0 or
                        command_center.assigned_harvesters <= self.min_num_mineral_harvesters) \
                            and not self.all_refineries_checked:
                        self.num_CC_refineries_checked += 1

                    #  Check if all refineries are checked for all Command Centers
                    if (len(refineries_not_ideal) == 0
                        or command_center.assigned_harvesters <= self.min_num_mineral_harvesters) \
                            and self.num_CC_refineries_checked >= self.num_command_centers \
                            and not self.all_refineries_checked:
                        self.all_refineries_checked = True

                #  Check if all refineries for all Command Centers are checked. If so, start distributing mineral SCV:s
                if self.all_refineries_checked:

                    #  Check if all Command Centers have less than maximum amount of mineral harvesting SCV:s
                    if abs(self.num_CC_minerals_checked) != self.num_command_centers:

                        #  Calculate the difference between the assigned and ideal amount of mineral harvesting SCV:s
                        scv_ideal_diff = command_center.assigned_harvesters - command_center.ideal_harvesters

                        if obs.observation.single_select[0][0] != 0:
                            num_units_selected = 1
                        else:
                            num_units_selected = len(obs.observation.multi_select)

                        # Check if number of SCV:s is more than ideal
                        if scv_ideal_diff > 0:

                            if not self.num_CC_minerals_incremented:
                                if self.num_CC_minerals_checked < 0:
                                    self.num_CC_minerals_checked = 0
                                self.num_CC_minerals_checked += 1
                                self.num_CC_minerals_incremented = True

                            if not self.first_scv_selected:
                                action_type = "select"
                                self.first_scv_selected = True
                                new_action = self.select_single_scv_at_minerals(
                                    obs, action_type, "mean")
                            else:
                                action_type = "toggle"

                                if num_units_selected < scv_ideal_diff:
                                    new_action = self.select_single_scv_at_minerals(
                                        obs, action_type, "mean")
                                elif num_units_selected > scv_ideal_diff:
                                    new_action = self.deselect_at_index(obs, 0)

                            if num_units_selected != scv_ideal_diff:  # If the right amount is not selected, loop again
                                self.curr_step -= 1

                        elif scv_ideal_diff <= 0:  # Check if number of SCV:s is less than or equal to ideal amount

                            if not self.num_CC_minerals_incremented:
                                if self.num_CC_minerals_checked > 0:
                                    self.num_CC_minerals_checked = 0
                                self.num_CC_minerals_checked -= 1
                                self.num_CC_minerals_incremented = True

                            #  Check if number of SCV:s is less than ideal
                            if scv_ideal_diff < 0 and self.first_scv_selected:

                                #  Check if number selected is more than the amount missing. If so, deselect.
                                if num_units_selected > abs(scv_ideal_diff):
                                    new_action = self.deselect_at_index(obs, 0)
                                    self.curr_step -= 1
                                #  If the amount selected is not more than the amount missing but more than 1, send
                                #  these SCV:s to harvest at this Command Center
                                elif num_units_selected > 0:

                                    minerals_on_screen = self.get_units_by_type(
                                        obs, units.Neutral.MineralField)
                                    mineral = random.choice(minerals_on_screen)

                                    new_action = [
                                        actions.FUNCTIONS.Harvest_Gather_screen("now", [mineral.x, mineral.y])]

                                    self.first_scv_selected = False

                    #  Check if all Command Centers have less than maximum amount of mineral harvesting SCV:s
                    elif abs(self.num_CC_minerals_checked) == self.num_command_centers\
                            and self.curr_step >= 2*len(self.command_centers_pos):
                        self.all_CC_checked = True

        self.curr_step += 1

        if self.curr_step % steps_needed == 0:
            self.curr_CC += 1
            if self.curr_CC == len(self.command_centers_pos):
                self.curr_CC = 0

        if self.all_CC_checked:  # or self.curr_step > 600
            new_action = [actions.FUNCTIONS.no_op()]
            obj.action_finished = True
            obj.reqSteps = 0

        ActionSingleton().set_action(new_action)
        return