Exemple #1
0
def DoTurn(pw):
  try:
    # (1) If we currently have a fleet in flight, just do nothing.
    if len(pw.MyFleets()) >= 3:
      log.debug('Returning since more than 2 fleets are out')
      return
    # (2) Find my strongest planet.
    source = -1
    source_score = -999999.0
    source_num_ships = 0
    my_planets = pw.MyPlanets()
    for p in my_planets:
      score = float(p.NumShips())
      if score > source_score:
        source_score = score
        source = p.PlanetID()
        source_num_ships = p.NumShips()
  
    # (3) Find the weakest enemy or neutral planet.
    dest = -1
    dest_score = -999999.0
    not_my_planets = pw.NotMyPlanets()
    for p in not_my_planets:
      score = 1.0 / (1 + p.NumShips())
      if score > dest_score:
        dest_score = score
        dest = p.PlanetID()
  
    # (4) Send half the ships from my strongest planet to the weakest
    # planet that I do not own.
    if source >= 0 and dest >= 0:
      num_ships = source_num_ships / 2
      pw.IssueOrder(source, dest, num_ships)
  except Exception, e:
    log.error(str(e))
Exemple #2
0
def main():
  map_data = ''
  while(True):
    current_line = raw_input()
    if len(current_line) >= 2 and current_line.startswith("go"):
      log.startTurn()
      pw = PlanetWars(map_data)
      DoTurn5(pw)
      pw.FinishTurn()
      map_data = ''
      log.debug('finished turn')
    else:
      map_data += current_line + '\n'
Exemple #3
0
def getBestOrders1(gains, availableShips):
  #gains: dict, key = planetId, list of (ships required, gain, other planetID())
  #available ships: dict, key = planetId, int of available ships for attacking
  orders = [] #list of (source planetId, destinationPlanetId, number of attackers)
  
  for planet in availableShips:
    log.debug('planet: ' + str(planet) + '   available ships: ' + str(availableShips[planet]))
    log.debug('gains: \n' + '\n'.join([str(x) for x in gains[planet]]))
    
    if availableShips[planet] == 0:
      continue
    # should probably do some recursive optimization crazyness here...
    if gains[planet][0][0] < availableShips[planet]:
      orders.append((planet, gains[planet][0][2], gains[planet][0][0]))
      
  return orders
Exemple #4
0
def DoTurn3(pw):
  global turn_number
  turn_number += 1
  try:
    #if turn_number == 1:
      #if FirstTurn.doFirstTurn(pw):
      #  return
    
    #for each of my planets
      #for each of the other planets
      
        #find the total number of fleets when we could get there from our planet, then determine the best planet to attack
    
    orders = []
    allGains = {}
    availableShips = {}
    
    for my_planet in pw.MyPlanets():
      
      availableShips[my_planet.PlanetID()] = max(0, my_planet.NumShips() - extra_ships)
      
      gains = []
      for other_planet in pw.Planets():
        if other_planet.GrowthRate() == 0: # not worth taking over
          continue
        if my_planet.PlanetID() == other_planet.PlanetID(): #same planet
          continue
        
        shipsAtArriveTime, time = pw.GetShipsAtArriveTime(my_planet.PlanetID(), other_planet.PlanetID())
        if shipsAtArriveTime[1] == 1:
          # we will have control of that planet, don't bother with it
          pass
        else:
          # should we try to take over?
          gain = 0 if time >= turns_ahead else (turns_ahead - time) * other_planet.GrowthRate() * (1 if shipsAtArriveTime == 0 else 2)
          
          gains.append((shipsAtArriveTime[0] + extra_ships, gain, other_planet.PlanetID()))
      
      allGains[my_planet.PlanetID()] = sorted(gains)
    
    log.debug('got all gains')
    
    orders = getBestOrders2(allGains, availableShips, pw)
    log.debug('got orders from getBestOrders1(): \n' + '\n'.join([str(x) for x in orders]))
    
    log.debug('Starting to issue all orders')
    for order in orders:
      try:
        pw.IssueOrder(order[0], order[1], order[2])
      except Exception, e:
        log.exc(e)
    log.debug('done issueing orders')
Exemple #5
0
def addStreamOrders(orders, stayHomeGain, pw):
  new_orders = []
  for my_planet in pw.MyPlanets():
    totalOrdersSent = sum([order[2] for order in orders if order[0] == my_planet.PlanetID()])
    available = stayHomeGain[my_planet.PlanetID()]
    
    bestGainStaying = -1
    for ships in available:
      if available[ships] > bestGainStaying:
        bestGainStaying = available[ships]
        shipsLeft = my_planet.NumShips() - totalOrdersSent - ships
    
    log.debug('for planet : ' + str(my_planet))
    log.debug('total orders sent: ' + str(totalOrdersSent))
    log.debug('ships left: ' + str(shipsLeft))
    log.debug('availableShips: ' + str(available))
    
    if availableShips > 0:
      log.debug('find a potential planet to send to')
      
  return new_orders
Exemple #6
0
def getPlanetsToGoToFirst(planetTuples, availableShips):
  """
  takes a list of the physically closest planets to the home
  returns a list of planets that should immediately be attacked
  """
  
  planetTuples.sort(cmp = fleetSizeSort)
  
  #sorted with the largets fleet first, recursively keep adding fleets until you run out of space
  #if it gets the most growth, keep track of it
  
  #log.debug('planets sorted by fleet size: \n' + '\n'.join([str(x) for x in planetTuples]))
  
  log.debug('before recursiveIndexFinder()')
  best = recursiveIndexFinder(planetTuples, [], availableShips)
  #planetsToAttack = 
  
  log.debug('best planets to go to first: ' + str(best))
  
  result = [] # list of planet, number of ships
  for index in best[0]:
    result.append((planetTuples[index][3], planetTuples[index][0]))
  
  return result
Exemple #7
0
def PlanetWorthinessToTakeOver(myPlanet, otherPlanet, minFleetSize, distance):
  try:
    enemyLoss = int(otherPlanet.Owner() == 2) * otherPlanet.GrowthRate()
    growthRate = otherPlanet.GrowthRate()
    
    log.debug('enemy loss: ' + str(enemyLoss))
    log.debug('growth rate: ' + str(growthRate))
    log.debug('min fleet size: ' + str(minFleetSize))
    
    result = 1.0 * (growthRate + enemyLoss) / (minFleetSize * ( 1.0 + distance)**2.0)
    
    log.debug('result of planet worthiness: ' + str(result))
    
    return result
  except Exception, e:
    log.exc(e)
    log.error('due to error, PlanetWorthinessToTakeOver() will return 0')
    return 0.0
Exemple #8
0
def getBestOrders3(allGains, allAvailableShips, pw):
  #gains: dict, key = planetId, list of (ships required, gain, other planetID())
  #available ships: dict, key = planetId, int of available ships for attacking
  
  #has the 'stay here' gains
  
  orders = [] #list of (source planetId, destinationPlanetId, number of attackers)
  
  
  for planet in allAvailableShips:
    #log.debug('started planet ' + str(planet))
    availableShips = allAvailableShips[planet]
    gains = sorted(allGains[planet], reverse = True)
    
    if len(gains) == 0:
      #log.debug('no planets left to conquer?')
      continue
    
    if availableShips == 0:
      continue
    
    #now recursively optimize the gain
    indeces = []
    
    strategy = optimizeFleets(gains, availableShips, [])
    log.debug('planet: ' + str(planet) + ' strategy: ' + str(strategy))
    
    for index in strategy[1]:
      planet_to_attack = gains[index][2]
      ships = gains[index][0]
        
      if planet_to_attack == planet:
        if ships > 0:
          log.debug('decided to leave ' + str(ships) + ' fleets at home planet')
        pass
      else:
        orders.append((planet, planet_to_attack, ships))
      
    log.debug('planet: ' + str(planet) + ' best places to attack: ' + str(strategy[1]))
    
  #log.debug('getBestOrders3 returning : ' + str(orders))
  return orders
Exemple #9
0
def doFirstTurn(pw):
  try:
    log.debug('Start of doFirstTurn()')
    myPlanets = pw.MyPlanets()
    if len(myPlanets) != 1:
      raise Exception("should always have 1 planet on turn on")
    myPlanet = myPlanets[0]
    if myPlanet.NumShips() != 100:
      raise Exception("should always have 100 ships on initial planet")
      
    availableShips = 99 # leave 5 behind minimum
      
    planets = []
    #try to get as much growth as possible, while also minimizing distance to planets, (and possible fleet loss)
    for planet in pw.NeutralPlanets():
      growthRate = planet.GrowthRate()
      distance = pw.Distance(myPlanet.PlanetID(), planet.PlanetID())
      minShips = planet.NumShips() + 1
      
      planets.append((minShips, growthRate, distance, planet))
    
    #log.debug('before sort: ' + '\n'.join([str(p) for p in planets]))
    planets.sort(cmp = distanceSort)
    #log.debug('after sort: ' + '\n'.join([str(p) for p in planets]))
    
    #not sure if the next line should be commented, or changed in some way
    planets = planets[:len(planets)/3]
      
    #log.debug('planets to actually consider: ' + '\n'.join([str(p) for p in planets]))

    planetsToConquer = getPlanetsToGoToFirst(planets, availableShips)
    
    for planet in planetsToConquer:
        log.debug('issueing order: planetId: ' + str(planet[0].PlanetID()) + ' with ' + str(planet[1]) + ' ships')
        pw.IssueOrder(myPlanet.PlanetID(), planet[0].PlanetID(), planet[1])
        
    log.debug('end of doFirstTurn()')
    return True
  except Exception, e:
    log.exc(e)
    return False
Exemple #10
0
def filterOrders(orders, distanceFunc):
  try:
    destinations = {}
    removeIndeces =[]
    for index, (source, destination, fleet) in enumerate(orders):
      if destinations.has_key(destination):
        distance1 = distanceFunc(source, destination)
        distance2 = distanceFunc(destinations[destination][0][0], destinations[destination][0][1])
        if distance1 < distance2:
          removeIndeces.append(destinations[destination][1])
        else:
          removeIndeces.append(index)          
      else:
        destinations[destination] = ((source, destination, fleet), index)
    
    log.debug('orders: ' + str(orders))
    log.debug('remove indeces: ' + str(removeIndeces))
    for index in sorted(removeIndeces, reverse = True):
      orders.pop(index)
    
    log.debug('orders after: ' + str(orders))
          
  except Exception, e:
    log.exc(e)
Exemple #11
0
def DoTurn5(pw):
  global wait_for_enemy
  global turn_number
  turn_number += 1
  try:
    
    if turn_number == 1:
      distance_to_enemy = pw.Distance(pw.MyPlanets()[0].PlanetID(), pw.EnemyPlanets()[0].PlanetID())
      if distance_to_enemy < distance_to_wait_first_turn:
        wait_for_enemy = True
        
    if wait_for_enemy:
      if len(pw.Fleets()) > 0:
        wait_for_enemy = False
      else:
        return
    
    #for each of my planets
      #for each of the other planets
      
        #find the total number of fleets when we could get there from our planet, then determine the best planet to attack
    
    orders = []
    allGains = {}
    stayHomeGain = getAvailableShips(pw)
    availableShips = {}
    
    log.debug('starting to get planet gains')
    for my_planet in pw.MyPlanets():
      
      gains = []
      for other_planet in pw.Planets():
        gainsDict = getPlanetGains(my_planet, other_planet, pw)
        #allGains[my_planet.PlanetID()] = getPlanetGains(my_planet, other_planet, pw)
        
        for ships in gainsDict:
          if gainsDict[ships] > 0:
            gains.append((ships, gainsDict[ships], other_planet.PlanetID()))
            
        log.debug('gains for planet ' + str(my_planet.PlanetID()) + ' : \n' + '\n'.join([(str(x) + ' : ' + str(gainsDict[x])) for x in gainsDict if gainsDict[x] > 0]))
      
        availableShips[my_planet.PlanetID()] = max(0, my_planet.NumShips() - extra_ships)
      
      allGains[my_planet.PlanetID()] = gains
    log.debug('done getting planet gains')
    log.debug('gains: ' + str(allGains))
    
    """
    allGains = {}
    for my_planet in pw.MyPlanets():
      gains = []
      
      #add the gains attained by leaving ships here
      for ships in stayHomeGain[my_planet.PlanetID()]:
        gains.append((ships, stayHomeGain[my_planet.PlanetID()][ships], my_planet.PlanetID()))
        
      for other_planet in pw.Planets():
        if other_planet.GrowthRate() == 0: # not worth taking over
          continue
        if my_planet.PlanetID() == other_planet.PlanetID(): #same planet
          continue
        
        availableShips[my_planet.PlanetID()] = max(0, my_planet.NumShips() - extra_ships)
        
        shipsAtArriveTime, time = pw.GetShipsAtArriveTime(my_planet.PlanetID(), other_planet.PlanetID())
        if shipsAtArriveTime[1] == 1:
          # we will have control of that planet, don't bother with it
          pass
        else:
          # should we try to take over?
          gain = 0 if time >= turns_ahead else (turns_ahead - time) * other_planet.GrowthRate() * (1 if shipsAtArriveTime == 0 else 2)
          
          gains.append((shipsAtArriveTime[0] + extra_ships, gain, other_planet.PlanetID()))
      
      allGains[my_planet.PlanetID()] = sorted(gains)
    """
    log.debug('got all gains')
    
    orders = getBestOrders3(allGains, availableShips, pw)
    
    log.debug('got orders from getBestOrders3(): \n' + '\n'.join([str(x) for x in orders]))
    log.debug(str(orders))
    log.debug('Starting to issue all orders')
    for order in orders:
      try:
        pw.IssueOrder(order[0], order[1], order[2])
      except Exception, e:
        log.exc(e)
    log.debug('done issueing orders')
Exemple #12
0
def getBestOrders2(gains, availableShips, pw):
  #gains: dict, key = planetId, list of (ships required, gain, other planetID())
  #available ships: dict, key = planetId, int of available ships for attacking
  orders = [] #list of (source planetId, destinationPlanetId, number of attackers)
  
  
  for planet in availableShips:
    log.debug('planet: ' + str(planet) + '   available ships: ' + str(availableShips[planet]))
    log.debug('gains: \n' + '\n'.join([str(x) for x in gains[planet]]))
    
    if len(gains[planet]) == 0:
      log.debug('no planets left to conquer?')
      continue
    
    if availableShips[planet] == 0:
      continue
    # should probably do some recursive optimization crazyness here...
    if gains[planet][0][0] < availableShips[planet]:
      previousDistance = orderAlreadyPlaced(orders, gains[planet][0][2], pw)
      log.debug('orders: ' + str(orders))
      log.debug('order to place: ' + str((planet, gains[planet][0][2], gains[planet][0][0])))
      log.debug('previous distance: ' + str(previousDistance))
      if previousDistance is None:
        orders.append((planet, gains[planet][0][2], gains[planet][0][0]))
        
      #if there has already been an order placed, choose the one that's closest
      if previousDistance < pw.Distance(planet, gains[planet][0][2]):
        # do nothing, the previous one is better
        pass
      else:
        # replace the order to be sent from the current planet, with the current fleet size(since it may vary due to different distance)
        for i in range(len(orders)):
          if orders[i][1] == gains[planet][0][2]:
            orders[i] = (planet, gains[planet][0][2], gains[planet][0][0])
  
  log.debug('getBestOrders2 returning : ' + str(orders))
  return orders
Exemple #13
0
def DoTurn2(pw):
  global turn_number
  turn_number += 1
  log.debug('turn number: ' + str(turn_number))
  
  try:
    if turn_number == 1:
      if FirstTurn.doFirstTurn(pw):
        return
    
    orders = []
    
    for myPlanet in pw.MyPlanets():
      
      closestPlanet = None
      #find the closest planet that we can take over
      for planet in pw.NotMyPlanets():
        
        if FleetIsEnRoute(myPlanet.PlanetID(), planet.PlanetID(), pw.MyFleets()):
          continue
        
        try:
          if planet.Owner() == 0:
            minFleetSize = planet.NumShips() + 1
          else:
            minFleetSize = planet.NumShips() + 1 + planet.GrowthRate() * pw.Distance(myPlanet.PlanetID(), planet.PlanetID())
        except Exception, e:
          log.exc(e)
          
        if minFleetSize >= myPlanet.NumShips(): # we can't take it over with just one planet
          continue
        distance = pw.Distance(myPlanet.PlanetID(), planet.PlanetID())
        worthiness = PlanetWorthinessToTakeOver(myPlanet, planet, minFleetSize, distance)
        log.debug('worthiness: ' + str(worthiness))
        
        if closestPlanet is None or worthiness > closestPlanet[1]:
          closestPlanet = (planet, worthiness, minFleetSize)
          log.debug('assigned, closestPlanet = ' + str(closestPlanet))
          
      log.debug('closest planet for planet: ' + str(myPlanet.PlanetID()) + ' : ' + str(closestPlanet))
      if closestPlanet is None:
        log.debug('from planet' + str(myPlanet.PlanetID()) + ', no closest planet to attack')
      else:
        log.debug('planet ' + str(myPlanet.PlanetID()) + ' will attack planet ' + str(closestPlanet[0].PlanetID()) + ' with worthiness' + str(closestPlanet[1]) + ', with a fleet of ' + str(closestPlanet[2]))
        orders.append((myPlanet.PlanetID(), closestPlanet[0].PlanetID(), closestPlanet[2]))
        
    filterOrders(orders, pw.Distance)
    
    log.debug('Starting to issue all orders')
    for order in orders:
      try:
        pw.IssueOrder(order[0], order[1], order[2])
      except Exception, e:
        log.exc(e)
Exemple #14
0
      if closestPlanet is None:
        log.debug('from planet' + str(myPlanet.PlanetID()) + ', no closest planet to attack')
      else:
        log.debug('planet ' + str(myPlanet.PlanetID()) + ' will attack planet ' + str(closestPlanet[0].PlanetID()) + ' with worthiness' + str(closestPlanet[1]) + ', with a fleet of ' + str(closestPlanet[2]))
        orders.append((myPlanet.PlanetID(), closestPlanet[0].PlanetID(), closestPlanet[2]))
        
    filterOrders(orders, pw.Distance)
    
    log.debug('Starting to issue all orders')
    for order in orders:
      try:
        pw.IssueOrder(order[0], order[1], order[2])
      except Exception, e:
        log.exc(e)
        
    log.debug('done issueing orders')
  except Exception, e:
    log.exc(e)
    
def getBestOrders1(gains, availableShips):
  #gains: dict, key = planetId, list of (ships required, gain, other planetID())
  #available ships: dict, key = planetId, int of available ships for attacking
  orders = [] #list of (source planetId, destinationPlanetId, number of attackers)
  
  for planet in availableShips:
    log.debug('planet: ' + str(planet) + '   available ships: ' + str(availableShips[planet]))
    log.debug('gains: \n' + '\n'.join([str(x) for x in gains[planet]]))
    
    if availableShips[planet] == 0:
      continue
    # should probably do some recursive optimization crazyness here...
Exemple #15
0
 def GetShipsAtArriveTime(self, source_planet, destination_planet):
   #log.debug('start GetShipsAtArriveTime() for source: ' + str(source_planet) + ' , destination: ' + str(destination_planet))
   distance = self.Distance(source_planet, destination_planet)
   #log.debug('distance: ' + str(distance))
   
   currentShips = [self._planets[destination_planet].NumShips(), self._planets[destination_planet].Owner()]
   #log.debug('current ships_: ' + str(currentShips))
   growthRate = self._planets[destination_planet].GrowthRate()
   my_fleets = [fleet for fleet in self.MyFleets() if fleet.DestinationPlanet() == destination_planet]
   enemy_fleets = [fleet for fleet in self.EnemyFleets() if fleet.DestinationPlanet() == destination_planet]
   
   #log.debug('enemy fleets: ' + str(enemy_fleets))
   #log.debug('my fleets: ' + str(my_fleets))
   
   allFleets = {}
   for fleet in my_fleets + enemy_fleets:
     turns = fleet.TurnsRemaining()
     
     if turns > distance:
       continue
     
     ships = fleet.NumShips()
     owner = fleet.Owner()
     
     if not allFleets.has_key(turns):
       allFleets[turns] = (ships, owner)
     else:
       if allFleets[turns][1] == owner:
         allFleets[turns] = (allFleets[turns][1] + ships, owner)
       else:
         s = allFleets[turns][0] - ships
         if s < 0:
           allFleets[turns] = (-s, 1 if allFleets[turns][1] == 2 else 2)
         else:
           allFleets[turns] = (s, allFleets[turns][1])
     
   #log.debug('all Fleets: ' + str(allFleets)) 
   
   #now we get to figure out what happens once all the fleets have shown up
   # up until we can get there if we leave this turn
   #log.debug('before figuring out future of planet, currentShips = ' + str(currentShips))
   
   lastTurn = 0
   for turn in sorted(allFleets.keys()):
     fleet = allFleets[turn]
     
     turnsSinceLast = turn - lastTurn
     lastTurn = turn
     if currentShips[1] == 0:
       #planet is neutral, no growing
       pass
     else:
       #planet is either mine or enemy's, regardless grow by growthRate * turnsSinceLast
       currentShips[0] += growthRate * turnsSinceLast
     
     if fleet[1] == currentShips[1]:
       #fleet is from the owner of the planet
       currentShips[0] += fleet[0]
     else:
       currentShips[0] -= fleet[0]
       if currentShips[0] < 0:
         currentShips[1] = fleet[1]
         currentShips[0] = -currentShips[0]
         
     log.debug('after fleet ' + str(fleet) + ' showed up: ' + str(currentShips))
     
   #add the growth between the last fleet showing up and when my fleet can get there
   if currentShips[1] != 0:
     currentShips[0] += (distance - lastTurn) * growthRate
     
   #log.debug('end of getShipsAtArriveTime()')
   return currentShips, distance