Advertisement
Guest User

Untitled

a guest
Nov 14th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.38 KB | None | 0 0
  1. import pandas as pd
  2. import numpy as np
  3.  
  4. import sc2
  5. from sc2 import Race, Difficulty
  6. from sc2.constants import *
  7. from sc2.position import Point2, Point3
  8. from sc2.unit import Unit
  9. from sc2.player import Bot, Computer
  10. from sc2.player import Human
  11. from sc2.ids.unit_typeid import UnitTypeId
  12. from sc2.ids.ability_id import AbilityId
  13. from sc2.data import Race, ActionResult, Attribute, race_worker, race_townhalls, race_gas
  14. from sc2.game_info import GameInfo
  15. from typing import List, Dict, Set, Tuple, Any, Optional, Union
  16.  
  17.  
  18. class PrototypeAI(sc2.BotAI):
  19.     def __init__(self):
  20.         self.combinedActions = []
  21.         self.stage = None
  22.         print(self.stage)
  23.         self.terran_dataframe = pd.DataFrame()
  24.         self.set_early_game()
  25.         print(self.terran_dataframe)
  26.  
  27.  
  28.     async def on_step(self, iteration):
  29.         await self.do_actions(self.combinedActions)
  30.         self.combinedActions = []
  31.         await self.distribute_workers()
  32.         await self.train_scv()
  33.  
  34.     def set_early_game(self):
  35.         if self.stage == None:
  36.             self.stage = "early"
  37.  
  38.         terran_unit_list = ['scv']
  39.         rax_units = ['marine', 'maurader', 'reaper']
  40.         fac_units = ['hellion', 'hellbat', 'cyclone', 'tank', 'thor']
  41.         starport_units = ['liberator', 'viking', 'banshee', 'raven', 'battlecruiser']
  42.         terran_building_list = ['barracks', 'factory', 'starport', 'armory']
  43.  
  44.         def compile_list(name, *args):
  45.             merged_list = []
  46.             merged_list.extend(name)
  47.             for arg in args:
  48.                 merged_list.extend(arg)
  49.             return merged_list
  50.  
  51.         terran_list = compile_list(terran_unit_list, rax_units, fac_units, starport_units, terran_building_list)
  52.         def build_dict(unit_list):
  53.             blanks =[]
  54.             for n in range(len(unit_list)):
  55.                 blanks.append(0)
  56.             unitdict = dict((zip(unit_list, blanks)))
  57.             return unitdict
  58.         terran_dict = build_dict(terran_list)
  59.         def build_dataframe(dictval):
  60.             df = pd.DataFrame()
  61.             df['name'] = dictval.keys()
  62.             df['current'] = dictval.values()
  63.             df['killed'] = dictval.values()
  64.             df['current_max'] = dictval.values()
  65.             return df
  66.         self.terran_dataframe = build_dataframe(terran_dict)
  67.  
  68.  
  69.     async def train_scv(self):
  70.         #if self.stage == "early"
  71.         n = 0
  72.         for cc in self.units(COMMANDCENTER).ready.noqueue:
  73.             if self.units(SCV).amount < 17:
  74.                 if self.can_afford(SCV) and not self.already_pending(SCV):
  75.                     self.combinedActions.append(cc.train(SCV))
  76.                     n += 1
  77.                     self.terran_dataframe.set_value(0, 'current', n)
  78.                     print(self.terran_dataframe)
  79.                     #add tag to unit, put tagged units into a list, update dataframe based on # in list.
  80.  
  81.                    
  82.                     #self.scv_count += 1
  83.                     #print("Current Game Time", str(datetime.timedelta(seconds=round(self.time))))
  84.                     #print("Total SCVs built:    " + str(self.scv_count))
  85.  
  86.  
  87.     async def distribute_workers(self, performanceHeavy=True, onlySaturateGas=False):
  88.         # expansion_locations = self.expansion_locations
  89.         # owned_expansions = self.owned_expansions
  90.         if self.townhalls.exists:
  91.             for w in self.workers.idle:
  92.                 th = self.townhalls.closest_to(w)
  93.                 mfs = self.state.mineral_field.closer_than(10, th)
  94.                 if mfs:
  95.                     mf = mfs.closest_to(w)
  96.                     self.combinedActions.append(w.gather(mf))
  97.  
  98.         mineralTags = [x.tag for x in self.state.units.mineral_field]
  99.         # gasTags = [x.tag for x in self.state.units.vespene_geyser]
  100.         geyserTags = [x.tag for x in self.geysers]
  101.  
  102.         workerPool = self.units & []
  103.         workerPoolTags = set()
  104.  
  105.         # find all geysers that have surplus or deficit
  106.         deficitGeysers = {}
  107.         surplusGeysers = {}
  108.         for g in self.geysers.filter(lambda x:x.vespene_contents > 0):
  109.             # only loop over geysers that have still gas in them
  110.             deficit = g.ideal_harvesters - g.assigned_harvesters
  111.             if deficit > 0:
  112.                 deficitGeysers[g.tag] = {"unit": g, "deficit": deficit}
  113.             elif deficit < 0:
  114.                 surplusWorkers = self.workers.closer_than(10, g).filter(lambda w:w not in workerPoolTags and len(w.orders) == 1 and w.orders[0].ability.id in [AbilityId.HARVEST_GATHER] and w.orders[0].target in geyserTags)
  115.                 # workerPool.extend(surplusWorkers)
  116.                 for i in range(-deficit):
  117.                     if surplusWorkers.amount > 0:
  118.                         w = surplusWorkers.pop()
  119.                         workerPool.append(w)
  120.                         workerPoolTags.add(w.tag)
  121.                 surplusGeysers[g.tag] = {"unit": g, "deficit": deficit}
  122.  
  123.         # find all townhalls that have surplus or deficit
  124.         deficitTownhalls = {}
  125.         surplusTownhalls = {}
  126.         if not onlySaturateGas:
  127.             for th in self.townhalls:
  128.                 deficit = th.ideal_harvesters - th.assigned_harvesters
  129.                 if deficit > 0:
  130.                     deficitTownhalls[th.tag] = {"unit": th, "deficit": deficit}
  131.                 elif deficit < 0:
  132.                     surplusWorkers = self.workers.closer_than(10, th).filter(lambda w:w.tag not in workerPoolTags and len(w.orders) == 1 and w.orders[0].ability.id in [AbilityId.HARVEST_GATHER] and w.orders[0].target in mineralTags)
  133.                     # workerPool.extend(surplusWorkers)
  134.                     for i in range(-deficit):
  135.                         if surplusWorkers.amount > 0:
  136.                             w = surplusWorkers.pop()
  137.                             workerPool.append(w)
  138.                             workerPoolTags.add(w.tag)
  139.                     surplusTownhalls[th.tag] = {"unit": th, "deficit": deficit}
  140.  
  141.             if all([len(deficitGeysers) == 0, len(surplusGeysers) == 0, len(surplusTownhalls) == 0 or deficitTownhalls == 0]):
  142.                 # cancel early if there is nothing to balance
  143.                 return
  144.  
  145.         # check if deficit in gas less or equal than what we have in surplus, else grab some more workers from surplus bases
  146.         deficitGasCount = sum(gasInfo["deficit"] for gasTag, gasInfo in deficitGeysers.items() if gasInfo["deficit"] > 0)
  147.         surplusCount = sum(-gasInfo["deficit"] for gasTag, gasInfo in surplusGeysers.items() if gasInfo["deficit"] < 0)
  148.         surplusCount += sum(-thInfo["deficit"] for thTag, thInfo in surplusTownhalls.items() if thInfo["deficit"] < 0)
  149.  
  150.         if deficitGasCount - surplusCount > 0:
  151.             # grab workers near the gas who are mining minerals
  152.             for gTag, gInfo in deficitGeysers.items():
  153.                 if workerPool.amount >= deficitGasCount:
  154.                     break
  155.                 workersNearGas = self.workers.closer_than(10, gInfo["unit"]).filter(lambda w:w.tag not in workerPoolTags and len(w.orders) == 1 and w.orders[0].ability.id in [AbilityId.HARVEST_GATHER] and w.orders[0].target in mineralTags)
  156.                 while workersNearGas.amount > 0 and workerPool.amount < deficitGasCount:
  157.                     w = workersNearGas.pop()
  158.                     workerPool.append(w)
  159.                     workerPoolTags.add(w.tag)
  160.  
  161.         # now we should have enough workers in the pool to saturate all gases, and if there are workers left over, make them mine at townhalls that have mineral workers deficit
  162.         for gTag, gInfo in deficitGeysers.items():
  163.             if performanceHeavy:
  164.                 # sort furthest away to closest (as the pop() function will take the last element)
  165.                 workerPool.sort(key=lambda x:x.distance_to(gInfo["unit"]), reverse=True)
  166.             for i in range(gInfo["deficit"]):
  167.                 if workerPool.amount > 0:
  168.                     w = workerPool.pop()
  169.                     if len(w.orders) == 1 and w.orders[0].ability.id in [AbilityId.HARVEST_RETURN]:
  170.                         self.combinedActions.append(w.gather(gInfo["unit"], queue=True))
  171.                     else:
  172.                         self.combinedActions.append(w.gather(gInfo["unit"]))
  173.  
  174.         if not onlySaturateGas:
  175.             # if we now have left over workers, make them mine at bases with deficit in mineral workers
  176.             for thTag, thInfo in deficitTownhalls.items():
  177.                 if performanceHeavy:
  178.                     # sort furthest away to closest (as the pop() function will take the last element)
  179.                     workerPool.sort(key=lambda x:x.distance_to(thInfo["unit"]), reverse=True)
  180.                 for i in range(thInfo["deficit"]):
  181.                     if workerPool.amount > 0:
  182.                         w = workerPool.pop()
  183.                         mf = self.state.mineral_field.closer_than(10, thInfo["unit"]).closest_to(w)
  184.                         if len(w.orders) == 1 and w.orders[0].ability.id in [AbilityId.HARVEST_RETURN]:
  185.                             self.combinedActions.append(w.gather(mf, queue=True))
  186.                         else:
  187.                             self.combinedActions.append(w.gather(mf))
  188.  
  189.  
  190. def main():
  191.     sc2.run_game(sc2.maps.get("FractureLE"), [
  192.         Bot(Race.Terran, PrototypeAI()),
  193.         Computer(Race.Protoss, Difficulty.VeryEasy)
  194.     ], realtime=False)
  195.  
  196.  
  197. if __name__ == '__main__':
  198.     main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement