Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sc2
- from sc2 import run_game, maps, Race, Difficulty
- from sc2.constants import HATCHERY, ZERGLING, QUEEN, LARVA, EFFECT_INJECTLARVA, \
- SPAWNINGPOOL, RESEARCH_ZERGLINGMETABOLICBOOST, OVERLORD, EXTRACTOR, DRONE, ROACHWARREN, ROACH, \
- QUEENSPAWNLARVATIMER, EVOLUTIONCHAMBER, RESEARCH_ZERGMISSILEWEAPONSLEVEL1, AbilityId, \
- RESEARCH_ZERGGROUNDARMORLEVEL1, HYDRALISKDEN, HYDRALISK, LAIR, RESEARCH_ZERGMISSILEWEAPONSLEVEL2, \
- RESEARCH_ZERGGROUNDARMORLEVEL2, PROBE, SCV, SPINECRAWLER, UPGRADETOLAIR_LAIR, CANCEL_MORPHLAIR, \
- ADEPTPHASESHIFT, DISRUPTORPHASED, RESEARCH_TUNNELINGCLAWS, RESEARCH_GLIALREGENERATION, \
- BURROWDOWN_ROACH, BURROWUP_ROACH, EGG
- from sc2.player import Bot, Computer
- # todo for v4 release
- # todo zerg rush defense
- # todo work defense have much better performance now but still not perfect usage wise
- # todo general micro
- # todo detection, high ground spotter
- # todo figure out a way to handle base loss
- # todo make the attacks periodic
- # todo make burrow micro work
- # todo attacking logic just find close buildings
- class ZergRoachv3(sc2.BotAI):
- def __init__(self):
- self.flag1 = False
- self.flag2 = False
- async def on_step(self, iteration):
- """globals so I dont repeat the same variable all the functions"""
- global larvas, roaches, drones, base_amount, hatcherys, sp, enemy_units, \
- roach, rw, lair, base, abilitys, suplyl, hydraden, hydra, base_exist, larva_exist, \
- evochambers
- larvas = self.units(LARVA)
- larva_exist = larvas.exists
- roach = self.units(ROACH)
- roaches = roach.amount
- drones = self.units(DRONE).amount
- hatcherys = self.townhalls
- base_exist = hatcherys.exists
- hydraden = self.units(HYDRALISKDEN)
- hydra = self.units(HYDRALISK)
- base_amount = hatcherys.amount
- sp = self.units(SPAWNINGPOOL)
- base = self.units(HATCHERY)
- enemy_units = self.known_enemy_units.not_structure
- rw = self.units(ROACHWARREN)
- lair = self.units(LAIR)
- evochambers = self.units(EVOLUTIONCHAMBER)
- abilitys = self.get_available_abilities
- suplyl = self.supply_left
- await self.defend_workerrush()
- if iteration % 7 or not self.flag2:
- await self.distribute_workers()
- await self.build_workers()
- await self.build_overlords()
- await self.build_hatchery()
- await self.build_spawning_pool()
- await self.upgrade_lair()
- await self.build_queens_inject_larva()
- await self.build_roach_warren()
- await self.build_extrator()
- await self.build_evochamber()
- await self.build_roaches()
- await self.defend_attack()
- await self.armor_attack()
- await self.build_hydraden()
- await self.build_hydras()
- await self.rw_upgrades()
- '''def seconds(self):
- return self.state.game_loop * 0.725 * (1 / 16)
- '''
- async def build_workers(self):
- """this logic works for now, maybe later I ll have to change(when I
- focus on the transition)"""
- if drones < 18 * base_amount \
- and self.can_afford(DRONE) and larva_exist \
- and suplyl > 0 and drones < 81:
- if base_amount > 3:
- if roaches > 7:
- await self.do(larvas.random.train(DRONE))
- else:
- await self.do(larvas.random.train(DRONE))
- async def build_overlords(self):
- """this logic can be improved, sometimes I get supply blocked for a
- little bit, nothing major"""
- if base_amount == 1:
- if suplyl < 3 and self.can_afford(OVERLORD) and larva_exist \
- and not self.already_pending(OVERLORD):
- await self.do(larvas.random.train(OVERLORD))
- elif suplyl < 11 and self.can_afford(OVERLORD) and larva_exist\
- and self.supply_cap != 200:
- await self.do(larvas.random.train(OVERLORD))
- async def build_hatchery(self):
- """this logic works for now, Ill have to change it when the expand_now()
- bug gets fixed"""
- try:
- if self.can_afford(HATCHERY) and base_amount < 7 \
- and not self.already_pending(HATCHERY):
- if base_amount <= 2:
- await self.expand_now()
- elif base_amount == 3 and roaches > 15:
- await self.expand_now()
- elif base_amount * 6.5 < roaches + hydra.amount:
- await self.expand_now()
- except AssertionError:
- print("damn it")
- async def build_spawning_pool(self):
- """good logic, no way to improve, final version"""
- if self.can_afford(SPAWNINGPOOL) and not sp.exists and base_amount == 2:
- await self.build(SPAWNINGPOOL, near=hatcherys.first.position.towards(self._game_info.map_center, 6))
- async def build_queens_inject_larva(self):
- """this logic works for now, even tho it works for now it will be ideal
- if the queens get created once for each hatchery so it doesnt have to
- travel for the injection"""
- queens = self.units(QUEEN)
- if base_exist:
- hatcherys_random = hatcherys.random
- if sp.ready.exists:
- if queens.amount < hatcherys.ready.amount and hatcherys_random.is_ready \
- and not self.already_pending(QUEEN) and hatcherys_random.noqueue and suplyl > 1:
- if self.can_afford(QUEEN) and not queens.closer_than(8, hatcherys_random):
- await self.do(hatcherys_random.train(QUEEN))
- for queen in queens.idle:
- selected = hatcherys.closest_to(queen.position)
- if queen.energy >= 25 and not selected.has_buff(QUEENSPAWNLARVATIMER):
- await self.do(queen(EFFECT_INJECTLARVA, selected))
- async def build_roach_warren(self):
- """good logic, no way to improve, final version"""
- if self.can_afford(ROACHWARREN) and not rw.exists \
- and not self.already_pending(ROACHWARREN) and sp.ready and base_amount == 3:
- await self.build(ROACHWARREN, near=sp.first)
- async def build_extrator(self):
- """logic can be improved, its over collecting gas, when the amount of
- bases raise, this will have to be changed even more"""
- gas = self.units(EXTRACTOR)
- gaisers = gas.amount
- if sp.exists:
- if hatcherys.ready.exists:
- vgs = self.state.vespene_geyser.closer_than(10, hatcherys.ready.random)
- for vg in vgs:
- drone = self.select_build_worker(vg.position)
- if drone is not None and self.can_afford(EXTRACTOR)\
- and await self.can_place(EXTRACTOR, vg.position):
- if gaisers < 9 and not self.already_pending(EXTRACTOR) \
- and base_amount >= 2 and self.can_afford(EXTRACTOR):
- if not gas.exists:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- elif gaisers == 1 and evochambers.ready.exists:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- elif gaisers <= 4 and rw.ready.exists and roach.ready.exists:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- elif roaches > gaisers * 1.75 and hatcherys.ready.amount >= gaisers / 2:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- async def build_evochamber(self):
- """this works for now, maybe will have to change the logic, since its
- way to greedy to make 2 evochambers before the third base, but for now
- the change is not needed"""
- if self.can_afford(EVOLUTIONCHAMBER) and rw.exists \
- and not self.already_pending(EVOLUTIONCHAMBER):
- if not evochambers.exists:
- await self.build(EVOLUTIONCHAMBER, near=rw.first)
- elif base_amount == 3 and evochambers.amount < 2:
- await self.build(EVOLUTIONCHAMBER, near=rw.first)
- async def build_roaches(self):
- """this works for now but can be improved a lot, the hydra-roach ratio
- needs observation and also needs to be smarter"""
- if roaches > 16:
- if hydraden.ready.exists:
- if self.flag1 and suplyl > 1 \
- and self.can_afford(ROACH) and larva_exist \
- and rw.ready.exists \
- and (hydra.amount * 2) - roaches > 0:
- await self.do(larvas.random.train(ROACH))
- elif suplyl > 1 and self.can_afford(ROACH) and larva_exist \
- and rw.ready.exists:
- await self.do(larvas.random.train(ROACH))
- async def armor_attack(self):
- """good logic for now all Ill have to do is add 3/ 3 when I focus on
- the late game later"""
- if evochambers.ready.idle.exists:
- for evo in evochambers.ready.idle:
- abilities = await abilitys(evo)
- abilities_list = [RESEARCH_ZERGMISSILEWEAPONSLEVEL1,
- RESEARCH_ZERGMISSILEWEAPONSLEVEL2,
- RESEARCH_ZERGGROUNDARMORLEVEL1,
- RESEARCH_ZERGGROUNDARMORLEVEL2]
- for ability in abilities_list:
- if ability in abilities:
- if self.can_afford(ability):
- err = await self.do(evo(ability))
- if not err:
- break
- async def rw_upgrades(self):
- if rw.ready.idle.exists and lair.exists and hatcherys.ready.amount >= 3:
- abilities = await abilitys(rw.first)
- abilities_list = [RESEARCH_TUNNELINGCLAWS, RESEARCH_GLIALREGENERATION]
- for ability in abilities_list:
- if ability in abilities:
- if self.can_afford(ability):
- err = await self.do(rw.first(ability))
- if not err:
- break
- async def defend_attack(self):
- """this is the logic the needs changes the most, its much better than
- before, but the units are sent in a line instead of being in a group,
- there is a fail in that too that prevents it from targeting buildings(
- unless its on sight), also its not smart at all it just a_moves and
- target the closest enemy, needs a lot of improvements, its the soul of
- the engine"""
- enemy_structures = self.known_enemy_structures
- hydra_roach = self.units.of_type([HYDRALISK, ROACH])
- filtered_enemies = enemy_units.exclude_type([ADEPTPHASESHIFT, DISRUPTORPHASED, EGG])
- if roaches > 14:
- for r in hydra_roach.prefer_idle:
- if r.health < 60 and BURROWDOWN_ROACH in await abilitys(roach)\
- and self.can_afford(BURROWDOWN_ROACH):
- await self.do(r(BURROWDOWN_ROACH))
- elif r.health > 120 and BURROWUP_ROACH in await abilitys(roach) \
- and self.can_afford(BURROWUP_ROACH):
- await self.do(r(BURROWUP_ROACH))
- else:
- if filtered_enemies.exists:
- if r.type_id == HYDRALISK:
- err = await self.do(r.attack(filtered_enemies.closest_to(r.position)))
- if not err:
- break
- else:
- target = filtered_enemies.not_flying
- if target.exists:
- err = await self.do(r.attack(target.closest_to(r.position)))
- if not err:
- break
- if enemy_structures.exists:
- err = await self.do(r.attack(enemy_structures.closest_to(r.position)))
- if not err:
- break
- elif r.position.distance_to(self.enemy_start_locations[0]) > 5:
- err = await self.do(r.attack(self.enemy_start_locations[0]))
- if not err:
- break
- elif roaches + hydra.amount > 4:
- for r in hydra_roach.prefer_idle:
- if filtered_enemies.exists:
- if r.type_id == HYDRALISK:
- err = await self.do(r.attack(filtered_enemies.closest_to(r.position)))
- if not err:
- break
- else:
- target = filtered_enemies.not_flying
- if target.exists:
- err = await self.do(r.attack(target.closest_to(r.position)))
- if not err:
- break
- async def upgrade_lair(self):
- """Good for now, but just like the evochambers, its way too greedy,
- maybe Ill have to change it but for now is good, carefull to not
- surpass the number of roaches of the first condition in the build
- roaches function"""
- if base.ready.exists and sp.ready.exists and self.can_afford(
- UPGRADETOLAIR_LAIR) and not self.flag1:
- self.flag1 = True
- await self.do(base.ready.idle.random(UPGRADETOLAIR_LAIR))
- async def build_hydraden(self):
- """This starts very late, maybe ill have to change it but its not
- priority, I want to build it smartly(like only build it vs flying
- focused army)"""
- if self.can_afford(HYDRALISKDEN) and not hydraden.exists \
- and not self.already_pending(HYDRALISKDEN) and rw.ready \
- and lair.exists:
- if roaches > 13:
- await self.build(HYDRALISKDEN, near=rw.first)
- async def build_hydras(self):
- """good enough for now, no need for more condition since the program
- already prioritizes roaches so I put the logic there, maybe later when
- I add more units Ill have to change this"""
- if suplyl > 1 and self.can_afford(HYDRALISK) and larva_exist \
- and hydraden.ready.exists:
- await self.do(larvas.random.train(HYDRALISK))
- async def defend_workerrush(self):
- """it always works vs worker rushes, but its way too abroad it attacks
- scouting workers, also the logic can be optimized, its super slow when
- its called"""
- if enemy_units.exists and base_exist:
- enemy_units_close = enemy_units.closer_than(5, hatcherys.first)
- if enemy_units_close.exists:
- workers = enemy_units_close.of_type([PROBE, DRONE, SCV])
- if workers.exists and base_amount < 2:
- self.flag2 = True
- for worker in self.workers:
- err = await self.do(worker.attack(enemy_units.closest_to(worker.position)))
- if not err:
- break
- else:
- self.flag2 = False
- '''
- async def defend_12pool(self):
- if self.seconds() < 210:
- my_zerglings = self.units(ZERGLING).idle
- zerglings = enemy_units.of_type([ZERGLING])
- if zerglings.amount > 4:
- for z in my_zerglings:
- if zerglings.exists and my_zerglings.amount > 8:
- await self.do(z.attack(zerglings.closest_to(z.position)))
- if sp.ready.exists:
- if self.can_afford(ZERGLING)and larva_exist:
- await self.do(larvas.random.train(ZERGLING))
- if self.can_afford(SPINECRAWLER):
- await self.build(SPINECRAWLER, near=sp.first)
- '''
- class WorkerRushBot(sc2.BotAI):
- async def on_step(self, iteration):
- if iteration == 0:
- for worker in self.workers:
- await self.do(worker.attack(self.enemy_start_locations[0]))
- run_game(maps.get("AbyssalReefLE"), [
- Bot(Race.Zerg, ZergRoachv3()),
- Computer(Race.Zerg, Difficulty.VeryHard)
- ], realtime=False)
- # CheatVision
Advertisement
Add Comment
Please, Sign In to add comment