Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # todo for v2 release
- # todo fix the expansion bug(not on me)
- # todo zerg_rush defense
- # todo better attacking pattern (can be improved further)
- # todo improve hydra-roach ratio and hydras attack pattern
- # todo optimize worker rush defense() also need optimization
- # todo refactor
- # todo update comments
- class ZergRoachv2(sc2.BotAI):
- def __init__(self):
- self.flag1 = False # It identifies if the upgrade 1 attack is started
- self.flag2 = False # It identifies if the upgrade 1 defense is started
- self.flag3 = False # It identifies if the upgrade 2 attack is started
- self.flag4 = False # It identifies if the upgrade 2 defense is started
- self.flag5 = False # It identifies if the upgrade 2 defense is started
- async def on_step(self, iteration):
- await self.defend_workerrush()
- # await self.defend_12pool()
- 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()
- def seconds(self):
- return self.state.game_loop * 0.725 * (1 / 16)
- async def build_workers(self):
- """ 18 works per base is fast enough and allows a continuos flow of units
- after the first attack(Still needs better ratio after the 3rd base, it overgathers)"""
- larvas = self.units(LARVA)
- hatch_amount = self.townhalls.ready.amount
- roaches = self.units(ROACH).amount
- drones = self.units(DRONE).amount
- if drones < 18.5 * hatch_amount \
- and self.can_afford(DRONE) and larvas.exists\
- and self.supply_left > 0 and drones < 66:
- if hatch_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):
- """It makes overlords trying to avoid supply blocks, its good enough for now"""
- larvas = self.units(LARVA)
- hatch_amount = self.townhalls.ready.amount
- if hatch_amount == 1:
- if self.supply_left < 3 and self.can_afford(OVERLORD) and larvas.exists \
- and not self.already_pending(OVERLORD):
- await self.do(larvas.random.train(OVERLORD))
- elif self.supply_left < 4 and self.can_afford(OVERLORD) and larvas.exists:
- await self.do(larvas.random.train(OVERLORD))
- async def build_hatchery(self):
- """It makes bases trying to keep the attack going and making it stronger
- everytime, its good enough for now"""
- base_amount = self.townhalls.amount
- if self.can_afford(HATCHERY) and base_amount < 2\
- and not self.already_pending(HATCHERY):
- if base_amount == 1:
- await self.expand_now()
- '''
- elif base_amount * 8.5 < self.units(ROACH).amount:
- await self.expand_now()'''
- async def build_spawning_pool(self):
- """It builds the spawning pool right after the second base is placed,
- its good enough"""
- hatcherys = self.townhalls
- if self.can_afford(SPAWNINGPOOL) and not self.units(SPAWNINGPOOL).exists \
- and hatcherys.amount == 2:
- await self.build(SPAWNINGPOOL, near=hatcherys.first)
- async def build_queens_inject_larva(self):
- """it build queen and make then use injection, a queen-hatchery ratio
- can be implemented later, also the injection logic can be improved"""
- sp = self.units(SPAWNINGPOOL)
- hatcherys = self.townhalls.random
- if sp.exists:
- if self.units(QUEEN).amount < self.townhalls.amount and hatcherys.is_ready\
- and not self.already_pending(QUEEN) and hatcherys.noqueue\
- and sp.first.is_ready:
- if self.can_afford(QUEEN):
- await self.do(hatcherys.train(QUEEN))
- for queen in self.units(QUEEN).idle:
- if hatcherys.is_ready:
- if queen.energy >= 25 and queen.is_idle and not hatcherys.has_buff(QUEENSPAWNLARVATIMER):
- await self.do(queen(EFFECT_INJECTLARVA, hatcherys))
- async def build_roach_warren(self):
- """It builds the roach warren right after the spawning pool is finished,
- its good enough"""
- sp = self.units(SPAWNINGPOOL)
- if self.can_afford(ROACHWARREN)and not self.units(ROACHWARREN).exists\
- and not self.already_pending(ROACHWARREN) and sp.ready:
- await self.build(ROACHWARREN, near=sp.first)
- async def build_extrator(self):
- """it build extractors, the method can be improved a lot and the logic
- for the 4th or more extractor can be improved too"""
- gas = self.units(EXTRACTOR)
- roaches = self.units(ROACH).amount
- hatcheries = self.townhalls
- vgs = self.state.vespene_geyser.closer_than(10, hatcheries.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 gas.amount < 5 and not self.already_pending(EXTRACTOR) \
- and hatcheries.amount >= 2 and self.can_afford(EXTRACTOR):
- if not gas.exists:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- elif gas.amount <= 2 and self.units(EVOLUTIONCHAMBER).ready.exists:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- if not err:
- break
- elif gas.amount == 3 and roaches > 2:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- elif gas.amount >= 4 and roaches > 12 and hatcheries.amount > 2:
- err = await self.do(drone.build(EXTRACTOR, vg))
- if not err:
- break
- async def build_evochamber(self):
- """it builds the evochambers its good enough, but it might be too greedy
- vs rushes"""
- rw = self.units(ROACHWARREN)
- if self.can_afford(EVOLUTIONCHAMBER)and rw.exists \
- and self.units(EVOLUTIONCHAMBER).amount < 2\
- and not self.already_pending(EVOLUTIONCHAMBER):
- await self.build(EVOLUTIONCHAMBER, near=rw.first)
- async def build_roaches(self):
- """it will build roaches when it can, its good enough for now but I might
- need to change it when the hydras get implemented"""
- larvas = self.units(LARVA)
- if self.units(ROACH).amount > 10:
- if self.units(LAIR).exists and self.supply_left > 1\
- and self.can_afford(ROACH) and larvas.exists\
- and self.units(ROACHWARREN).ready.exists:
- await self.do(larvas.random.train(ROACH))
- elif self.supply_left > 1 and self.can_afford(ROACH) and larvas.exists\
- and self.units(ROACHWARREN).ready.exists:
- await self.do(larvas.random.train(ROACH))
- async def defend_attack(self):
- """its the logic for attacking, it works well when the first attack works,
- but its bad when it fails or almost fails, needs to be improved drastically"""
- roaches = self.units(ROACH)
- hydras = self.units(HYDRALISK)
- enemy_units = self.known_enemy_units.not_structure
- enemy_structures = self.known_enemy_structures
- if enemy_units.exists and roaches.amount > 2:
- target = enemy_units.random
- if not target.is_flying:
- for r in roaches.idle:
- await self.do(r.attack(target))
- elif roaches.amount > 14:
- for r in roaches.idle:
- if not enemy_structures.exists:
- await self.do(r.attack(self.enemy_start_locations[0]))
- elif enemy_units.exists:
- target = enemy_units.random
- if not target.is_flying:
- await self.do(r.attack(target))
- else:
- if roaches.amount + hydras.amount >= 19:
- await self.do(r.attack(enemy_structures.closest_to(r.position)))
- if hydras.exists:
- for h in hydras.idle:
- if enemy_units.exists:
- target = enemy_units.random
- await self.do(h.attack(target))
- else:
- if roaches.amount + hydras.amount >= 19:
- await self.do(h.attack(enemy_structures.closest_to(h.position)))
- async def armor_attack(self):
- """It makes the inicial upgrades, it works very well, maybe the logic can
- be improved slightly but I dont see how yet"""
- evochambers = self.units(EVOLUTIONCHAMBER)
- if evochambers.ready.idle.exists:
- for evo in evochambers.ready.idle:
- abilities = await self.get_available_abilities(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 upgrade_lair(self):
- hatchery = self.units(HATCHERY)
- if self.units(SPAWNINGPOOL).ready.exists:
- if not self.units(LAIR).exists and self.can_afford(LAIR)\
- and not self.already_pending(LAIR)\
- and hatchery.ready.idle.exists and not self.flag5:
- self.flag5 = True
- await self.do(hatchery.first.build(LAIR))
- async def build_hydraden(self):
- rw = self.units(ROACHWARREN)
- if self.can_afford(HYDRALISKDEN) and not self.units(HYDRALISKDEN).exists\
- and not self.already_pending(HYDRALISKDEN) and rw.ready\
- and self.units(LAIR).ready:
- if self.units(ROACH).amount > 16:
- await self.build(HYDRALISKDEN, near=rw.first)
- async def build_hydras(self):
- """it will build roaches when it can, its good enough for now but I might
- need to change it when the hydras get implemented"""
- larvas = self.units(LARVA)
- if self.supply_left > 1 and self.can_afford(HYDRALISK) and larvas.exists\
- and self.units(HYDRALISKDEN).ready.exists and \
- self.units(ROACH).amount * 10 > self.units(HYDRALISK).amount:
- await self.do(larvas.random.train(HYDRALISK))
- async def defend_workerrush(self):
- enemy_units = self.known_enemy_units.not_structure
- if enemy_units.exists:
- enemy_units_close = enemy_units.closer_than(5, self.townhalls.first)
- if enemy_units_close.exists:
- workers = enemy_units_close.of_type([PROBE, DRONE, SCV])
- if workers.exists and self.townhalls.amount < 2:
- for worker in self.workers:
- await self.do(worker.attack(enemy_units.closest_to(worker.position)))
- async def defend_12pool(self):
- if self.seconds() < 210:
- larvas = self.units(LARVA)
- sp = self.units(SPAWNINGPOOL)
- my_zerglings = self.units(ZERGLING).idle
- zerglings = self.known_enemy_units.not_structure.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 larvas.exists:
- await self.do(larvas.random.train(ZERGLING))
- if self.can_afford(SPINECRAWLER):
- await self.build(SPINECRAWLER, near=sp.first)
Add Comment
Please, Sign In to add comment