Commits

David Jones committed c4bd05c

done with this for the night.

Comments (0)

Files changed (1)

   def score(self):
     """This is leftover from trying different scoring schemes"""
     return self.score_end_count()
-    # return self.score_exponential()
+  
+
   
   def get_my_on(self, idx, srcs=None):
+    """Find the number of ships I can land on idx"""
     return find_number_on_available(self.pw, self.my_available, idx, self.max_turn,
                                     srcs)
   def get_en_on(self, idx):
+    """Find the number of ships the enemy can land on idx"""    
     return find_number_on_available(self.pw, self.en_available, idx,
                                     self.max_turn, None)
                            
+  def find_neutrals(self, neutrals):
+    """
+    Find all the neutrals I can take.
 
-  def find_neutrals(self, neutrals):
+    This is called with a list of all the planets that are neutral at
+    the end of the simulation.
+    
+    Try to see if I can take it and earn back the ships before the
+    enemy can take it back.
+
+    The rest was hacked together, because I had a hard time with being
+    too aggressive or too passive.
+
+    Return a list of potential targets.
+    """
+    
     result = []
+
     for idx in neutrals:
       debug("looking at neutral: %d", idx)
       rate = self.pw.planets[idx].growth_rate
 
       
       self.log_planet_state(idx, False)
-      
-      # BUG HERE ... sometimes takes neutrals too early.
 
       for my_t in xrange(1,self.max_turn-1):
+        # never take on a turn that the enemy has a fleet landing.
         if fleets[2][my_t] > 0: continue
+
         if my_on[my_t] > future[my_t+1][2]:
+          # I can take it!
           needed = future[my_t+1][2]
-          num = needed + 1 # TODO:  account for sending more! my_on[my_t]
+          num = needed + 1 
           break
       else:
-        # cannot take.  pass
+        # cannot take ever, so skip.
         continue
 
+      # Check if the enemy can take it, without me reinforcing.
+      # Find the first turn it could happen.
       for en_t in xrange(my_t):
         if en_on[en_t] > 0:
+          # enemy can land ships before me.  so don't bother.
           en_t = -1000
           break
       else:
           if en_on[en_t] > (en_t - my_t) * rate + 1:
             break
 
+      # cost is confusing, but negative is good.
+      # -n means I have made n ships on the deal.
       cost = num + (my_t - en_t) * rate
 
+      # find the first turn I can take.  This is more useful
+      # in the enemy functions.
       first_turn = 0
       for t in xrange(self.max_turn):
         if fleets[2][t] > 0:
                        "rate": rate})
       else:
         # harder neutral.  time to think through this a little more.
+
         for earliest_enemy_landing in xrange(self.max_turn):
           if en_on[earliest_enemy_landing] > 0:
             break
 
-        # Maybe only look at things we can beat the enemy to by
-        # sum number of moves?
+
+        # only take if I am at least take_limit turns closer to the neutral
+        # than the enemy.  Now that I am typing this after the finals have started,
+        # I realize this is why I am losing some games.
         take_limit = 5
-
-        
-        delay =  max(int(ceil(1.0 * needed / rate)), 1)
-        # debug("delay is %d, needed %d, rate %d", delay, needed, rate)
         cost = 9e99
         for i in xrange(1, take_limit+1):
           if my_t + i >= self.max_turn:
             break
 
         else:
-          debug("hard neutral: my_t: %d, diff: %d, take_turn %d, delay: %d, rate:%d",
-                my_t, diff, my_t + i, delay, rate)
+          debug("hard neutral: my_t: %d, diff: %d, take_turn %d, rate:%d",
+                my_t, diff, my_t + i, rate)
 
           result.append({"planet": idx,
                          "first_turn": my_t,
           debug(result[-1])
     return result
 
-  def find_defend_at_last_moment(self, mine):
-    result = []
-    if not mine:
-      return result
-
-    for idx in mine:
-      t = self.run_defend(idx)
-      if t:  result.append(t)
-    return result
-
 
   def find_enemies(self, enemies, offset=0,all_in=True):
+    """
+    Calculate attacking planets that will be owned
+    by the enemy unless I do something about it.
+
+    
+    """
     result = []
     if not enemies:
       return []
+
+
+
+    # if not all_in,  limit firing planets to the planets
+    # closest to the enemy.  There is a magic number down here too...
+
+
+    # dict of src planets for each enemy.
     srcs = dict([(en, None) for en in enemies])
-    
+
     if not all_in:
       mine = [p for p in self.pidx
               if self.futures[p][-1][1] == 1 or
       debug("mine: %s", mine)
       debug("enemies: %s", enemies)
 
+      # doh.  This would be easier with the neighbors list.
       tmp = [(m,find_closest(self.pw, m, enemies)) for m in mine]
       tmp = [(m, d) for (m, (junk,d)) in tmp]
       closest = dict(tmp)
       debug("closest: %s", closest)
+
       for idx in enemies:
+        # only fire from the closest of my planets, plus any other
+        # ones within a small radius.  This was an attempt
+        # to prevent cross screen shots.
         srcs[idx] = [m for m in mine
                      if self.pw.planets[m].dists[idx] < closest[m] + 5]
       
     for idx in enemies:
+      # Try to calculate for each enemy, accumulate the results.
       t = self.run_enemy(idx,offset,srcs[idx])
       if t:
         result.append(t)
     
 
   def run_enemy(self, idx, offset, srcs):
+    """
+    Calculate if an enemy planet is a possible target, and
+    if so, how many to send.
+
+    Offset is the number of turns I get to move before the enemy.  This
+    used to be useful.  Basically, 0 considers that the enemy launches
+    a defense the same turn I attack.  1 means that they don't defend
+    until the next turn.
+    """
     debug("looking at enemy: %d", idx)
     rate = self.pw.planets[idx].growth_rate
     fleets = self.fleets[idx]
     for turn in xrange(1, self.max_turn-1):
       # don't consider when the enemy doesn't own it.
       if future[turn+1][1] != 2: continue
+      if turn < offset: continue
 
-      # assume they delay a turn to fire.
-      # we will deal with possible launches later.
+      # need as many ships as the enemy could land here on turn - offset
+      needed = en_on[turn - offset]
 
-      if turn < offset: continue
-      # if offset > -1:
-      needed = en_on[turn - offset]
-      # else:
-      #   needed = 0
-          
+      
       fut = future[turn+1]
       if fut[1] == 2:
+        # Enemy owns, so need to add the number of ships + 1
         needed += fut[2] + 1
       else:
+        # this should never happen I guess...
         needed -= fut[2]
 
       if needed <= 0:
         continue
 
+      # If I cannot take, keep looping.
       if my_on[turn] < needed: continue
-      
+
+      # If I can take, figure out how quickly I could take it.
       dist = turn
       while my_on[dist-1] >= needed:
         dist -= 1
 
-
-        
       if my_on[dist] >= needed:
+        # This is one of the things that worked well.
+        # If I already own the planet, go ahead and send now.
+        # If not, delay firing until the last second.  This
+        # helps because I can avoid sending more than needed,.
+                
         # find the first turn to strike
-        first_turn = turn
         # First turn is
         #  - never when the planet is neutral
         #  - the first time I own it
         #  - else when I can take it.
+
+        first_turn = turn        
         for first_turn in xrange(1, turn):
           if future[first_turn][1] == 1:
             break
     return None
 
   def fire(self, target):
+    """
+    Calculate the shots needed to attack target.
+
+    Target includes some information needed here:
+       - turn is the turn we want to land by
+       - first_turn is the first turn it is ok to land.
+
+    Loop through all the the planets from closest to farthest,
+    and make orders to launch from each planet on each turn
+    until the number needed has been launched.  Mark
+    launched ships off from the available list.
+    """
+       
     debug("trying to attack: %s", target)
+
     
     dists = [(d,p) for (d,p) in self.pw.planets[target["planet"]].neighbors
              if self.my_available[p]]
       for (d, p) in dists:
         debug("planet: %d, distance: %d, av: %s", p, d, self.my_available[p])
 
-
         
     num = target["num"]
     first_turn = target["first_turn"]