Matuiss2

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

Jul 27th, 2018
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 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)
Advertisement
Add Comment
Please, Sign In to add comment