Matuiss2

Roach rush AI- v2 (22 - 2 against version 1)

Jul 27th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.96 KB | None | 0 0
  1. # todo for v2 release
  2. # todo fix the expansion bug(not on me)
  3. # todo zerg_rush defense
  4. # todo better attacking pattern (can be improved further)
  5. # todo improve hydra-roach ratio and hydras attack pattern
  6. # todo optimize worker rush defense() also need optimization
  7. # todo refactor
  8. # todo update comments
  9.  
  10.  
  11. class ZergRoachv2(sc2.BotAI):
  12.     def __init__(self):
  13.         self.flag1 = False  # It identifies if the upgrade 1 attack is started
  14.         self.flag2 = False  # It identifies if the upgrade 1 defense is started
  15.         self.flag3 = False  # It identifies if the upgrade 2 attack is started
  16.         self.flag4 = False  # It identifies if the upgrade 2 defense is started
  17.         self.flag5 = False  # It identifies if the upgrade 2 defense is started
  18.  
  19.     async def on_step(self, iteration):
  20.             await self.defend_workerrush()
  21.             # await self.defend_12pool()
  22.             await self.distribute_workers()
  23.             await self.build_workers()
  24.             await self.build_overlords()
  25.             await self.build_hatchery()
  26.             await self.build_spawning_pool()
  27.             await self.upgrade_lair()
  28.             await self.build_queens_inject_larva()
  29.             await self.build_roach_warren()
  30.             await self.build_extrator()
  31.             await self.build_evochamber()
  32.             await self.build_roaches()
  33.             await self.defend_attack()
  34.             await self.armor_attack()
  35.             await self.build_hydraden()
  36.             await self.build_hydras()
  37.  
  38.     def seconds(self):
  39.         return self.state.game_loop * 0.725 * (1 / 16)
  40.  
  41.     async def build_workers(self):
  42.         """ 18 works per base is fast enough and allows a continuos flow of units
  43.        after the first attack(Still needs better ratio after the 3rd base, it overgathers)"""
  44.         larvas = self.units(LARVA)
  45.         hatch_amount = self.townhalls.ready.amount
  46.         roaches = self.units(ROACH).amount
  47.         drones = self.units(DRONE).amount
  48.         if drones < 18.5 * hatch_amount \
  49.                 and self.can_afford(DRONE) and larvas.exists\
  50.                 and self.supply_left > 0 and drones < 66:
  51.             if hatch_amount == 3:
  52.                 if roaches > 7:
  53.                     await self.do(larvas.random.train(DRONE))
  54.             else:
  55.                 await self.do(larvas.random.train(DRONE))
  56.  
  57.     async def build_overlords(self):
  58.         """It makes overlords trying to avoid supply blocks, its good enough for now"""
  59.         larvas = self.units(LARVA)
  60.         hatch_amount = self.townhalls.ready.amount
  61.         if hatch_amount == 1:
  62.             if self.supply_left < 3 and self.can_afford(OVERLORD) and larvas.exists \
  63.                     and not self.already_pending(OVERLORD):
  64.                 await self.do(larvas.random.train(OVERLORD))
  65.         elif self.supply_left < 4 and self.can_afford(OVERLORD) and larvas.exists:
  66.                 await self.do(larvas.random.train(OVERLORD))
  67.  
  68.     async def build_hatchery(self):
  69.         """It makes bases trying to keep the attack going and making it stronger
  70.         everytime, its good enough for now"""
  71.         base_amount = self.townhalls.amount
  72.         if self.can_afford(HATCHERY) and base_amount < 2\
  73.                 and not self.already_pending(HATCHERY):
  74.             if base_amount == 1:
  75.                 await self.expand_now()
  76.             '''    
  77.            elif base_amount * 8.5 < self.units(ROACH).amount:
  78.                await self.expand_now()'''
  79.  
  80.     async def build_spawning_pool(self):
  81.         """It builds the spawning pool right after the second base is placed,
  82.         its good enough"""
  83.         hatcherys = self.townhalls
  84.         if self.can_afford(SPAWNINGPOOL) and not self.units(SPAWNINGPOOL).exists \
  85.                 and hatcherys.amount == 2:
  86.                     await self.build(SPAWNINGPOOL, near=hatcherys.first)
  87.  
  88.     async def build_queens_inject_larva(self):
  89.         """it build queen and make then use injection, a queen-hatchery ratio
  90.         can be implemented later, also the injection logic can be improved"""
  91.         sp = self.units(SPAWNINGPOOL)
  92.         hatcherys = self.townhalls.random
  93.         if sp.exists:
  94.             if self.units(QUEEN).amount < self.townhalls.amount and hatcherys.is_ready\
  95.                     and not self.already_pending(QUEEN) and hatcherys.noqueue\
  96.                     and sp.first.is_ready:
  97.                 if self.can_afford(QUEEN):
  98.                     await self.do(hatcherys.train(QUEEN))
  99.         for queen in self.units(QUEEN).idle:
  100.             if hatcherys.is_ready:
  101.                 if queen.energy >= 25 and queen.is_idle and not hatcherys.has_buff(QUEENSPAWNLARVATIMER):
  102.                     await self.do(queen(EFFECT_INJECTLARVA, hatcherys))
  103.  
  104.     async def build_roach_warren(self):
  105.         """It builds the roach warren right after the spawning pool is finished,
  106.        its good enough"""
  107.         sp = self.units(SPAWNINGPOOL)
  108.         if self.can_afford(ROACHWARREN)and not self.units(ROACHWARREN).exists\
  109.                 and not self.already_pending(ROACHWARREN) and sp.ready:
  110.             await self.build(ROACHWARREN, near=sp.first)
  111.  
  112.     async def build_extrator(self):
  113.         """it build extractors, the method can be improved a lot and the logic
  114.        for the 4th or more extractor can be improved too"""
  115.         gas = self.units(EXTRACTOR)
  116.         roaches = self.units(ROACH).amount
  117.         hatcheries = self.townhalls
  118.         vgs = self.state.vespene_geyser.closer_than(10, hatcheries.ready.random)
  119.         for vg in vgs:
  120.             drone = self.select_build_worker(vg.position)
  121.             if drone is not None and self.can_afford(EXTRACTOR) and await self.can_place(EXTRACTOR, vg.position):
  122.                 if gas.amount < 5 and not self.already_pending(EXTRACTOR) \
  123.                         and hatcheries.amount >= 2 and self.can_afford(EXTRACTOR):
  124.                     if not gas.exists:
  125.                         err = await self.do(drone.build(EXTRACTOR, vg))
  126.                         if not err:
  127.                             break
  128.                     elif gas.amount <= 2 and self.units(EVOLUTIONCHAMBER).ready.exists:
  129.                         err = await self.do(drone.build(EXTRACTOR, vg))
  130.                         if not err:
  131.                             break
  132.                         if not err:
  133.                             break
  134.                     elif gas.amount == 3 and roaches > 2:
  135.                         err = await self.do(drone.build(EXTRACTOR, vg))
  136.                         if not err:
  137.                             break
  138.                     elif gas.amount >= 4 and roaches > 12 and hatcheries.amount > 2:
  139.                         err = await self.do(drone.build(EXTRACTOR, vg))
  140.                         if not err:
  141.                             break
  142.  
  143.     async def build_evochamber(self):
  144.         """it builds the evochambers its good enough, but it might be too greedy
  145.         vs rushes"""
  146.         rw = self.units(ROACHWARREN)
  147.         if self.can_afford(EVOLUTIONCHAMBER)and rw.exists \
  148.                 and self.units(EVOLUTIONCHAMBER).amount < 2\
  149.                 and not self.already_pending(EVOLUTIONCHAMBER):
  150.             await self.build(EVOLUTIONCHAMBER, near=rw.first)
  151.  
  152.     async def build_roaches(self):
  153.         """it will build roaches when it can, its good enough for now but I might
  154.         need to change it when the hydras get implemented"""
  155.         larvas = self.units(LARVA)
  156.         if self.units(ROACH).amount > 10:
  157.             if self.units(LAIR).exists and self.supply_left > 1\
  158.                     and self.can_afford(ROACH) and larvas.exists\
  159.                     and self.units(ROACHWARREN).ready.exists:
  160.                 await self.do(larvas.random.train(ROACH))
  161.         elif self.supply_left > 1 and self.can_afford(ROACH) and larvas.exists\
  162.                 and self.units(ROACHWARREN).ready.exists:
  163.             await self.do(larvas.random.train(ROACH))
  164.  
  165.     async def defend_attack(self):
  166.         """its the logic for attacking, it works well when the first attack works,
  167.         but its bad when it fails or almost fails, needs to be improved drastically"""
  168.         roaches = self.units(ROACH)
  169.         hydras = self.units(HYDRALISK)
  170.         enemy_units = self.known_enemy_units.not_structure
  171.         enemy_structures = self.known_enemy_structures
  172.         if enemy_units.exists and roaches.amount > 2:
  173.             target = enemy_units.random
  174.             if not target.is_flying:
  175.                 for r in roaches.idle:
  176.                     await self.do(r.attack(target))
  177.         elif roaches.amount > 14:
  178.             for r in roaches.idle:
  179.                 if not enemy_structures.exists:
  180.                     await self.do(r.attack(self.enemy_start_locations[0]))
  181.                 elif enemy_units.exists:
  182.                     target = enemy_units.random
  183.                     if not target.is_flying:
  184.                         await self.do(r.attack(target))
  185.                 else:
  186.                     if roaches.amount + hydras.amount >= 19:
  187.                         await self.do(r.attack(enemy_structures.closest_to(r.position)))
  188.             if hydras.exists:
  189.                 for h in hydras.idle:
  190.                     if enemy_units.exists:
  191.                         target = enemy_units.random
  192.                         await self.do(h.attack(target))
  193.                     else:
  194.                         if roaches.amount + hydras.amount >= 19:
  195.                             await self.do(h.attack(enemy_structures.closest_to(h.position)))
  196.  
  197.     async def armor_attack(self):
  198.         """It makes the inicial upgrades, it works very well, maybe the logic can
  199.         be improved slightly but I dont see how yet"""
  200.         evochambers = self.units(EVOLUTIONCHAMBER)
  201.         if evochambers.ready.idle.exists:
  202.             for evo in evochambers.ready.idle:
  203.                 abilities = await self.get_available_abilities(evo)
  204.                 abilities_list = [RESEARCH_ZERGMISSILEWEAPONSLEVEL1,
  205.                                    RESEARCH_ZERGMISSILEWEAPONSLEVEL2,
  206.                                    RESEARCH_ZERGGROUNDARMORLEVEL1,
  207.                                    RESEARCH_ZERGGROUNDARMORLEVEL2]
  208.                 for ability in abilities_list:
  209.                     if ability in abilities:
  210.                         if self.can_afford(ability):
  211.                             err = await self.do(evo(ability))
  212.                             if not err:
  213.                                 break
  214.  
  215.     async def upgrade_lair(self):
  216.         hatchery = self.units(HATCHERY)
  217.         if self.units(SPAWNINGPOOL).ready.exists:
  218.             if not self.units(LAIR).exists and self.can_afford(LAIR)\
  219.                     and not self.already_pending(LAIR)\
  220.                     and hatchery.ready.idle.exists and not self.flag5:
  221.                 self.flag5 = True
  222.                 await self.do(hatchery.first.build(LAIR))
  223.  
  224.     async def build_hydraden(self):
  225.         rw = self.units(ROACHWARREN)
  226.         if self.can_afford(HYDRALISKDEN) and not self.units(HYDRALISKDEN).exists\
  227.                 and not self.already_pending(HYDRALISKDEN) and rw.ready\
  228.                 and self.units(LAIR).ready:
  229.             if self.units(ROACH).amount > 16:
  230.                 await self.build(HYDRALISKDEN, near=rw.first)
  231.  
  232.     async def build_hydras(self):
  233.         """it will build roaches when it can, its good enough for now but I might
  234.         need to change it when the hydras get implemented"""
  235.         larvas = self.units(LARVA)
  236.         if self.supply_left > 1 and self.can_afford(HYDRALISK) and larvas.exists\
  237.                 and self.units(HYDRALISKDEN).ready.exists and \
  238.                 self.units(ROACH).amount * 10 > self.units(HYDRALISK).amount:
  239.             await self.do(larvas.random.train(HYDRALISK))
  240.  
  241.     async def defend_workerrush(self):
  242.         enemy_units = self.known_enemy_units.not_structure
  243.         if enemy_units.exists:
  244.             enemy_units_close = enemy_units.closer_than(5, self.townhalls.first)
  245.             if enemy_units_close.exists:
  246.                 workers = enemy_units_close.of_type([PROBE, DRONE, SCV])
  247.                 if workers.exists and self.townhalls.amount < 2:
  248.                         for worker in self.workers:
  249.                             await self.do(worker.attack(enemy_units.closest_to(worker.position)))
  250.  
  251.     async def defend_12pool(self):
  252.         if self.seconds() < 210:
  253.             larvas = self.units(LARVA)
  254.             sp = self.units(SPAWNINGPOOL)
  255.             my_zerglings = self.units(ZERGLING).idle
  256.             zerglings = self.known_enemy_units.not_structure.of_type([ZERGLING])
  257.             if zerglings.amount > 4:
  258.                 for z in my_zerglings:
  259.                     if zerglings.exists and my_zerglings.amount > 8:
  260.                         await self.do(z.attack(zerglings.closest_to(z.position)))
  261.                 if sp.ready.exists:
  262.                     if self.can_afford(ZERGLING)and larvas.exists:
  263.                         await self.do(larvas.random.train(ZERGLING))
  264.                     if self.can_afford(SPINECRAWLER):
  265.                         await self.build(SPINECRAWLER, near=sp.first)
Add Comment
Please, Sign In to add comment