Advertisement
Guest User

Galconfusion Clone AI

a guest
Apr 23rd, 2012
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.02 KB | None | 0 0
  1. ''' Simple "Blank" PlanetWars controller bot.
  2.  
  3. The Bot does nothing, but shows the minimum a bot needs to have.
  4.  
  5. See the `update` method which is where your code goes.
  6.  
  7. The `PlanetWars` `Player` object (see players.py), will contain your bot
  8. controller instance. The Player will provide a current `GameInfo` instance
  9. to your bot `update` method each time it is called.
  10.  
  11. The `gameinfo` instance is a facade of the state of the game for the `Player`,
  12. and includes all planets and fleets that currently exist. Note that the
  13. details are limited by "fog of war" visions and only match what you can see.
  14.  
  15. A gameinfo instance has various (possibly useful) dict's for you to use:
  16.  
  17.    # all planet and fleets (that you own or can see)
  18.    planets
  19.    fleets
  20.  
  21.    # dict's of just your planets/fleets
  22.    my_planets
  23.    my_fleets
  24.  
  25.    # dict's of both neutral and enemy planets/fleets
  26.    not_my_planets
  27.    not_my_fleets
  28.  
  29.    # dict's of just the enemy planet/fleets (fog limited)
  30.    enemy_planets
  31.    enemy_fleets
  32.  
  33. You issue orders from your bot using the methods of the gameinfo instance.
  34.  
  35.    gameinfo.planet_order(src, dest, ships)
  36.    gameinfo.fleet_order(src, dest, ships)
  37.  
  38. For example, to send 10 ships from planet src to planet dest, you would
  39. say `gameinfo.planet_order(src, dest, 10)`.
  40.  
  41. There is also a player specific log if you want to leave a message
  42.  
  43.    gameinfo.log("Here's a message from the bot")
  44.  
  45. '''
  46.  
  47. from random import choice
  48.  
  49. SPY_TIME = 10
  50.  
  51. class Tactics():
  52.    
  53.     #dest = None
  54.     #src = None
  55.     #numShips = 0
  56.     #gameinfo.planetOrder(src, dest, numShips)
  57.     #gameinfo.fleetOrder(src, dest, numShips)
  58.    
  59.     def Fortify(self, details, gameinfo, estimate):
  60.         pass
  61.    
  62.     def Attack(self, details, gameinfo, estimate):
  63.         pass
  64.    
  65.     def Scout(self, details, gameinfo, estimate):
  66.         gameinfo.planet_order(choice(gameinfo.my_planets), details, 1)
  67.    
  68.     TACTICS = {"Fortify" : Fortify, "Attack" : Attack, "Scout": Scout}
  69.  
  70. class ArtOfWar(object):
  71.     def __init__(self):
  72.         self._last_gameinfo = None
  73.         self._estimate = Estimator()
  74.         self._calculator = Calculator()
  75.         self._currentTactics = [] #Tuple of Sets e.g. [("Fortify": PlanetX), ("Colonize": PlanetY)])
  76.    
  77.     def update(self, gameinfo):
  78.         """Plan:
  79.        1. Measurement of visible data (automatic)
  80.        2. Estimation of data outside the scope (using class Estimate update method)
  81.        3. Calculation of possible tactics (using AoW Heuristics)
  82.        4. Comparison of possible tactics
  83.        5. Utilization of tactics for victory """
  84.         self._last_gameinfo = gameinfo
  85.        
  86.         self._estimation()
  87.        
  88.         new_tactics = self._calculation()
  89.        
  90.         self._compare(new_tactics)
  91.        
  92.         for tactic in self._currentTactics:
  93.             self._act(tactic)
  94.             self._currentTactics.remove(tactic)
  95.            
  96.         self._cleanup()
  97.        
  98.     def _estimation(self):
  99.         """Plan:
  100.        Estimate opponents current forces
  101.        Estimate what the opponent currently knows"""
  102.        
  103.         self._estimate.update(self._last_gameinfo)
  104.        
  105.        
  106.     def _calculation(self):
  107.         """Plan:
  108.        Calculate what tactics are viable from the current information known"""
  109.        
  110.         return self._calculator.update(self._estimate, self._last_gameinfo)
  111.    
  112.     def _compare(self, new_tactics):
  113.         """Plan:
  114.        Compare a variety of tactics to determine the most necessary or likely to work
  115.        Check if any _currentTactics are "holding tactics" that require a change into their active state
  116.        adds the chosen tactics to _currentTactics"""
  117.        
  118.         #Remove this from Compare, add to Estimate.Initialize
  119.         temp_scouting = [] #starts as tuple for adding data
  120.        
  121.         for tactic in new_tactics:
  122.             if tactic[0] == "Scout":
  123.                 for old_tactic in self._currentTactics:
  124.                     #If not already being scouted
  125.                     if (old_tactic[0] == "Scouting") and (old_tactic[1] == tactic[1]):
  126.                         pass
  127.                     else:
  128.                         temp_scouting.append(tactic[1])
  129.                
  130.         scouting = set(temp_scouting) #convert to set for no duplicate elements for later testing
  131.        
  132.         scout_data = {} #dict of {Planet to be scouted: (Set of planets it can see)}
  133.         for i in scouting:
  134.             scout_data[i] = [] #default can't see any other planets
  135.             for j in scouting:
  136.                 if j in self._estimate.planets_see[i]:
  137.                     scout_data[i].append(j)
  138.                    
  139.         #Formula that determines the minimum number of planets to be scouted to see all of them
  140.         removal = []
  141.         for p in scouting:
  142.             temp_scouting.remove(p)
  143.             temp_scout_can_see = []
  144.             for i in temp_scouting:
  145.                 for j in temp_scouting:
  146.                     if j in self._estimate.planets_see[i]:
  147.                         temp_scout_can_see.append(j)
  148.             for ptest in scouting:
  149.                 if ptest not in temp_scout_can_see:
  150.                     temp_scouting.append(p)
  151.             if p not in temp_scouting:
  152.                 removal.append(p)
  153.        
  154.         for p in removal:
  155.             for tactic in new_tactics:
  156.                 if (tactic[0] == "Scout") and (tactic[1] == p):
  157.                     new_tactics.remove(p)
  158.                    
  159.        
  160.         self._currentTactics.append(new_tactics)
  161.        
  162.     def _act(self, tactic):
  163.         """Plan:
  164.        Act out the given tactic
  165.        If necessary adds a "holding tactic" pending a future condition
  166.        May also use gameinfo.log to post messages to the screen"""
  167.        
  168.         if tactic[0] in Tactics.TACTICS.keys():
  169.             func = Tactics.TACTICS[tactic]
  170.             func(tactic[1], self._last_gameinfo, self._estimate)
  171.            
  172.         if tactic[0] == "Scout":
  173.             self._currentTactics.append(("Scouting", tactic[1]))
  174.            
  175.     def _cleanup(self):
  176.         for tactic in self._currentTactics:
  177.             if tactic[0] == "Scouting":
  178.                 if self._estimate.planet_info[tactic[1]]["Data Age"] < SPY_TIME:
  179.                     self._currentTactics.remove(tactic)
  180.      
  181. class Calculator():
  182.     def __init__(self):
  183.         self.must_hasten = () #planets, enemy must hasten, rescue, etc. >Appear here
  184.         self.undefended = () #planets, >Attack here
  185.        
  186.     def update(self, estimate, gameinfo):
  187.         """update information first
  188.        then make broad assumptions
  189.        return a dict of possible tactics"""
  190.        
  191.         new_tactics = [("Blank", "Filler")]
  192.        
  193.         #for fleet in self.fleets:
  194.             #if there is no gain RTB
  195.            
  196.         for p in estimate.planet_info:
  197.             if estimate.planet_info[p]["Data Age"] > SPY_TIME:
  198.                 new_tactics.append(("Scout", p))            
  199.         return new_tactics
  200.        
  201. class Estimator():
  202.     def __init__(self):
  203.         self.planet_info = {} #{planet: (time since last info, last info)}
  204.        
  205.         self.hidden_planets = {} #{planet: (time since enemy last saw, what enemy last saw)}
  206.         #not sure if possible
  207.        
  208.         self.planet_distances = {} #{planet: {planet: distance}}
  209.         self.planets_see = {}
  210.        
  211.         self.terrain = {} #{planet: Terrain}
  212.         #Accessible, Entangling, Deadlock, Enclosed, Precipitous, Distant
  213.        
  214.         self.ground = {} #{planet: Ground}
  215.         #Scattering, Light, Strategic, Open, Crossroad, Heavy, Intractable, Enclosed, Death
  216.        
  217.         self.initialized = False
  218.        
  219.     def update(self, gameinfo):
  220.         if self.initialized == False:
  221.             self._initialize(gameinfo)
  222.            
  223.         for p in gameinfo.not_my_planets:
  224.             if p not in gameinfo.enemy_planets:
  225.                 if p in self.planet_info:
  226.                     self.planet_info[p]["Data Age"] += 1
  227.             else:
  228.                 self.planet_info[p]["Ships"] = gameinfo.enemy_planets[p].num_ships
  229.                 self.planet_info[p]["Data Age"] = 0
  230.                    
  231.     def _initialize(self, gameinfo):
  232.         self.initialized = True
  233.         for p in gameinfo.not_my_planets:
  234.             self.planet_info[p] = {"Ships" : gameinfo.not_my_planets[p].num_ships, "Data Age" : 0}
  235.            
  236.         for p in gameinfo.planets:
  237.             planet = gameinfo.planets[p]
  238.             self.planet_distances[planet] = {}
  239.             self.planets_see[planet] = []
  240.             for q in gameinfo.planets:
  241.                 qlanet = gameinfo.planets[q]
  242.                 self.planet_distances[planet][qlanet] = planet.distance_to(qlanet)
  243.                 if self.planet_distances[planet][qlanet] < planet.vision_range():
  244.                     self.planets_see[planet].append(qlanet)
  245.                    
  246.         #YELL AT CLINTON FOR PASSING GAMEINFO.PLANETS AS A FUCKING GODDAWFUL DICTIONARY
  247.         #I MEAN, SERIOUSLY, IS THIS FUCKING 1989 USING C
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement