async def morph_Archons(self): if upgrade.PSISTORMTECH is self.state.upgrades or self.already_pending_upgrade(upgrade.PSISTORMTECH): archons = self.army(unit.ARCHON) ht_amount = int(archons.amount / 2) ht_thresh = ht_amount + 1 else: ht_thresh = 1 if self.units(unit.HIGHTEMPLAR).amount > ht_thresh: hts = self.units(unit.HIGHTEMPLAR).sorted(lambda u: u.energy) ht2 = hts[0] ht1 = hts[1] if ht2 and ht1: for ht in self.army(unit.HIGHTEMPLAR): if ht.tag == ht1.tag or ht.tag==ht2.tag: self.army.remove(ht) if ht1.distance_to(ht2) > 4: if ht1.distance_to(self.main_base_ramp.bottom_center) > 30: self.do(ht1.move(ht2)) self.do(ht2.move(ht1)) else: self.do(ht1.move(self.main_base_ramp.bottom_center)) self.do(ht2.move(self.main_base_ramp.bottom_center)) else: # print('morphing!') from s2clientprotocol import raw_pb2 as raw_pb from s2clientprotocol import sc2api_pb2 as sc_pb command = raw_pb.ActionRawUnitCommand( ability_id=ability.MORPH_ARCHON.value, unit_tags=[ht1.tag,ht2.tag], queue_command=False ) action = raw_pb.ActionRaw(unit_command=command) await self._client._execute(action=sc_pb.RequestAction( actions=[sc_pb.Action(action_raw=action)] ))
def combine_actions(action_iter): for key, items in groupby(action_iter, key=lambda a: a.combining_tuple): ability, target, queue = key if target is None: cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags=[u.unit.tag for u in items], queue_command=queue) elif isinstance(target, Point2): cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags=[u.unit.tag for u in items], queue_command=queue, target_world_space_pos=common_pb.Point2D(x=target.x, y=target.y)) elif isinstance(target, Unit): cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags=[u.unit.tag for u in items], queue_command=queue, target_unit_tag=target.tag) else: raise RuntimeError( f"Must target an unit or a point or None, found '{target !r}'") yield raw_pb.ActionRaw(unit_command=cmd)
async def execute(self) -> bool: templars = self.cache.own(self.allowed_types).ready for ht in templars: # type: Unit if ht.is_idle and ht.tag in self.already_merging_tags: self.knowledge.roles.clear_task(ht) self.already_merging_tags.remove(ht.tag) templars = templars.tags_not_in(self.already_merging_tags) if templars.amount > 1: unit: Unit = templars[0] self.already_merging_tags.append(unit.tag) target: Unit = templars.tags_not_in(self.already_merging_tags).closest_to(unit) # Reserve upcoming archon so that they aren't stolen by other states. self.knowledge.roles.set_task(UnitTask.Reserved, unit) self.knowledge.roles.set_task(UnitTask.Reserved, target) self.knowledge.print(f"[ARCHON] merging {str(unit.type_id)} and {str(unit.type_id)}") from s2clientprotocol import raw_pb2 as raw_pb from s2clientprotocol import sc2api_pb2 as sc_pb command = raw_pb.ActionRawUnitCommand( ability_id=AbilityId.MORPH_ARCHON.value, unit_tags=[unit.tag, target.tag], queue_command=False ) action = raw_pb.ActionRaw(unit_command=command) await self.ai._client._execute(action=sc_pb.RequestAction( actions=[sc_pb.Action(action_raw=action)] )) return True
def step(self, obs): """ :param obs: observation to pass to agent :return: returns starcraft action based on observation """ action_id, arguments = self.agent.step(obs) args = arguments[SCIIAgentWrapper.ARG_SLICE[action_id]] raw_action = raw_pb.ActionRaw(unit_command=self.actions[action_id]( *args)) action = sc_pb.Action(action_raw=raw_action) return action
async def move_camera(self, position: Union[Unit, Point2, Point3]): """ Moves camera to the target position """ assert isinstance(position, (Unit, Point2, Point3)) if isinstance(position, Unit): position = position.position await self._execute(action=sc_pb.RequestAction(action=[ sc_pb.Action(action_raw=raw_pb.ActionRaw( camera_move=raw_pb.ActionRawCameraMove( center_world_space=common_pb.Point(x=position.x, y=position.y)))) ]))
async def toggle_autocast(self, units: Union[List[Unit], Units], ability: AbilityId): """ Toggle autocast of all specified units """ assert units assert isinstance(units, list) assert all(isinstance(u, Unit) for u in units) assert isinstance(ability, AbilityId) await self._execute(action=sc_pb.RequestAction(actions=[ sc_pb.Action(action_raw=raw_pb.ActionRaw( toggle_autocast=raw_pb.ActionRawToggleAutocast( ability_id=ability.value, unit_tags=(u.tag for u in units)))) ]))
async def morph_archons(self): if self.units(UnitTypeId.HIGHTEMPLAR).ready.amount >= 2: ht1 = self.units(UnitTypeId.HIGHTEMPLAR).ready.random ht2 = next((ht for ht in self.units(UnitTypeId.HIGHTEMPLAR).ready if ht.tag != ht1.tag), None) if ht2: command = raw_pb.ActionRawUnitCommand( ability_id=AbilityId.MORPH_ARCHON.value, unit_tags=[ht1.tag, ht2.tag], queue_command=False ) action = raw_pb.ActionRaw(unit_command=command) await self._client._execute(action=sc_pb.RequestAction( actions=[sc_pb.Action(action_raw=action)] ))
async def move_camera(self, position: Union[Unit, Units, Point2, Point3]): """Moves camera to the target position :param position:""" assert isinstance(position, (Unit, Units, Point2, Point3)) if isinstance(position, Units): position = position.center if isinstance(position, Unit): position = position.position await self._execute(action=sc_pb.RequestAction(actions=[ sc_pb.Action(action_raw=raw_pb.ActionRaw( camera_move=raw_pb.ActionRawCameraMove( center_world_space=position.to3.as_Point))) ]))
def get_agent_action_heuristic(self, a_id, action): unit = self.get_unit_by_id(a_id) tag = unit.tag target_tag = self.enemies[self.heuristic_targets[a_id]].tag action_id = action_attack_id cmd = r_pb.ActionRawUnitCommand(ability_id=action_id, target_unit_tag=target_tag, unit_tags=[tag], queue_command=False) sc_action = sc_pb.Action(action_raw=r_pb.ActionRaw(unit_command=cmd)) return sc_action
async def whiteball(self): if self.units(UnitTypeId.HIGHTEMPLAR).idle.ready.amount >= 4: ht1 = self.units(UnitTypeId.HIGHTEMPLAR).idle.ready.random ht2 = next((ht for ht in self.units(UnitTypeId.HIGHTEMPLAR).idle.ready if ht.tag != ht1.tag), None) if ht2: from s2clientprotocol import raw_pb2 as raw_pb from s2clientprotocol import sc2api_pb2 as sc_pb command = raw_pb.ActionRawUnitCommand( ability_id=AbilityId.MORPH_ARCHON.value, unit_tags=[ht1.tag, ht2.tag], queue_command=False) action = raw_pb.ActionRaw(unit_command=command) await self._client._execute(action=sc_pb.RequestAction( actions=[sc_pb.Action(action_raw=action)]))
def get_agent_action_heuristic(self, a_id, action): unit = self.get_unit_by_id(a_id) tag = unit.tag #if self.map_type == 'MMM': # if unit.unit_type == self.medivac_id: # units = [t_unit for t_unit in self.agents.values() if # (t_unit.unit_type == self.marine_id and t_unit.health < t_unit.health_max and t_unit.health > 0)] # if len(units) == 0: # units = [t_unit for t_unit in self.agents.values() if # (t_unit.unit_type == self.marauder_id and t_unit.health > 0)] # action_id = action_heal_id # elif unit.unit_type == self.marauder_id: # units = [t_unit for t_unit in self.enemies.values() if (t_unit.unit_type == 48 or t_unit.unit_type == 51)] # action_id = action_attack_id # else: # units = self.enemies.values() # action_id = action_attack_id #else: # units = self.enemies.items() # action_id = action_attack_id # # for t_id, t_unit in units: # if t_unit.health > 0: # target_tag = t_unit.tag # target_id = t_id # break target_tag = self.enemies[self.heuristic_targets[a_id]].tag action_id = action_attack_id cmd = r_pb.ActionRawUnitCommand(ability_id = action_id, target_unit_tag = target_tag, unit_tags = [tag], queue_command = False) sc_action = sc_pb.Action(action_raw=r_pb.ActionRaw(unit_command=cmd)) return sc_action
def perform(self, spawn_id): # Pass arguments print(self) unit_command = raw_pb.ActionRawUnitCommand(ability_id=self.sc2_id) unit_command.unit_tags.append(spawn_id) if self.require['target'] == 'point': unit_command.target_world_space_pos.x = self.require['pos_x'] unit_command.target_world_space_pos.y = self.require['pos_y'] elif self.require['target'] == 'unit': unit_command.target_unit_tag = self.require['unit_tag'] else: pass action_raw = raw_pb.ActionRaw(unit_command=unit_command) action = sc_pb.RequestAction() action.actions.add(action_raw=action_raw) msg = MessageToJson(action) print(type(msg)) return msg
def get_agent_action(self, a_id, action): """Construct the action for agent a_id.""" unit = self.get_unit_by_id(a_id) tag = unit.tag x = unit.pos.x y = unit.pos.y if action == 0: # no-op (valid only when dead) assert unit.health == 0, "No-op only available for dead agents." if self.debug: logging.debug("Agent {}: Dead".format(a_id)) return None elif action == 1: # stop cmd = r_pb.ActionRawUnitCommand(ability_id=actions["stop"], unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Stop".format(a_id)) elif action == 2: # move north cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x, y=y + self._move_amount), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move North".format(a_id)) elif action == 3: # move south cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x, y=y - self._move_amount), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move South".format(a_id)) elif action == 4: # move east cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x + self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move East".format(a_id)) elif action == 5: # move west cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x - self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move West".format(a_id)) elif action == 6: cmd = r_pb.ActionRawUnitCommand( ability_id=actions["forcefield"], target_world_space_pos=sc_common.Point2D( x=x + self.field_offset[0], y=y + self.field_offset[1]), unit_tags=[tag], queue_command=False) if self.debug: logging.debug( "Agent {}: Releasing Force Field at Location: {}".format( a_id, (x + self.field_offset[0], y + self.field_offset[1]))) elif action == 7: cmd = r_pb.ActionRawUnitCommand( ability_id=actions["autoturrent"], target_world_space_pos=sc_common.Point2D(x=x, y=y), unit_tags=[tag], queue_command=False) if self.debug: logging.debug( "Agent {}: Building A Auto-Turrent at Location: {}".format( a_id, (x, y))) else: # attack/heal units that are in range target_id = action - self.n_actions_no_attack if self.map_content == "MMM" and self.unit_to_name( unit) == 'medivac': target_unit = self.agents[target_id] action_name = "heal" else: target_unit = self.enemies[target_id] action_name = "attack" action_id = actions[action_name] target_tag = target_unit.tag cmd = r_pb.ActionRawUnitCommand(ability_id=action_id, target_unit_tag=target_tag, unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {} {}s unit # {}".format( a_id, action_name, target_id)) sc_action = sc_pb.Action(action_raw=r_pb.ActionRaw(unit_command=cmd)) return sc_action
def get_agent_action(self, a_id, action): unit = self.get_unit_by_id(a_id) tag = unit.tag x = unit.pos.x y = unit.pos.y if action == 0: # no-op (valid only when dead) try: assert unit.health == 0, "No-op chosen but the agent's unit is not dead" except Exception as e: pass if self.debug_inputs: print("Agent %d: Dead" % a_id) return None elif action == 1: # stop cmd = r_pb.ActionRawUnitCommand(ability_id=action_stop_id, unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d: Stop" % a_id) elif action == 2: # north cmd = r_pb.ActionRawUnitCommand( ability_id=action_move_id, target_world_space_pos=sc_common.Point2D(x=x, y=y + self._move_amount), unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d: North" % a_id) elif action == 3: # south cmd = r_pb.ActionRawUnitCommand( ability_id=action_move_id, target_world_space_pos=sc_common.Point2D(x=x, y=y - self._move_amount), unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d: South" % a_id) elif action == 4: # east cmd = r_pb.ActionRawUnitCommand( ability_id=action_move_id, target_world_space_pos=sc_common.Point2D(x=x + self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d: East" % a_id) elif action == 5: # west cmd = r_pb.ActionRawUnitCommand( ability_id=action_move_id, target_world_space_pos=sc_common.Point2D(x=x - self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d: West" % a_id) else: # attack/heal units that are in range target_id = action - self.n_actions_no_attack if self.map_type == 'MMM' and unit.unit_type == self.medivac_id: target_unit = self.agents[target_id] action_id = action_heal_id else: target_unit = self.enemies[target_id] action_id = action_attack_id target_tag = target_unit.tag cmd = r_pb.ActionRawUnitCommand(ability_id=action_id, target_unit_tag=target_tag, unit_tags=[tag], queue_command=False) if self.debug_inputs: print("Agent %d attacks enemy # %d" % (a_id, target_id)) sc_action = sc_pb.Action(action_raw=r_pb.ActionRaw(unit_command=cmd)) return sc_action
action = sc_pb.RequestAction() action.actions.add(action_raw = action_raw) test_client.comm.send(action=action) """ """Move Units""" unit_tag_list=[] observation = sc_pb.RequestObservation() t=test_client.comm.send(observation=observation) for unit in t.observation.observation.raw_data.units: if unit.unit_type == 84: # Probe unit_type_tag unit_tag_list.append(unit.tag) unit_command = raw_pb.ActionRawUnitCommand() unit_command.ability_id = 16 # Move Ability unit_command.target_world_space_pos.x = 30 unit_command.target_world_space_pos.y = 30 for i in range(0,12): unit_command.unit_tags.append(unit_tag_list[i]) action_raw = raw_pb.ActionRaw(unit_command = unit_command) action = sc_pb.RequestAction() action.actions.add(action_raw = action_raw) test_client.comm.send(action=action) #conn.close()
def combine_actions(action_iter): """ Example input: [ # Each entry in the list is a unit command, with an ability, unit, target, and queue=boolean UnitCommand(AbilityId.TRAINQUEEN_QUEEN, Unit(name='Hive', tag=4353687554), None, False), UnitCommand(AbilityId.TRAINQUEEN_QUEEN, Unit(name='Lair', tag=4359979012), None, False), UnitCommand(AbilityId.TRAINQUEEN_QUEEN, Unit(name='Hatchery', tag=4359454723), None, False), ] """ for key, items in groupby(action_iter, key=lambda a: a.combining_tuple): ability: AbilityId target: Union[None, Point2, Unit] queue: bool # See constants.py for combineable abilities combineable: bool ability, target, queue, combineable = key if combineable: # Combine actions with no target, e.g. train and research commands if target is None: cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags={u.unit.tag for u in items}, queue_command=queue) # Combine actions with target point elif isinstance(target, Point2): cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags={u.unit.tag for u in items}, queue_command=queue, target_world_space_pos=common_pb.Point2D(x=target.x, y=target.y), ) # Combine actions with target unit elif isinstance(target, Unit): cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags={u.unit.tag for u in items}, queue_command=queue, target_unit_tag=target.tag, ) else: raise RuntimeError( f"Must target a unit, point or None, found '{target !r}'") yield raw_pb.ActionRaw(unit_command=cmd) else: """ Return one action for each unit; this is required for certain commands that would otherwise be grouped, and only executed once Examples: Select 3 hatcheries, build a queen with each hatch - the grouping function would group these unit tags and only issue one train command once to all 3 unit tags - resulting in one total train command I imagine the same thing would happen to certain other abilities: Battlecruiser yamato on same target, queen transfuse on same time, ghost snipe on same target, all build commands with the same unit type and also all morphs (zergling to banelings) However, other abilities can and should be grouped, see constants.py 'COMBINEABLE_ABILITIES' """ u: UnitCommand if target is None: for u in items: cmd = raw_pb.ActionRawUnitCommand(ability_id=ability.value, unit_tags={u.unit.tag}, queue_command=queue) yield raw_pb.ActionRaw(unit_command=cmd) elif isinstance(target, Point2): for u in items: cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags={u.unit.tag}, queue_command=queue, target_world_space_pos=common_pb.Point2D(x=target.x, y=target.y), ) yield raw_pb.ActionRaw(unit_command=cmd) elif isinstance(target, Unit): for u in items: cmd = raw_pb.ActionRawUnitCommand( ability_id=ability.value, unit_tags={u.unit.tag}, queue_command=queue, target_unit_tag=target.tag, ) yield raw_pb.ActionRaw(unit_command=cmd) else: raise RuntimeError( f"Must target a unit, point or None, found '{target !r}'")
def get_agent_action(self, a_id, action): """Construct the action for agent a_id.""" avail_actions = self.get_avail_agent_actions(a_id) # modify # assert avail_actions[action] == 1, \ # "Agent {} cannot perform action {}".format(a_id, action) if avail_actions[action] != 1: return None unit = self.get_unit_by_id(a_id) tag = unit.tag x = unit.pos.x y = unit.pos.y if action == 0: # no-op (valid only when dead) assert unit.health == 0, "No-op only available for dead agents." if self.debug: logging.debug("Agent {}: Dead".format(a_id)) return None elif action == 1: # stop cmd = r_pb.ActionRawUnitCommand(ability_id=actions["stop"], unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Stop".format(a_id)) elif action == 2: # move north cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x, y=y + self._move_amount), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move North".format(a_id)) elif action == 3: # move south cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x, y=y - self._move_amount), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move South".format(a_id)) elif action == 4: # move east cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x + self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move East".format(a_id)) elif action == 5: # move west cmd = r_pb.ActionRawUnitCommand( ability_id=actions["move"], target_world_space_pos=sc_common.Point2D(x=x - self._move_amount, y=y), unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {}: Move West".format(a_id)) else: # attack/heal units that are in range target_id = action - self.n_actions_no_attack if self.map_type == "MMM" and unit.unit_type == self.medivac_id: target_unit = self.agents[target_id] action_name = "heal" else: target_unit = self.enemies[target_id] action_name = "attack" action_id = actions[action_name] target_tag = target_unit.tag cmd = r_pb.ActionRawUnitCommand(ability_id=action_id, target_unit_tag=target_tag, unit_tags=[tag], queue_command=False) if self.debug: logging.debug("Agent {} {}s unit # {}".format( a_id, action_name, target_id)) sc_action = sc_pb.Action(action_raw=r_pb.ActionRaw(unit_command=cmd)) return sc_action