예제 #1
0
    def __init__(self, response_observation, previous_observation=None):
        """
        :param response_observation:
        """
        # Only filled in realtime=True in case the bot skips frames
        self.previous_observation = previous_observation
        self.response_observation = response_observation

        # https://github.com/Blizzard/s2client-proto/blob/51662231c0965eba47d5183ed0a6336d5ae6b640/s2clientprotocol/sc2api.proto#L575
        self.observation = response_observation.observation
        self.observation_raw = self.observation.raw_data
        self.player_result = response_observation.player_result
        self.common: Common = Common(self.observation.player_common)

        # Area covered by Pylons and Warpprisms
        self.psionic_matrix: PsionicMatrix = PsionicMatrix.from_proto(
            self.observation_raw.player.power_sources)
        # 22.4 per second on faster game speed
        self.game_loop: int = self.observation.game_loop

        # https://github.com/Blizzard/s2client-proto/blob/33f0ecf615aa06ca845ffe4739ef3133f37265a9/s2clientprotocol/score.proto#L31
        self.score: ScoreDetails = ScoreDetails(self.observation.score)
        self.abilities = self.observation.abilities  # abilities of selected units
        self.upgrades: Set[UpgradeId] = {
            UpgradeId(upgrade)
            for upgrade in self.observation_raw.player.upgrade_ids
        }

        # self.visibility[point]: 0=Hidden, 1=Fogged, 2=Visible
        self.visibility: PixelMap = PixelMap(
            self.observation_raw.map_state.visibility, mirrored=False)
        # self.creep[point]: 0=No creep, 1=creep
        self.creep: PixelMap = PixelMap(self.observation_raw.map_state.creep,
                                        in_bits=True,
                                        mirrored=False)

        # Effects like ravager bile shot, lurker attack, everything in effect_id.py
        self.effects: Set[EffectData] = {
            EffectData(effect)
            for effect in self.observation_raw.effects
        }
        """ Usage:
def get_upgrade_abilities(data):
    ability_data = data["Ability"]
    unit_data = data["Unit"]
    upgrade_data = data["Upgrade"]

    ability_to_upgrade_dict: Dict[AbilityId, UpgradeId] = OrderedDict2()
    """
    We want to be able to research an upgrade by doing
    await self.can_research(UpgradeId, return_idle_structures=True) -> returns list of idle structures that can research it
    So we need to assign each upgrade id one building type, and its research ability and requirements (e.g. armory for infantry level 2)
    """

    # Collect all upgrades and their corresponding abilities
    entry: dict
    for entry in ability_data:
        if isinstance(entry.get("target", {}), str):
            continue
        ability_id: AbilityId = AbilityId(entry["id"])
        researched_ability_id: UnitTypeId

        upgrade_id_value: int = entry.get("target",
                                          {}).get("Research",
                                                  {}).get("upgrade", 0)
        if upgrade_id_value:
            upgrade_id: UpgradeId = UpgradeId(upgrade_id_value)

            ability_to_upgrade_dict[ability_id] = upgrade_id
    """
    unit_research_abilities = {
        UnitTypeId.ENGINEERINGBAY: {
            UpgradeId.TERRANINFANTRYWEAPONSLEVEL1:
            {
                "ability": AbilityId.ENGINEERINGBAYRESEARCH_TERRANINFANTRYWEAPONSLEVEL1,
                "required_building": None,
                "requires_power": False, # If a pylon nearby is required
            },
            UpgradeId.TERRANINFANTRYWEAPONSLEVEL2: {
                "ability": AbilityId.ENGINEERINGBAYRESEARCH_TERRANINFANTRYWEAPONSLEVEL2,
                "required_building": UnitTypeId.ARMORY,
                "requires_power": False, # If a pylon nearby is required
            },
        }
    }
    """
    unit_research_abilities = OrderedDict2()
    for entry in unit_data:
        unit_abilities = entry.get("abilities", [])
        unit_type = UnitTypeId(entry["id"])

        if unit_type == UnitTypeId.TECHLAB:
            continue

        current_unit_research_abilities = OrderedDict2()
        for ability_info in unit_abilities:
            ability_id_value: int = ability_info.get("ability", 0)
            if ability_id_value:
                ability_id: AbilityId = AbilityId(ability_id_value)
                # Upgrade is not a known upgrade ability
                if ability_id not in ability_to_upgrade_dict:
                    continue

                required_building = None
                required_upgrade = None
                requirements = ability_info.get("requirements", [])
                if requirements:
                    req_building_id_value = next(
                        (req["building"]
                         for req in requirements if req.get("building", 0)),
                        None)
                    if req_building_id_value:
                        req_building_id = UnitTypeId(req_building_id_value)
                        required_building = req_building_id

                    req_upgrade_id_value = next(
                        (req["upgrade"]
                         for req in requirements if req.get("upgrade", 0)),
                        None)
                    if req_upgrade_id_value:
                        req_upgrade_id = UpgradeId(req_upgrade_id_value)
                        required_upgrade = req_upgrade_id

                requires_power = entry.get("needs_power", False)

                resulting_upgrade = ability_to_upgrade_dict[ability_id]

                research_info = {"ability": ability_id}
                if required_building:
                    research_info["required_building"] = required_building
                if required_upgrade:
                    research_info["required_upgrade"] = required_upgrade
                if requires_power:
                    research_info["requires_power"] = requires_power
                current_unit_research_abilities[
                    resulting_upgrade] = research_info

        if current_unit_research_abilities:
            unit_research_abilities[
                unit_type] = current_unit_research_abilities

    return unit_research_abilities
예제 #3
0
def main():
    unit_count = defaultdict(int)
    with open("build_order.json", "r") as f:
        raw_order = json.load(f)

    race = get_race(raw_order)

    unit_count[UnitTypeId.OVERLORD] = 1

    if race == Race.Protoss:
        worker = UnitTypeId.PROBE
        townhall = UnitTypeId.NEXUS
    elif race == Race.Terran:
        worker = UnitTypeId.SCV
        townhall = UnitTypeId.COMMANDCENTER
    elif race == Race.Zerg:
        unit_count[UnitTypeId.OVERLORD] = 1
        worker = UnitTypeId.DRONE
        townhall = UnitTypeId.HATCHERY
    else:
        print("Unknown race")
        return

    unit_count[worker] = 12
    unit_count[townhall] = 1

    text_timings = "WarnBuildMacro(["

    text = ""
    last_line: Optional[str] = None
    last_id: Optional[Union[UnitTypeId, UpgradeId]] = None
    replacer_dict = action_replacement_dict()

    for order in raw_order:
        line = ""

        if order["type"] in {"unit", "structure", "worker"}:
            id = UnitTypeId(order["id"])
            unit_count[id] += 1
            line += f"BuildId({str(id)}, to_count={unit_count[id]})"
            if order["type"] == "structure":
                text_timings += f"({str(id)}, {unit_count[id]}, {order['frame'] // 22.4}),"
        elif order["type"] == "upgrade":
            id = UpgradeId(order["id"])
            line += f"Tech({str(id)})"
        elif order["type"] == "action" and order["name"] in replacer_dict:
            id = None
            line += replacer_dict[order["name"]]
        else:
            id = None
            line += "# " + order["name"]

        line += ","

        if last_line is not None and (last_id is None or last_id != id):
            text += last_line + "\n"

        last_line = line
        last_id = id

    text += last_line + "\n"
    text_timings += "], []),"
    print(text_timings)
    print(text)
예제 #4
0
    def __init__(self, response_observation):
        self.response_observation = response_observation
        self.actions = response_observation.actions  # successful actions since last loop
        self.action_errors = response_observation.action_errors  # error actions since last loop

        # https://github.com/Blizzard/s2client-proto/blob/51662231c0965eba47d5183ed0a6336d5ae6b640/s2clientprotocol/sc2api.proto#L575
        # TODO: implement alerts https://github.com/Blizzard/s2client-proto/blob/51662231c0965eba47d5183ed0a6336d5ae6b640/s2clientprotocol/sc2api.proto#L640
        self.observation = response_observation.observation
        self.observation_raw = self.observation.raw_data
        self.dead_units: Set[
            int] = self.observation_raw.event.dead_units  # returns set of tags of units that died
        self.alerts = self.observation.alerts
        self.player_result = response_observation.player_result
        self.chat = response_observation.chat
        self.common: Common = Common(self.observation.player_common)

        # Area covered by Pylons and Warpprisms
        self.psionic_matrix: PsionicMatrix = PsionicMatrix.from_proto(
            self.observation_raw.player.power_sources)
        self.game_loop: int = self.observation.game_loop  # 22.4 per second on faster game speed

        # https://github.com/Blizzard/s2client-proto/blob/33f0ecf615aa06ca845ffe4739ef3133f37265a9/s2clientprotocol/score.proto#L31
        self.score: ScoreDetails = ScoreDetails(self.observation.score)
        self.abilities = self.observation.abilities  # abilities of selected units

        self._blipUnits = []
        self.own_units: Units = Units([])
        self.enemy_units: Units = Units([])
        self.mineral_field: Units = Units([])
        self.vespene_geyser: Units = Units([])
        self.resources: Units = Units([])
        self.destructables: Units = Units([])
        self.watchtowers: Units = Units([])
        self.units: Units = Units([])

        for unit in self.observation.raw_data.units:
            if unit.is_blip:
                self._blipUnits.append(unit)
            else:
                unit_obj = Unit(unit)
                self.units.append(unit_obj)
                alliance = unit.alliance
                # Alliance.Neutral.value = 3
                if alliance == 3:
                    unit_type = unit.unit_type
                    # XELNAGATOWER = 149
                    if unit_type == 149:
                        self.watchtowers.append(unit_obj)
                    # mineral field enums
                    elif unit_type in mineral_ids:
                        self.mineral_field.append(unit_obj)
                        self.resources.append(unit_obj)
                    # geyser enums
                    elif unit_type in geyser_ids:
                        self.vespene_geyser.append(unit_obj)
                        self.resources.append(unit_obj)
                    # all destructable rocks
                    else:
                        self.destructables.append(unit_obj)
                # Alliance.Self.value = 1
                elif alliance == 1:
                    self.own_units.append(unit_obj)
                # Alliance.Enemy.value = 4
                elif alliance == 4:
                    self.enemy_units.append(unit_obj)
        self.upgrades: Set[UpgradeId] = {
            UpgradeId(upgrade)
            for upgrade in self.observation_raw.player.upgrade_ids
        }

        # Set of unit tags that died this step
        self.dead_units: Set[int] = {
            dead_unit_tag
            for dead_unit_tag in self.observation_raw.event.dead_units
        }
        # Set of enemy units detected by own sensor tower, as blips have less unit information than normal visible units
        self.blips: Set[Blip] = {Blip(unit) for unit in self._blipUnits}
        # self.visibility[point]: 0=Hidden, 1=Fogged, 2=Visible
        self.visibility: PixelMap = PixelMap(
            self.observation_raw.map_state.visibility, mirrored=True)
        # HSPARK 수정 시작
        # self.creep[point]: 0=No creep, 1=creep
        # self.creep: PixelMap = PixelMap(self.observation_raw.map_state.creep, mirrored=True)
        self.creep: PixelMap = PixelMap(self.observation_raw.map_state.creep,
                                        mirrored=True,
                                        in_bits=True)
        # HSPARK 수정 끝

        # Effects like ravager bile shot, lurker attack, everything in effect_id.py
        self.effects: Set[EffectData] = {
            EffectData(effect)
            for effect in self.observation_raw.effects
        }
        """ Usage: