Esempio n. 1
0
    async def on_step(self, iteration):
        cc = self.units(COMMANDCENTER)
        if not cc.exists:
            return
        else:
            cc = cc.first

        if self.can_afford(SCV) and self.workers.amount < 16 and cc.noqueue:
            await self.do(cc.train(SCV))

        depot_placement_positions = self.main_base_ramp.corner_depots
        # Uncomment the following if you want to build 3 supplydepots in the wall instead of a barracks in the middle + 2 depots in the corner
        # depot_placement_positions = self.main_base_ramp.corner_depots | {self.main_base_ramp.depot_in_middle}

        barracks_placement_position = None
        barracks_placement_position = self.main_base_ramp.barracks_correct_placement
        # If you prefer to have the barracks in the middle without room for addons, use the following instead
        # barracks_placement_position = self.main_base_ramp.barracks_in_middle

        all_depots = self.units(SUPPLYDEPOT) | self.units(SUPPLYDEPOTLOWERED)

        # Filter locations close to finished supply depots
        wall_depots = None
        if all_depots:
            wall_depots = Units(
                list(depot for depot in all_depots if min(
                    depot.distance_to(d)
                    for d in depot_placement_positions) <= 1), self.game_info)
            depot_placement_positions = {
                d
                for d in depot_placement_positions
                if all_depots.closest_distance_to(d) > 1
            }
        if iteration % 10 == 0:
            logger.info(
                f"wall_depots: {wall_depots}, depot_placement_positions: {depot_placement_positions}"
            )
        # Build 2 depots for wall
        if self.can_afford(
                SUPPLYDEPOT) and not self.already_pending(SUPPLYDEPOT):
            if len(depot_placement_positions) > 0:
                # Choose any depot location
                target_depot_location = depot_placement_positions.pop()
                gathering = self.workers.gathering
                if gathering:  # if workers were found
                    w = gathering.random
                    await self.do(w.build(SUPPLYDEPOT, target_depot_location))

        # Build barracks for wall
        if all_depots.ready.exists and self.should_build(BARRACKS):
            if not self.units(BARRACKS).exists:
                gathering = self.workers.gathering
                if gathering and barracks_placement_position:
                    w = gathering.random
                    await self.do(
                        w.build(BARRACKS, barracks_placement_position))

        # Build refinery after barracks
        if (self.already_pending(BARRACKS) or self.units(BARRACKS).amount) \
                and not self.units(REFINERY).exists and not self.already_pending(REFINERY) \
            and self.can_afford(REFINERY):
            vgs = self.state.vespene_geyser.closer_than(20.0, cc)
            for vg in vgs:
                if self.units(REFINERY).closer_than(1.0, vg).exists:
                    break

                worker = self.select_build_worker(vg.position)
                if worker is None:
                    break

                await self.do(worker.build(REFINERY, vg))
                break

        # Assign workers to refinery
        for refinery in self.units(REFINERY):
            if refinery.assigned_harvesters < refinery.ideal_harvesters:
                w = self.workers.closer_than(20, refinery)
                if w.exists:
                    await self.do(w.random.gather(refinery))

        # Build more supply depots
        if self.supply_left <= 6:
            if self.should_build(SUPPLYDEPOT):
                await self.build(SUPPLYDEPOT,
                                 near=cc.position.towards(
                                     self.game_info.map_center, 8))

        # Build reactors
        for barracks in self.units(BARRACKS).ready:
            reactor = [
                reactor for reactor in self.units(BARRACKSREACTOR)
                if reactor.add_on_land_position == barracks.position
            ]
            if reactor:
                reactor = reactor[0]

            if not reactor and self.can_afford(BARRACKSREACTOR):
                await self.do(barracks.build(BARRACKSREACTOR))

            # Build marines
            elif self.can_afford(MARINE) and self.supply_left > 0 and \
                    len(barracks.orders) < 2 and reactor.is_ready:
                await self.do(barracks.train(MARINE))

        # Build more barracks after the first is done
        if self.units(BARRACKS).ready.exists and self.should_build(BARRACKS):
            await self.build(BARRACKS,
                             near=cc.position.towards(
                                 self.game_info.map_center, 8))

        # Assign idle workers to minerals
        for scv in self.units(SCV).idle:
            await self.do(scv.gather(self.state.mineral_field.closest_to(cc)))

        if barracks_placement_position and iteration % 50 == 0:
            marines_at_wall = self.units(MARINE).closer_than(
                20, barracks_placement_position)

            # Attack when 12 are at the wall
            if marines_at_wall.amount >= 12:
                for marine in marines_at_wall:
                    await self.do(marine.attack(self.enemy_start_locations[0]))

            # Move idle marines to wall
            elif wall_depots:
                idle_marines = self.units(MARINE).idle
                for marine in idle_marines:
                    if wall_depots.closest_distance_to(marine) > 3:
                        await self.do(marine.move(wall_depots.random))

        # Lower depot when no enemies are nearby or we have a defending force
        for depot in self.units(SUPPLYDEPOT).ready:
            if self.units(MARINE).closer_than(6, depot).amount >= 8:
                await self.do(depot(MORPH_SUPPLYDEPOT_LOWER))
                continue

            for unit in self.known_enemy_units.not_structure:
                if unit.position.to2.distance_to(depot.position.to2) < 15:
                    break
            else:
                await self.do(depot(MORPH_SUPPLYDEPOT_LOWER))

        # Raise depot when enemies are nearby unless we have a defending force
        for depot in self.units(SUPPLYDEPOTLOWERED).ready:
            if self.units(MARINE).closer_than(6, depot).amount >= 8:
                continue

            for unit in self.known_enemy_units.not_structure:
                if unit.position.to2.distance_to(depot.position.to2) < 10:
                    await self.do(depot(MORPH_SUPPLYDEPOT_RAISE))
                    break

        # List all buildings in need of repairs
        repairs_needed = [
            building for building in self.units(SUPPLYDEPOT).ready
            | self.units(SUPPLYDEPOTLOWERED).ready | self.units(BARRACKS).ready
            if building.health_percentage < 1
        ]

        # Send on average 3 SCVs to each building in need of repairs
        repairers_active = len(
            [scv for scv in self.workers if scv.is_repairing])
        for index in range(0, max(0,
                                  len(repairs_needed) * 3 - repairers_active)):
            target = repairs_needed[index % len(repairs_needed)]
            gathering = self.workers.gathering.closest_to(target)
            if gathering:
                await self.do(gathering.repair(target))
Esempio n. 2
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)