コード例 #1
0
    def obs_to_state(self, obs):
        """
        Convert sc2 obs object to a (distance_to_enemy, viking_flying_or_landed) state.
        :param obs: SC2Env observation
        :return:
        """
        # Distance
        own_unit_loc = np.array(get_own_unit_location(obs))
        enemy_loc = np.array(get_enemy_unit_location(obs))
        dist = np.linalg.norm(own_unit_loc - enemy_loc)
        rounded_dist = int(round(dist))

        # Flying or landed
        flying = None
        landed_action_id = internal_id_to_action_id(constants.LAND)
        can_land = landed_action_id in obs.observation['available_actions']
        if can_land:
            # If we can land we are flying
            flying = 'flying'
        else:
            flying_action_id = internal_id_to_action_id(constants.FLIGHT)
            can_fly = flying_action_id in obs.observation['available_actions']
            if can_fly:
                # If we can fly we are landed
                flying = 'landed'
            else:
                ValueError("Can neither land nor fly ... ")

        # Is enemy coming towards us
        enemy_closing_in = 'enemy_closing_in' if obs.reward > 0 and rounded_dist < 25 else 'enemy_not_attacking'

        return f'{rounded_dist}/{flying}/{enemy_closing_in}'
コード例 #2
0
    def _act(self, obs):
        state = self.obs_to_state(obs)
        illegal_internal_action_ids = self._get_illegal_internal_action_ids(
            obs)
        sc_action = self.model.select_action(state,
                                             illegal_internal_action_ids)

        if sc_action.internal_id == constants.NO_OP:
            pass
        elif sc_action.internal_id == constants.ATTACK_ENEMY:
            location = get_enemy_unit_location(obs)
            sc_action.set_location(location)
        elif sc_action.internal_id == constants.MOVE_TO_ENEMY:
            raise ValueError("Move to enemy action is illegal for this agent")
        elif sc_action.internal_id == constants.MOVE_FROM_ENEMY:
            location = self.get_location_away(obs)
            sc_action.set_location(location)
        elif sc_action.internal_id == constants.LAND:
            pass
        elif sc_action.internal_id == constants.FLIGHT:
            pass
        else:
            raise NotImplementedError("Unknown action ID received")

        return sc_action
コード例 #3
0
    def get_location_to(self, obs):
        """
        Get the location we want to move towards the enemy. We cannot move 'on' the enemy because that equals attacking
        :return: x, y
        """
        enemy_x_min, enemy_x_max, enemy_y_min, enemy_y_max = get_enemy_width_and_height(
            obs)
        own_unit_x, own_unit_y = get_own_unit_location(obs)
        enemy_x, enemy_y = get_enemy_unit_location(obs)

        # Select between 4 quadrants below/above and left/right of the enemy to move to.
        # We want to move further than the enemy in case we are standing too close to move to a location between our
        # unit(s) and the enemy

        if enemy_x >= own_unit_x:
            x = enemy_x_max + 2
        else:
            x = enemy_x_min - 2

        if enemy_y >= own_unit_y:
            y = enemy_y_max + 2
        else:
            y = enemy_y_min - 2

        location_to = self.clip_location((x, y), obs)
        return location_to
コード例 #4
0
 def obs_to_state(obs):
     """
     Convert sc2 obs object to a distance_to_enemy state.
     :param obs: SC2Env observation
     :return:
     """
     own_unit_loc = np.array(get_own_unit_location(obs))
     enemy_loc = np.array(get_enemy_unit_location(obs))
     dist = np.linalg.norm(own_unit_loc - enemy_loc)
     rounded_dist = int(round(dist))
     return rounded_dist
コード例 #5
0
    def get_location_away(self, obs):
        own_location = get_own_unit_location(obs)
        enemy_location = get_enemy_unit_location(obs)

        # Distance between units
        dx = enemy_location[0] - own_location[0]
        dy = enemy_location[1] - own_location[1]

        # Move in opposite direction of enemy
        away_location = (own_location[0] - dx, own_location[1] - dy)

        # Make sure we don't move outside the screen
        away_location = self.clip_location(away_location, obs)
        return away_location
コード例 #6
0
    def _act(self, obs):
        state = self.obs_to_state(obs)
        sc_action = self.model.select_action(state)

        if sc_action.internal_id == constants.NO_OP:
            pass
        elif sc_action.internal_id == constants.ATTACK_ENEMY:
            location = get_enemy_unit_location(obs)
            sc_action.set_location(location)
        elif sc_action.internal_id == constants.MOVE_TO_ENEMY:
            location = self.get_location_to(obs)
            sc_action.set_location(location)
        elif sc_action.internal_id == constants.MOVE_FROM_ENEMY:
            location = self.get_location_away(obs)
            sc_action.set_location(location)
        else:
            raise NotImplementedError(
                f"Unknown action ID {sc_action.internal_id} received")

        return sc_action