Exemplo n.º 1
0
    async def do_queen_micro(self,
                             queen: Unit,
                             enemy: Units,
                             grid: Optional[np.ndarray] = None) -> None:
        if not queen:
            return

        in_range_enemies: Units = self.bot.enemy_units.in_attack_range_of(
            queen)
        in_range_enemies = in_range_enemies.exclude_type(
            {UnitID.EGG, UnitID.LARVA})
        if in_range_enemies:
            target: Unit = self._get_target_from_in_range_enemies(
                in_range_enemies)
            if target:
                if self.attack_ready(queen, target):
                    queen.attack(target)
                elif self.map_data and grid is not None:
                    await self.move_towards_safe_spot(queen, grid)
                else:
                    distance: float = queen.ground_range + queen.radius + target.radius
                    move_to: Point2 = target.position.towards(queen, distance)
                    if self.bot.in_pathing_grid(move_to):
                        queen.move(move_to)
            else:
                queen.attack(in_range_enemies.center)
        elif enemy:
            target = enemy.closest_to(queen)
            queen.attack(target)
        elif self.bot.all_enemy_units:
            target = self.bot.all_enemy_units.closest_to(queen)
            queen.attack(target)
Exemplo n.º 2
0
    async def on_before_start(self):
        """
        Override this in your bot class. This function is called before "on_start"
        and before expansion locations are calculated.
        Not all data is available yet.
        """

        # Start building first worker before doing any heavy calculations
        # This is only needed for real time, but we don't really know whether the game is real time or not.
        await self.start_first_worker()
        self._client.game_step = int(self.config["general"]["game_step_size"])

        if self.realtime_split:
            # Split workers
            mfs = self.mineral_field.closer_than(10,
                                                 self.townhalls.first.position)
            workers = Units(self.workers, self)

            for mf in mfs:  # type: Unit
                if workers:
                    worker = workers.closest_to(mf)
                    self.do(worker.gather(mf))
                    workers.remove(worker)

            for w in workers:  # type: Unit
                self.do(w.gather(mfs.closest_to(w)))
            await self._do_actions(self.actions)
            self.actions.clear()
Exemplo n.º 3
0
    async def newNexusAndBase(self):
        if self.bot.units(NEXUS).amount < 2 and not self.bot.already_pending(
                NEXUS) and self.bot.can_afford(NEXUS):
            nexus = self.bot.units(NEXUS).first
            worker = self.bot.workers[0]
            minerals_next_nexus = self.bot.state.mineral_field.closer_than(
                15, nexus)
            minerals = self.bot.state.mineral_field
            minerals = Units(
                self.removeMinerals(minerals_next_nexus, minerals),
                self.bot._game_data)
            mineral_field = minerals.closest_to(nexus)

            if not self.bot.units(PYLON).closer_than(
                    20.0, mineral_field
            ).exists and not self.bot.already_pending(PYLON):
                print("Build ", PYLON)
                await self.bot.build(PYLON,
                                     mineral_field,
                                     max_distance=10,
                                     unit=worker)

            if self.bot.can_afford(NEXUS):
                print("Build ", NEXUS)
                self.building_nexus = True
                await self.bot.build(NEXUS,
                                     mineral_field,
                                     max_distance=10,
                                     unit=worker)
Exemplo n.º 4
0
class BallFormation():
    def __init__(self, knowledge):
        self.ai = knowledge.ai
        self.knowledge: 'Knowledge' = knowledge
        self.unit_values: 'UnitValue' = knowledge.unit_values
        self.our_units: Units
        self.keep_together: List[UnitTypeId] = [
            UnitTypeId.COLOSSUS, UnitTypeId.OBSERVER, UnitTypeId.PHOENIX
        ]
        self.enemy_units_in_combat: Units
        self.units_in_combat: Units
        self.units_to_regroup: Units
        self.minimum_distance = 3.5

    def prepare_solve(self, our_units: Units, goal_position: Point2,
                      combat_data: Dict[int, EnemyData], units_median: Point2):
        self.our_units = our_units

        time = self.knowledge.ai.time
        units_behind_tags = []
        units_behind_tags.clear()
        average_distance2 = 0
        wait_ended = False

        self.enemy_units_in_combat = Units([], self.ai)
        self.units_in_combat = Units([], self.ai)

        unit_count = len(our_units)
        # wait for 15% reinforcements
        wait_count = unit_count * 0.15
        if any(our_units):
            our_units = our_units.sorted_by_distance_to(goal_position)

            self.units_gather = units_median

            for unit in our_units:

                enemy_data = combat_data[unit.tag]
                if enemy_data.powered_enemies.exists:
                    self.enemy_units_in_combat.append(enemy_data.closest)
                    self.units_in_combat.append(unit)
                elif enemy_data.enemies_exist:
                    self.units_in_combat.append(unit)

    def solve_combat(self, goal: CombatGoal,
                     command: CombatAction) -> CombatAction:
        if self.enemy_units_in_combat.exists:
            # Move in to assist closest friendly in combat
            closest_enemy = self.enemy_units_in_combat.closest_to((goal.unit))
            return CombatAction(goal.unit, closest_enemy.position,
                                command.is_attack)

        if goal.unit.distance_to(
                self.units_gather
        ) > self.minimum_distance + len(self.our_units) / 10:
            return CombatAction(goal.unit, self.units_gather, False)
        return command
Exemplo n.º 5
0
 def _get_builder(self, location=None):
     ws = self.bot.workers.gathering
     if ws:  # if workers found
         not_scouts = Units([w for w in ws if self.scouting_worker is None or w.tag != self.scouting_worker.tag], self.bot.game_data())
         if not_scouts.amount > 0:
             if location is None:
                 return not_scouts.furthest_to(not_scouts.center)
             else:
                 return not_scouts.closest_to(location)
     return None
Exemplo n.º 6
0
    def closest_distance_between_our_theirs(self, combined_enemies: Units) -> Tuple[float, Optional[Unit]]:
        own = self.ai.units.filter(
            lambda unit: not unit.is_structure and unit.type_id not in self.unit_values.combat_ignore
        )
        closest: Optional[Unit] = None
        d = 0
        for own_unit in own:  # type: Unit
            closest_temp = combined_enemies.closest_to(own_unit)
            temp_distance = closest_temp.distance_to(own_unit)
            if closest is None or temp_distance < d:
                d = temp_distance
                closest = closest_temp

        return (d, closest)
Exemplo n.º 7
0
    def solve_combat(self, goal: CombatGoal, command: CombatAction, enemies: EnemyData) -> List[CombatAction]:
        oracle = goal.unit

        if not oracle.has_buff(BuffId.ORACLEWEAPON):
            goal.ready_to_shoot = False

        air_shooter_enemies = Units([], self.ai)
        enemy: Unit

        power = ExtendedPower(self.unit_values)

        for enemy in enemies.close_enemies:
            if self.unit_values.air_range(enemy) < enemy.distance_to(oracle) + 1:
                air_shooter_enemies.append(enemy)
                power.add_unit(enemy)
                if self.unit_values.is_static_air_defense(enemy):
                    power.add(5) # can't beat turrets with oracle

        enemy_center = enemies.close_enemies.center

        for air_shooter in air_shooter_enemies:  # type: Unit
            if air_shooter.is_light and not air_shooter.is_flying:
                power.add_units(air_shooter_enemies)
            else:
                power.add_units(air_shooter_enemies * 2)

        time = self.knowledge.ai.time
        if goal.move_type == MoveType.PanicRetreat and oracle.has_buff(BuffId.ORACLEWEAPON):
            return self.disable_beam(oracle)

        possible_targets = enemies.close_enemies.filter(lambda u: not u.is_flying and not u.is_structure and u.is_light)

        if possible_targets.exists:
            if oracle.energy > 50 and possible_targets.closest_distance_to(oracle) < 5 and not oracle.has_buff(BuffId.ORACLEWEAPON):
                return self.enable_beam(oracle)

        if  power.air_power > 0 and power.air_power <= 3:
            target = air_shooter_enemies.closest_to(oracle)
            if target.is_light or target.health_percentage < 0.5:
                if not oracle.has_buff(BuffId.ORACLEWEAPON):
                    return self.enable_beam(oracle)
                # Kill the target
                return [CombatAction(oracle, target, True)]

            #target_pos = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
            #move_step = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, target_pos)
            return [CombatAction(oracle, target.position, True)]
        elif goal.ready_to_shoot and possible_targets:
            return [CombatAction(oracle, possible_targets.closest_to(oracle), True)]
        elif power.air_power > 12:
            # Panic retreat to whatever direction
            if goal.move_type in offensive:
                new_target: Point2 = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
                step = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, new_target)
                # backstep: Point2 = self.knowledge.pathing_manager.find_weak_influence_air(oracle.position, 7)
                move_action = CombatAction(oracle, step, False)
            else:
                backstep = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, goal.target)
                move_action = CombatAction(oracle, backstep, False)

            # Todo disable beam?
            return [move_action]

        elif power.air_power > 3:
            # Try kiting while killing the target
            target = self.knowledge.pathing_manager.find_weak_influence_air(goal.target, 7)
            backstep = self.knowledge.pathing_manager.find_influence_air_path(oracle.position, target)

            if goal.move_type in offensive:
                move_action = CombatAction(oracle, backstep, False)
            else:
                move_action = CombatAction(oracle, backstep, False)

            if oracle.has_buff(BuffId.ORACLEWEAPON):
                if possible_targets:
                    closest = possible_targets.closest_to(oracle)
                    if closest.distance_to(oracle) < 5:
                        return [CombatAction(oracle, closest, True)]
                return [CombatAction(oracle, command.target, True), move_action]
            else:
                return [move_action]


        if possible_targets.exists:
            return [CombatAction(oracle, command.target, True)]
        else:
            return [CombatAction(oracle, command.target, False)]
Exemplo n.º 8
0
class TestUnits(unittest.TestCase):

    # @classmethod
    # def setUpClass(cls):
    #     pass

    # @classmethod
    # def tearDownClass(cls):
    #     pass

    def setUp(self):
        mock_proto_data1 = MockProtoData(tag=245346374,
                                         pos=Mock(x=-5, y=6, z=50),
                                         health=35,
                                         health_max=45,
                                         orders=[
                                             Mock(ability_id=AbilityId.ATTACK,
                                                  target_unit_tag=1337,
                                                  progress=1.0)
                                         ])
        mock_proto_data2 = MockProtoData(
            tag=245346375,
            pos=Mock(x=-2, y=7, z=50),
            orders=[
                Mock(ability_id=AbilityId.MOVE,
                     target_world_space_pos=Point2((0, 0)),
                     progress=1.0)
            ])
        mock_proto_data3 = MockProtoData(
            tag=245346376,
            pos=Mock(x=7, y=7, z=50),
        )
        self.mock_game_state = MockGameState()
        self.marine1 = Unit(mock_proto_data1, self.mock_game_state)
        self.marine2 = Unit(mock_proto_data2, self.mock_game_state)
        self.marine3 = Unit(mock_proto_data3, self.mock_game_state)
        self.marines = Units([self.marine1, self.marine2, self.marine3],
                             self.mock_game_state)
        self.emptyUnitsGroup = Units([], self.mock_game_state)

    def tearDown(self):
        # unnecessary here
        del self.marine1
        del self.marine2
        del self.marine3
        del self.marines
        del self.mock_game_state

    def test_amount(self):
        self.assertEqual(self.marines.amount, 3)
        self.assertEqual(self.emptyUnitsGroup.amount, 0)

    def test_empty(self):
        self.assertFalse(self.marines.empty)
        self.assertTrue(self.emptyUnitsGroup.empty)

    def test_exists(self):
        self.assertTrue(self.marines.exists)
        self.assertFalse(self.emptyUnitsGroup.exists)

    def test_find_by_tag(self):
        self.assertEqual(self.marines.find_by_tag(245346374), self.marine1)
        self.assertIsNone(self.marines.find_by_tag(245346))

    def test_first(self):
        self.assertEqual(self.marines.first, self.marine1)

    def test_random(self):
        self.assertTrue(
            self.marines.random in [self.marine1, self.marine2, self.marine3])

    def test_closest_distance_to(self):
        self.assertEqual(self.marines.closest_distance_to(Point2((10, 10))),
                         (3**2 + 3**2)**0.5)

    def test_closest_to(self):
        self.assertEqual(self.marines.closest_to(Point2((10, 10))),
                         self.marine3)

    def test_furthest_to(self):
        self.assertEqual(self.marines.furthest_to(Point2((10, 10))),
                         self.marine1)

    def test_closer_than(self):
        self.assertEqual(self.marines.closer_than(20, Point2((10, 10))),
                         self.marines)
        self.assertEqual(self.marines.closer_than(6, Point2((10, 10))),
                         Units([self.marine3], self.mock_game_state))
        self.assertEqual(self.marines.closer_than(2, Point2((10, 10))),
                         self.emptyUnitsGroup)

    def test_tags_in(self):
        self.assertEqual(
            self.marines.tags_in({245346374, 245346375}),
            Units([self.marine1, self.marine2], self.mock_game_state))
        self.assertEqual(self.marines.tags_in({}), self.emptyUnitsGroup)

    def test_tags_not_in(self):
        self.assertEqual(self.marines.tags_not_in({}), self.marines)
        self.assertEqual(
            self.marines.tags_not_in({245346374}),
            Units([self.marine2, self.marine3], self.mock_game_state))

    def test_of_type(self):
        self.assertEqual(self.marines.of_type(UnitTypeId.MARINE), self.marines)
        self.assertEqual(self.marines.of_type([UnitTypeId.MARINE]),
                         self.marines)

    def test_exclude_type(self):
        self.assertEqual(self.marines.exclude_type([UnitTypeId.MARINE]),
                         self.emptyUnitsGroup)

    def test_tags(self):
        self.assertSetEqual(self.marines.tags, {u.tag for u in self.marines})

    def test_noqueue(self):
        self.assertEqual(self.marines.noqueue,
                         Units([self.marine3], self.mock_game_state))

    def test_idle(self):
        self.assertEqual(self.marines.idle,
                         Units([self.marine3], self.mock_game_state))

    def test_owned(self):
        self.assertEqual(self.marines.owned, self.marines)

    def test_enemy(self):
        self.assertEqual(self.marines.enemy, self.emptyUnitsGroup)