예제 #1
0
 async def build_pylons(self):
     if self.supply_left < 6 and self.supply_used < 195 and (
             not self.already_pending(PYLON)
             or self.minerals > 600) and self.can_afford(PYLON):
         bot_logger.log_action(self, 'building pylon')
         if self.units(PYLON).amount < 1:
             await self.build(PYLON, near=self.main_base_ramp.top_center)
         else:
             await self.build_in_main(PYLON, 5, 40)
예제 #2
0
 async def build_workers(self):
     worker_count = self.workers.amount
     nexus_count = self.units(NEXUS).amount
     workers_per_nexus = worker_count / nexus_count if nexus_count > 0 else worker_count
     if (workers_per_nexus >= 24
             and not self.minerals > 800) or worker_count >= 70:
         return
     for nexus in self.units(NEXUS).ready.noqueue:
         if self.can_afford(PROBE):
             bot_logger.log_action(self, 'training probe')
             await self.do(nexus.train(PROBE))
예제 #3
0
async def upgrade_zergling_speed(bot: BotAI):
    spawning_pool = bot.units(UnitTypeId.SPAWNINGPOOL).ready
    if not spawning_pool.exists:
        return False
    spawning_pool = spawning_pool.first
    metabolic_boost = AbilityId.RESEARCH_ZERGLINGMETABOLICBOOST
    if bot.can_afford(metabolic_boost):
        available_abilities = await bot.get_available_abilities(spawning_pool)
        if metabolic_boost in available_abilities:
            bot_logger.log_action(bot, 'upgrading metabolic boost')
            await bot.do(spawning_pool(metabolic_boost))
            return True
    return False
예제 #4
0
 async def build_expansion(self):
     if not await self.get_next_expansion() or self.already_pending(NEXUS):
         return
     nexus_count = self.units(NEXUS).amount
     should_early_expand = nexus_count < 2 and self.time > 400
     if should_early_expand and self.can_afford(NEXUS):
         bot_logger.log_action(self, 'building expansion')
         await self.expand_now()
     elif self.minerals > max(nexus_count, 1) * 400:
         bot_logger.log_action(self, 'building expansion')
         try:
             r = await self.expand_now()
         except Exception as e:
             print(e)
예제 #5
0
async def build_building_once(bot: BotAI,
                              building: UnitTypeId,
                              location: Union[Point2, Point3, Unit],
                              max_distance: int = 20,
                              unit: Optional[Unit] = None,
                              random_alternative: bool = True,
                              placement_step: int = 2):
    if not bot.units(building).ready.exists and not bot.already_pending(
            building) and bot.can_afford(building):
        bot_logger.log_action(bot,
                              "building {} at {}".format(building, location))
        return await bot.build(building,
                               near=location,
                               max_distance=max_distance,
                               unit=unit,
                               random_alternative=random_alternative,
                               placement_step=placement_step)
예제 #6
0
    async def build_gas(self):
        for nexus in self.units(NEXUS).ready:
            if self.supply_used < 22:
                break
            if self.already_pending(ASSIMILATOR):
                break

            vespene_geysers = self.state.vespene_geyser.closer_than(
                10.0, nexus)
            for vespene_geyser in vespene_geysers:
                if not self.can_afford(ASSIMILATOR):
                    break
                worker = self.select_build_worker(vespene_geyser.position)
                if worker is None:
                    break
                if not self.units(ASSIMILATOR).closer_than(
                        1.0, vespene_geyser).exists:
                    bot_logger.log_action(self, 'building assimilator')
                    await self.do(worker.build(ASSIMILATOR, vespene_geyser))
예제 #7
0
 async def warp_new_units(self, proxy: Unit):
     for warpgate in self.units(WARPGATE).ready:
         abilities = await self.get_available_abilities(warpgate)
         # all the units have the same cooldown anyway so let's just look at ZEALOT
         if AbilityId.WARPGATETRAIN_ZEALOT in abilities:
             pos = proxy.position.to2.random_on_distance(4)
             placement = await self.find_placement(
                 AbilityId.WARPGATETRAIN_STALKER, pos, placement_step=1)
             if placement is None:
                 # return ActionResult.CantFindPlacementLocation
                 print("can't place")
                 return
             # make stalkers when possible. 70% chance after zealot charge
             if (not self.zealot_charge_started or random.randrange(100) <
                     40) and self.can_afford(STALKER):
                 bot_logger.log_action(
                     self, 'warping in stalker {}'.format(placement))
                 await self.do(warpgate.warp_in(STALKER, placement))
             elif self.can_afford(
                     SENTRY) and self.minerals / self.vespene < .3:
                 bot_logger.log_action(
                     self, 'warping in sentry {}'.format(placement))
                 await self.do(warpgate.warp_in(SENTRY, placement))
             elif self.can_afford(ZEALOT):
                 bot_logger.log_action(
                     self, 'warping in zealot {}'.format(placement))
                 await self.do(warpgate.warp_in(ZEALOT, placement))
             else:
                 return
예제 #8
0
 async def on_step(self, iteration):
     if iteration == 0:
         await self.first_iteration()
     if iteration % 8 == 0:
         self.manage_booming()
     if iteration % 50 == 0:
         await self.position_army()
         await self.set_rally_points()
         await self.distribute_workers()
         if 600 < self.time < 610:
             await self.scout_enemy()
     if iteration % 10 == 0 and self.time % 60 < 5:
         await self.fortify_proxy()
         await self.fortify_expansions()
     await self.chronoboost()
     await self.build_workers()
     await self.build_pylons()
     await self.build_gas()
     await self.improve_military_tech()
     if not self.booming:
         await self.build_standing_military()
     await self.build_expansion()
     if self.attacking and iteration % 2 == 0:
         if len(self.get_combat_forces()) < 5:
             self.attacking = False
         await micro_army(self)
     else:
         await self.attack_when_ready()
     if self.units(
             CYBERNETICSCORE
     ).ready.amount >= 1 and not self.proxy_built and self.can_afford(
             PYLON):
         for x in range(20, 40, 10):
             bot_logger.log_action(self, 'building proxy pylon')
             await build_proxy(self, distance_towards_location=x)
         self.proxy_built = True
예제 #9
0
 async def build_standing_military(self):
     has_cybercore = self.units(CYBERNETICSCORE).ready.exists
     for robo in self.units(ROBOTICSFACILITY).ready.noqueue:
         if self.can_afford(IMMORTAL):
             bot_logger.log_action(self, 'training immortal')
             await self.do(robo.train(IMMORTAL))
     if not self.warpgate_finished:
         for gateway in self.units(GATEWAY).ready.noqueue:
             if has_cybercore and self.vespene > 0 and self.minerals / self.vespene < .3 and self.can_afford(
                     SENTRY):
                 bot_logger.log_action(self, 'training sentry')
                 await self.do(gateway.train(SENTRY))
             elif has_cybercore and self.can_afford(STALKER):
                 bot_logger.log_action(self, 'training stalker')
                 await self.do(gateway.train(STALKER))
             elif self.can_afford(ZEALOT):
                 bot_logger.log_action(self, 'training zealot')
                 await self.do(gateway.train(ZEALOT))
     if self.units(PYLON).exists:
         proxy_pylon = get_closest_pylon_to_enemy_base(self)
         await self.warp_new_units(proxy_pylon)
예제 #10
0
    async def improve_military_tech(self):
        if self.units(PYLON).ready.exists:
            pylon = self.units(PYLON).ready.closer_than(
                50, self.start_location).first

            if self.units(GATEWAY).ready.exists:
                # build a cybernetics core
                if not self.units(CYBERNETICSCORE):
                    if self.can_afford(
                            CYBERNETICSCORE
                    ) and not self.already_pending(CYBERNETICSCORE):
                        bot_logger.log_action(self,
                                              'buildilng cybernetics core')
                        await self.build(CYBERNETICSCORE, near=pylon)
                # builds robotics facilities
                elif not self.already_pending(
                        ROBOTICSFACILITY) and self.can_afford(
                            ROBOTICSFACILITY):
                    if not self.units(ROBOTICSFACILITY) and self.time > 250:
                        await self.build(ROBOTICSFACILITY, near=pylon)
                    if self.time > 400 and self.units(
                            ROBOTICSFACILITY).amount < 2:
                        await self.build(ROBOTICSFACILITY, near=pylon)
                # research warpgate
                elif self.units(
                        CYBERNETICSCORE).ready.exists and self.can_afford(
                            AbilityId.RESEARCH_WARPGATE
                        ) and not self.warpgate_started:
                    cybercore = self.units(CYBERNETICSCORE).ready.first
                    await self.do(cybercore(AbilityId.RESEARCH_WARPGATE))
                    self.warpgate_started = True
                    self.warpgate_start_time = self.time

                # manage warpgate_finished
                if not self.warpgate_finished and self.is_researching_warpgate and not self.time - \
                        self.warpgate_start_time > 120:
                    self.warpgate_finished = True

            gateway_warpgate_count = self.units(GATEWAY).amount + self.units(
                WARPGATE).amount
            # build first gateway
            if gateway_warpgate_count < 1:
                if self.can_afford(
                        GATEWAY) and not self.already_pending(GATEWAY):
                    bot_logger.log_action(self, 'building first gateway')
                    await self.build(GATEWAY, near=pylon)
            # build second gateway
            if gateway_warpgate_count < 2 and self.time > 200 and not self.already_pending(
                    GATEWAY):
                if self.can_afford(GATEWAY):
                    bot_logger.log_action(self, 'building second gateway')
                    await self.build(GATEWAY, near=pylon)
            # build third gatway
            if gateway_warpgate_count < 3 and self.time > 300 and not self.already_pending(
                    GATEWAY):
                if self.can_afford(GATEWAY):
                    bot_logger.log_action(self, 'building third gateway')
                    await self.build(GATEWAY, near=pylon)
            # build 4-20 gateways
            if gateway_warpgate_count >= 3 and gateway_warpgate_count < 20 and self.minerals > 900 and self.time > 300 and not self.already_pending(
                    GATEWAY):
                if self.can_afford(GATEWAY):
                    bot_logger.log_action(
                        self,
                        'building gateway #{}'.format(gateway_warpgate_count))
                    await self.build(GATEWAY, near=pylon)

            if self.time > 300:
                # build forge
                if not self.units(
                        FORGE).ready.amount > 1 and not self.already_pending(
                            FORGE) and self.can_afford(FORGE):
                    bot_logger.log_action(self, 'building forge')
                    await self.build(FORGE, near=pylon)
                # manage forge upgrades
                else:
                    for forge in self.units(FORGE).ready.noqueue:
                        if forge:
                            forge_abilities = await self.get_available_abilities(
                                forge)
                            for upgrade in self.all_upgrades:
                                if upgrade in forge_abilities and self.minerals > 400 and self.vespene > 400:
                                    bot_logger.log_action(
                                        self,
                                        'buying upgrade {}'.format(upgrade))
                                    return await self.do(forge(upgrade))

            if self.time > 550:
                # build twlighlight council
                has_twilight = self.units(TWILIGHTCOUNCIL).ready.exists
                if not has_twilight and not self.already_pending(
                        TWILIGHTCOUNCIL) and self.can_afford(TWILIGHTCOUNCIL):
                    await self.build(TWILIGHTCOUNCIL, near=pylon)
                elif has_twilight:
                    twilight_council = self.units(TWILIGHTCOUNCIL).ready.first
                    twilight_abilities = await self.get_available_abilities(
                        twilight_council)
                    twilight_upgrades = [AbilityId.RESEARCH_CHARGE]
                    for upgrade in twilight_upgrades:
                        if upgrade in twilight_abilities and self.minerals > 400 and self.vespene > 400:
                            bot_logger.log_action(
                                self, 'buying upgrade {}'.format(upgrade))
                            return await self.do(twilight_council(upgrade))
                            self.zealot_charge_started = True
예제 #11
0
async def build_overlord(bot: BotAI, larva):
    if bot.can_afford(UnitTypeId.OVERLORD):
        unit = larva if larva else get_random_larva(bot)
        if unit:
            bot_logger.log_action(bot, "building overlord")
            return await bot.do(unit.train(UnitTypeId.OVERLORD))
예제 #12
0
async def build_zergling(bot: BotAI, larva):
    unit = larva if larva else get_random_larva(bot)
    if unit and bot.can_afford(UnitTypeId.ZERGLING) and bot.units(UnitTypeId.SPAWNINGPOOL).ready.exists:
        bot_logger.log_action(bot, "building zergling")
        return await bot.do(unit.train(UnitTypeId.ZERGLING))
예제 #13
0
async def build_drone(bot: BotAI, larva=None):
    unit = larva if larva else get_random_larva(bot)
    if unit:
        bot_logger.log_action(bot, "building drone")
        return await bot.do(unit.train(UnitTypeId.DRONE))