def build_state(self, location: Location, observations: Observations) -> []: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() cc_y, cc_x = (unit_type == unit_type_ids.terran_command_center()).nonzero() cc_count = 1 if cc_y.any() else 0 depot_y, depot_x = (unit_type == unit_type_ids.terran_supply_depot()).nonzero() supply_depot_count = int(round(len(depot_y) / 69)) barracks_y, barracks_x = (unit_type == unit_type_ids.terran_barracks()).nonzero() barracks_count = int(round(len(barracks_y) / 137)) current_state = np.zeros(8) current_state[0] = cc_count current_state[1] = supply_depot_count current_state[2] = barracks_count current_state[3] = observations.player().food_army() hot_squares = np.zeros(4) enemy_y, enemy_x = (observations.minimap().player_relative() == _PLAYER_HOSTILE).nonzero() for i in range(0, len(enemy_y)): y = int(math.ceil((enemy_y[i] + 1) / 32)) x = int(math.ceil((enemy_x[i] + 1) / 32)) hot_squares[((y - 1) * 2) + (x - 1)] = 1 if not location.command_center_is_top_left(): hot_squares = hot_squares[::-1] for i in range(0, 4): current_state[i + 4] = hot_squares[i] return current_state
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.scv_selected: unit_type = observations.screen().unit_type() unit_y, unit_x = ( unit_type == self.unit_type_ids.terran_scv()).nonzero() rand_unit_index = random.randint(0, len(unit_y) - 1) target = [unit_x[rand_unit_index], unit_y[rand_unit_index]] self.scv_selected = True return self.actions.select_point(target) elif not self.scv_moved and self.action_ids.move_minimap( ) in observations.available_actions(): unit_y, unit_x = self.other_bases_minimap_locations.pop(0) target = [unit_x, unit_y] self.scv_moved = True return self.actions.move_minimap(target) elif self.scv_moved and observations.player().idle_worker_count( ) > 0 and len(self.other_bases_minimap_locations) > 0: self.scv_moved = False return self.actions.select_idle_worker() elif self.infinite_scouting and len( self.other_bases_minimap_locations) == 0: self.other_bases_minimap_locations = self.base_location.other_unknown_bases_locations_on_minimap( ) elif not self.scv_back_to_base and len( self.other_bases_minimap_locations) == 0: unit_y, unit_x = self.base_location.base_location_on_minimap() target = [unit_x, unit_y] self.scv_back_to_base = True return self.actions.move_minimap(target) return self.actions.no_op()
def order(self, observations: Observations, step_index: int)-> Order: if observations.last(): self.qlearn.learn(str(self.previous_state), self.previous_action, observations.reward(), 'terminal') QLearningTableStorage().save(self.qlearn, self.agent_name) self.previous_action = None self.previous_state = None self.previous_order = None return NoOrder() elif observations.first(): self.location = Location(observations) self.smart_actions = SmartActions(self.location) self.qlearn = QLearningTable(actions=list(range(len(self.smart_actions.all())))) QLearningTableStorage().load(self.qlearn, self.agent_name) self.control_group_order = PrepareSCVControlGroupsOrder(self.location) if not self.control_group_order.done(observations): return self.control_group_order elif not self.previous_order or self.previous_order.done(observations): current_state = StateBuilder().build_state(self.location, observations) if self.previous_action is not None: self.qlearn.learn(str(self.previous_state), self.previous_action, 0, str(current_state)) rl_action = self.qlearn.choose_action(str(current_state)) self.previous_state = current_state self.previous_action = rl_action self.previous_order = self.smart_actions.order(rl_action) return self.previous_order
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.building_built: if self.build_action_id() in observations.available_actions(): unit_y, unit_x = self.base_location.locate_command_center( observations.screen()) if unit_x.any(): target = self.base_location.transform_distance( int(unit_x.mean()), self.x_from_base, int(unit_y.mean()), self.y_from_base) self.building_built = True return self.build_action(target) elif not self.select_scv_order.done(observations): return self.select_scv_order.execute(observations) elif not self.building_rallied: if not self.building_selected: unit_type = observations.screen().unit_type() unit_y, unit_x = (unit_type == self.building_type()).nonzero() if unit_y.any(): target = [int(unit_x.mean()), int(unit_y.mean())] self.building_selected = True return self.actions.select_point(target) else: self.building_rallied = True if self.base_location.command_center_is_top_left(): target = [29, 21] else: target = [29, 46] return self.actions.rally_units_minimap(target) return self.actions.no_op()
def __init__(self, first_observations: Observations): player_y, player_x = (first_observations.minimap().player_relative() == _PLAYER_SELF).nonzero() self.base_top_left = player_y.mean() <= 31 unit_type = first_observations.screen().unit_type() self.unit_type_ids = UnitTypeIds() self.cc_y, self.cc_x = ( unit_type == self.unit_type_ids.terran_command_center()).nonzero()
def step(self, obs): super(SCVControlGroupsAgent, self).step(obs) observations = Observations(obs) if observations.first(): self.base_location = Location(observations) self.order = PrepareSCVControlGroupsOrder(self.base_location) print(observations.control_groups()) return self.order.execute(observations)
def step(self, obs): super(ScoutingAgent, self).step(obs) observations = Observations(obs) if observations.first(): base_location = Location(observations) self.commander = ScoutingCommander(base_location, self.infinite_scouting) return self.commander.order(observations, self.steps).execute(observations)
def missing_supply_depot(self, observations: Observations, counter: BuildingCounter) -> bool: expectMore = self.expected_supply_depot > counter.supply_depots_count( observations) supplyAlmostFull = observations.player().food_cap( ) - observations.player().food_used() <= 4 buildingOne = isinstance(self.current_order, BuildSupplyDepot) # but still build several in a row, needs to detect if a supply building is in progress return expectMore and supplyAlmostFull and not buildingOne
def _extra_supply_depots(self, observations: Observations) -> Order: counter = BuildingCounter() expectMore = 8 > counter.supply_depots_count(observations) supplyAlmostFull = observations.player().food_cap( ) - observations.player().food_used() <= 2 if expectMore and supplyAlmostFull: return BuildSupplyDepot(self.location) else: return NoOrder()
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.select_scv_order.done(observations): return self.select_scv_order.execute(observations) elif self.action_ids.move_screen() in observations.available_actions(): unit_type = observations.screen().unit_type() unit_y, unit_x = ( unit_type == self.unit_type_ids.terran_refinery()).nonzero() if unit_y.any(): target = [int(unit_x.mean()), int(unit_y.mean())] self.scv_sent_to_refinery = True return self.actions.move_screen(target) return self.actions.no_op()
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.builder_scv_selected: self.builder_scv_selected = True print("select builder") return SelectSCV(self.base_location).execute(observations) # https://itnext.io/how-to-locate-and-select-units-in-pysc2-2bb1c81f2ad3 elif not self.refinery_building and self.action_ids.build_refinery( ) in observations.available_actions(): unit_type = observations.screen().unit_type() vespene_y, vespene_x = (unit_type == self.unit_type_ids. neutral_vespene_geyser()).nonzero() vespene_geyser_count = int(math.ceil(len(vespene_y) / 97)) units = [] for i in range(0, len(vespene_y)): units.append((vespene_x[i], vespene_y[i])) kmeans = KMeans(vespene_geyser_count) kmeans.fit(units) vespene1_x = int(kmeans.cluster_centers_[0][0]) vespene1_y = int(kmeans.cluster_centers_[0][1]) self.refinery_target = [vespene1_x, vespene1_y] self.refinery_building = True print("refinery building") return self.actions.build_refinery(self.refinery_target) elif self.refinery_building and not self.refinery_selected: unit_type = observations.screen().unit_type() refinery_y, refinery_x = ( unit_type == self.unit_type_ids.terran_refinery()).nonzero() if refinery_y.any(): self.refinery_selected = True print("refinery selected") return self.actions.select_point(self.refinery_target) elif self.refinery_selected and not self.first_collector_scv_selected: if observations.single_select().is_built(): self.first_collector_scv_selected = True print("select first collector") return SelectSCV(self.base_location).execute(observations) elif self.first_collector_scv_selected and not self.first_collector_scv_sent: self.first_collector_scv_sent = True print("sent first collector") return self.actions.harvest_gather(self.refinery_target) elif self.first_collector_scv_sent and not self.second_collector_scv_selected: self.second_collector_scv_selected = True print("select second collector") return SelectSCV(self.base_location).execute(observations) elif self.second_collector_scv_selected and not self.second_collector_scv_sent: self.second_collector_scv_sent = True print("sent second collector") return self.actions.harvest_gather(self.refinery_target) return self.actions.no_op()
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.scv_selected: if observations.player().idle_worker_count() > 0: self.scv_selected = True return self.actions.select_idle_worker() else: unit_type = observations.screen().unit_type() unit_y, unit_x = ( unit_type == self.unit_type_ids.terran_scv()).nonzero() rand_unit_index = random.randint(0, len(unit_y) - 1) target = [unit_x[rand_unit_index], unit_y[rand_unit_index]] self.scv_selected = True return self.actions.select_point(target) return self.actions.no_op()
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.supply_depot_built: if not self.select_scv_order.done(observations): return self.select_scv_order.execute(observations) elif self.action_ids.build_supply_depot( ) in observations.available_actions(): cc_y, cc_x = self.base_location.locate_command_center( observations.screen()) target = self.base_location.transform_distance( int(cc_x.mean()), self.x_from_base, int(cc_y.mean()), self.y_from_base) self.supply_depot_built = True return self.actions.build_supply_depot(target) return self.actions.no_op()
def send_scv_to_mineral( self, observations: Observations) -> actions.FunctionCall: if self.action_ids.harvest_gather() in observations.available_actions( ): unit_type = observations.screen().unit_type() unit_y, unit_x = (unit_type == self.unit_type_ids. neutral_mineral_field()).nonzero() if unit_y.any(): i = random.randint(0, len(unit_y) - 1) m_x = unit_x[i] m_y = unit_y[i] target = [int(m_x), int(m_y)] return self.actions.harvest_gather(target) return self.actions.no_op()
def execute(self, observations: Observations) -> actions.FunctionCall: if not self.command_center_selected: unit_type = observations.screen().unit_type() center_y, center_x = (unit_type == self.unit_type_ids. terran_command_center()).nonzero() center_x = round(center_x.mean()) center_y = round(center_y.mean()) target = [center_x, center_y] self.command_center_selected = True return self.actions.select_point(target) elif self.command_center_selected and self.action_ids.morph_orbital_command( ) in observations.available_actions(): self.orbital_command_built = True return self.actions.morph_orbital_command() return self.actions.no_op()
def attack_minimap(self, observations: Observations) -> actions.FunctionCall: do_it = True if not observations.single_select().empty() and observations.single_select().unit_type() == self.unit_type_ids.terran_scv(): do_it = False if not observations.multi_select().empty() and observations.multi_select().unit_type(0) == self.unit_type_ids.terran_scv(): do_it = False if do_it and self.action_ids.attack_minimap() in observations.available_actions(): x_offset = random.randint(-1, 1) y_offset = random.randint(-1, 1) target = self.location.transform_location(int(self.x) + (x_offset * 8), int(self.y) + (y_offset * 8)) return self.actions.attack_minimap(target) return self.actions.no_op()
def execute(self, observations: Observations) -> actions.FunctionCall: if self.done(observations): self._reset() elif self._train_action_id() in observations.available_actions(): self.already_trained = self.already_trained + 1 return self._train_action() elif not self.barracks_selected: unit_type = observations.screen().unit_type() unit_y, unit_x = ( unit_type == self.unit_type_ids.terran_barracks()).nonzero() if unit_y.any(): target = [int(unit_x.mean()), int(unit_y.mean())] self.barracks_selected = True return self.actions.select_point(target) return self.actions.no_op()
def _research_concussive_shells( self, observations: Observations) -> actions.FunctionCall: if self.action_ids.research_concussive_shells( ) in observations.available_actions(): self.step = self.step + 1 return self.actions.research_concussive_shells() return self.actions.no_op()
def _research_combat_shield( self, observations: Observations) -> actions.FunctionCall: if self.action_ids.research_combat_shield( ) in observations.available_actions(): self.step = self.step + 1 return self.actions.research_combat_shield() return self.actions.no_op()
def supply_depots_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() depot_y, depot_x = ( unit_type == unit_type_ids.terran_supply_depot()).nonzero() supply_depot_count = int(round(len(depot_y) / 69)) return supply_depot_count
def _select_a_new_vcs_from_all_group( self, observations: Observations) -> actions.FunctionCall: if self.action_ids.select_unit() in observations.available_actions(): self.step = self.step + 1 action = self.actions.select_unit(self.scv_index_in_all_group) self.scv_index_in_all_group = self.scv_index_in_all_group + 1 return action
def barracks_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() barracks_y, barracks_x = ( unit_type == unit_type_ids.terran_barracks()).nonzero() barracks_count = int(round(len(barracks_y) / 137)) return barracks_count
def refineries_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() unit_y, unit_x = ( unit_type == unit_type_ids.terran_refinery()).nonzero() units_count = int(round(len(unit_y) / 97)) return units_count
def factories_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() factories_y, factories_x = ( unit_type == unit_type_ids.terran_factory()).nonzero() factories_count = int(round(len(factories_y) / 137)) return factories_count
def command_center_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() cc_y, cc_x = ( unit_type == unit_type_ids.terran_command_center()).nonzero() cc_count = 1 if cc_y.any() else 0 return cc_count
def execute(self, observations: Observations) -> actions.FunctionCall: if self.done(observations): self._reset() elif not self.army_selected: if self.action_ids.select_army() in observations.available_actions( ): self.army_selected = True return self.actions.select_army() elif self.army_selected and self.action_ids.attack_minimap( ) in observations.available_actions(): self.push_ordered = True if self.base_location.command_center_is_top_left(): target = [39, 45] else: target = [21, 24] return self.actions.attack_minimap(target) return self.actions.no_op()
def executable(self, observations: Observations) -> bool: unit_type = observations.screen().unit_type() unit_y, unit_x = (unit_type == self.unit_type_ids. terran_barracks_techlab()).nonzero() if unit_y.any(): return True else: return False
def techlab_barracks_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() techlabs_y, techlabs_x = ( unit_type == unit_type_ids.terran_barracks_techlab()).nonzero() if techlabs_y.any(): return 1 return 0
def reactor_barracks_count(self, observations: Observations) -> int: unit_type = observations.screen().unit_type() unit_type_ids = UnitTypeIds() reactor_y, reactor_x = ( unit_type == unit_type_ids.terran_barracks_reactor()).nonzero() if reactor_y.any(): return 1 return 0
def _select_command_center( self, observations: Observations) -> actions.FunctionCall: unit_type = observations.screen().unit_type() cc_y, cc_x = ( unit_type == self.unit_type_ids.terran_command_center()).nonzero() if cc_y.any(): target = [round(cc_x.mean()), round(cc_y.mean())] return self.actions.select_point(target) return self.actions.no_op()