Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

85 bestplanets(15,40) - added files

  • Loading branch information...
commit 0091192e924ebf7c38cfd46e8cae2d57cdcb26fa 1 parent 85d92c8
Alex Pinkin authored
317 MyBot_82.py
... ... @@ -0,0 +1,317 @@
  1 +from planetwars import BaseBot, Game
  2 +from planetwars.universe2 import Universe2
  3 +from planetwars.planet import Planet
  4 +from planetwars.planet2 import Planet2
  5 +from planetwars.universe import player, Fleet
  6 +from logging import getLogger, sys
  7 +import copy
  8 +from copy import copy
  9 +import planetwars.planet
  10 +import planetwars.planet
  11 +import time
  12 +import random
  13 +
  14 +log = getLogger(__name__)
  15 +
  16 +ATTACK_PROXIMITY_RATIO = 1.2
  17 +
  18 +# Planet score function adjustment
  19 +# Simulation based on distance, growth and cost - X turns ahead?
  20 +# Raise score of neutrals attacked by enemy first?
  21 +# Is multi-attack worth it?
  22 +# Move ships to the front lines!
  23 +# Slow growth if enemy home nearby
  24 +# Smart calculation if to attack neutral (can enemy steal it without losing)
  25 +# Strategy adjustment depending on my vs enemy ship count/production
  26 +# Currently over-expanding with no need to
  27 +
  28 +class MyBot(BaseBot):
  29 +
  30 + def closest_enemy_planet_distance(self, p):
  31 + return min((lambda ep:ep.distance(p))(ep) for ep in self.universe.enemy_planets)
  32 +
  33 + def average_enemy_planet_distance(self, p):
  34 + distance_sum = sum( [ planet.distance(p) for planet in self.universe.enemy_planets ] )
  35 + if len(self.universe.enemy_planets) == 0:
  36 + return -1
  37 + return distance_sum/len(self.universe.enemy_planets)
  38 +
  39 + def com_enemy_planet_distance(self, p):
  40 + return self.enemy_com.distance(p)
  41 +
  42 + def closest_my_planet_distance(self, p):
  43 + return min((lambda mp:mp.distance(p))(mp) for mp in self.universe.my_planets)
  44 +
  45 + def closest_my_planet_distance(self, p):
  46 + return min((lambda mp:mp.distance(p) if self.ships_available[mp] >0 else 1000000)(mp) for mp in self.universe.my_planets)
  47 +
  48 + def max_turns_remaining(self, fleets):
  49 + return -1 if len(fleets) == 0 else max((lambda f:f.turns_remaining)(f) for f in fleets)
  50 +
  51 + def enemy_fleets_attacking(self, planet):
  52 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner in player.NOT_ME ] )
  53 +
  54 + def my_fleets_attacking(self, planet):
  55 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner == player.ME] )
  56 +
  57 + def calc_home_dist(self):
  58 + self.my_home = list(self.universe.my_planets)[0]
  59 + self.enemy_home = list(self.universe.enemy_planets)[0]
  60 + self.home_dist = self.my_home.distance(self.enemy_home)
  61 +
  62 + def get_best_planets_to_attack(self, count=1, turns=30, prod_turns=100):
  63 + planet_score = {}
  64 + #log.info("Score eval for %s planets" % len(self.universe.not_my_planets))
  65 + for planet_to_attack in self.universe.not_my_planets:
  66 + log.info("Score eval for %s" % planet_to_attack)
  67 + planet_score[planet_to_attack] = 0
  68 +
  69 + planet_to_attack_future = planet_to_attack.in_future(turns)
  70 + if planet_to_attack_future.owner == player.ME:
  71 + continue
  72 +
  73 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  74 + for source in my_nearest_planets:
  75 + log.info("Score eval source %s" % source)
  76 + distance = source.distance(planet_to_attack)
  77 + if self.ships_available[source] <= 0 or distance >= turns:
  78 + continue
  79 + if planet_to_attack.owner == player.NOBODY and \
  80 + distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  81 + continue
  82 +
  83 + fleet_to_send = Fleet(self.universe,12345,1, self.ships_available[source], source.id, planet_to_attack.id, distance, distance)
  84 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  85 + if planet_to_attack_future.owner != player.ME:
  86 + continue
  87 +
  88 + for ships_to_send in range(1, self.ships_available[source]+1, 10):
  89 + fleet_to_send = Fleet(self.universe,12345,1, ships_to_send, source.id, planet_to_attack.id, distance, distance)
  90 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  91 + if planet_to_attack_future.owner == player.ME:
  92 + planet_score[planet_to_attack] = planet_to_attack_future.ship_count - ships_to_send + prod_turns*planet_to_attack.growth_rate
  93 + break
  94 + if planet_score[planet_to_attack] > 0:
  95 + break
  96 + sorted_planets = sorted(self.universe.not_my_planets, key=lambda p : planet_score[p] + p.id/1000000.0, reverse=True)
  97 + result = sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  98 + filtered_result = []
  99 + for p in result:
  100 + if planet_score[p] > 0:
  101 + filtered_result.append(p)
  102 + for p in filtered_result:
  103 + if planet_score[p] > 0:
  104 + log.info("Score for %s is %s" % (p,planet_score[p]))
  105 +
  106 + log.info("Score eval done: %s planets" % len(result))
  107 + return filtered_result
  108 +
  109 + def weakest_not_my_planets_distance_based(self, count=1):
  110 + sorted_planets = sorted(self.universe.not_my_planets, \
  111 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count)/self.closest_my_planet_distance(p)+p.id/1000000.0, reverse=True)
  112 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  113 +
  114 + def total_fleet_count_enroute(self, owner, planet):
  115 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner, destination = planet) ] )
  116 +
  117 + def effective_fleet_ship_count_enroute(self, owner, planet):
  118 + result = 0
  119 + for fleet in self.universe.find_fleets(destination = planet):
  120 + if fleet.owner == owner:
  121 + result += fleet.ship_count
  122 + else:
  123 + result -= fleet.ship_count
  124 + return result
  125 +
  126 + def total_fleet_ship_count(self, owner):
  127 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner) ] )
  128 +
  129 +
  130 + def weakest_not_my_planets_effective(self, count=1):
  131 + sorted_planets = sorted(self.universe.not_my_planets, \
  132 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count-self.total_fleet_count_enroute(player.ME, p)+self.total_fleet_count_enroute(player.NOT_ME, p)) + p.id/1000000.0, reverse=True)
  133 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  134 +
  135 + def invert_owner(self, owner):
  136 + if owner == player.ME:
  137 + return player.NOT_ME
  138 + else:
  139 + return player.ME
  140 +
  141 + # calculate how many ships are available or needed for each of my and enemy planets
  142 + def doPrep(self):
  143 + log.info("Prep phase")
  144 +
  145 + # calculate current high level metrics
  146 + self.my_total_ships_available = 0
  147 + self.my_total_ships = 0
  148 + self.my_total_growth_rate = 0
  149 + self.enemy_total_ships_available = 0
  150 + self.enemy_total_ships = 0
  151 + self.enemy_total_growth_rate = 0
  152 + self.ships_available = {}
  153 + self.ships_needed = {}
  154 + for planet in self.universe.my_planets | self.universe.enemy_planets:
  155 + if len(planet.attacking_fleets) == 0:
  156 + self.ships_available[planet] = planet.ship_count
  157 + self.ships_needed[planet] = 0
  158 + else:
  159 + simulation_distance = self.max_turns_remaining(planet.attacking_fleets | planet.reinforcement_fleets)
  160 + planet_timeline = planet.in_future_timeline(simulation_distance)
  161 + max_needed = 0
  162 + min_available = 1000000
  163 + log.info("timeline for %s: %s" % (planet, planet_timeline))
  164 + for step in planet_timeline:
  165 + owner = step[0]
  166 + ship_count = step[1]
  167 + if owner != planet.owner:
  168 + max_needed = max(max_needed, ship_count)
  169 + else:
  170 + min_available = min(min_available, ship_count)
  171 + if max_needed > 0:
  172 + # do we bail if we are going to lose this planet anyway?
  173 + self.ships_available[planet] = 0
  174 + self.ships_needed[planet] = max_needed
  175 + else:
  176 + self.ships_available[planet] = min_available
  177 + self.ships_needed[planet] = 0
  178 + if (planet.owner == player.ME):
  179 + self.my_total_ships_available += self.ships_available[planet]
  180 + self.my_total_growth_rate += planet.growth_rate
  181 + self.my_total_ships += planet.ship_count
  182 + else:
  183 + self.enemy_total_ships_available += self.ships_available[planet]
  184 + self.enemy_total_growth_rate += planet.growth_rate
  185 + self.enemy_total_ships += planet.ship_count
  186 + log.info("avail ships for %s: %s" % (planet, self.ships_available[planet]))
  187 +
  188 +
  189 +
  190 + self.my_total_ships += self.total_fleet_ship_count(player.ME)
  191 + self.enemy_total_ships += self.total_fleet_ship_count(player.NOT_ME)
  192 +
  193 + # calculate enemy's center of mass
  194 + weighted_x = 0
  195 + weighted_y = 0
  196 + div = 0
  197 + for planet in self.universe.enemy_planets:
  198 + weighted_x += planet.position.x * self.ships_available[planet]
  199 + weighted_y += planet.position.y * self.ships_available[planet]
  200 + div += self.ships_available[planet]
  201 + if div == 0:
  202 + div = 1
  203 +
  204 + self.enemy_com = Planet(self.universe, 666, weighted_x/div, weighted_y/div, 2, 0, 0)
  205 +
  206 + log.info("MY STATUS: %s/%s - %s available" % (self.my_total_ships, self.my_total_growth_rate, self.my_total_ships_available))
  207 + log.info("ENEMY STATUS: %s/%s - %s available" % (self.enemy_total_ships, self.enemy_total_growth_rate, self.enemy_total_ships_available))
  208 + log.info("ENEMY COM: %s, %s" % (self.enemy_com.position.x, self.enemy_com.position.y))
  209 +
  210 + def doDefense(self):
  211 + log.info("Defense phase")
  212 + prioritized_planets_to_defend = sorted(self.universe.my_planets, key=lambda p : p.growth_rate + p.id/1000000.0, reverse=True)
  213 + for planet_to_defend in prioritized_planets_to_defend:
  214 + if self.ships_needed[planet_to_defend] > 0:
  215 + current_ships_needed = self.ships_needed[planet_to_defend]
  216 + log.info("Planet %s needs %s ships!" % (planet_to_defend, current_ships_needed))
  217 + # send reinforcements from closest planets
  218 + my_closest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_defend) + p.id/1000000.0)
  219 +
  220 + for source in my_closest_planets:
  221 + if source.id != planet_to_defend.id and self.ships_available[source] > 0:
  222 + ships_to_send = min(current_ships_needed, self.ships_available[source])
  223 + source.send_fleet(planet_to_defend, ships_to_send)
  224 + self.ships_available[source] -= ships_to_send
  225 + self.ships_needed[planet_to_defend] -= ships_to_send
  226 + current_ships_needed -= ships_to_send
  227 + if current_ships_needed <= 0:
  228 + break
  229 +
  230 +
  231 + def doOffense(self):
  232 + log.info("Offense phase")
  233 + #weakest_planets = self.universe.weakest_planets(player.NOT_ME,10)
  234 + #weakest_planets = self.weakest_not_my_planets_effective(10)
  235 + #weakest_planets = self.get_best_planets_to_attack(10,30,100)
  236 + weakest_planets = self.weakest_not_my_planets_distance_based(10)
  237 + #log.info("Weakest planets: %s" % weakest_planets)
  238 +
  239 + for planet_to_attack in weakest_planets:
  240 + #log.info("Evaluating attack on %s" % planet_to_attack)
  241 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  242 + for source in my_nearest_planets:
  243 + if self.ships_available[source] <= 0:
  244 + continue
  245 + attack_distance = source.distance(planet_to_attack)
  246 + steal = False
  247 + if planet_to_attack.owner == player.NOBODY and self.enemy_fleets_attacking(planet_to_attack) == 1 and \
  248 + self.my_fleets_attacking(planet_to_attack) == 0:
  249 + # see if we can steal
  250 + enemy_fleet = list(self.universe.find_fleets(player.NOT_ME, destination = planet_to_attack))[0]
  251 + if attack_distance == (enemy_fleet.turns_remaining+1) and self.ships_available[source]>=(planet_to_attack.growth_rate+2) and \
  252 + enemy_fleet.ship_count == (planet_to_attack.ship_count+1):
  253 + log.info("Need to steal %s, fleet inbound %s" % (planet_to_attack,enemy_fleet))
  254 + steal = True
  255 + else:
  256 + continue
  257 +
  258 + if planet_to_attack.owner == player.NOBODY and \
  259 + steal == False and \
  260 + attack_distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  261 + continue
  262 +
  263 + simulation_distance = attack_distance
  264 + if planet_to_attack.owner == player.NOBODY:
  265 + simulation_distance = max(attack_distance, self.max_turns_remaining(planet_to_attack.attacking_fleets))
  266 + planet_to_attack_future = planet_to_attack.in_future(simulation_distance)
  267 + current_ships_needed = planet_to_attack_future.ship_count + 1
  268 + # we currently attack from a single planet within one move
  269 + #log.info("Future eval for %s is %s, simul dist %s" % (planet_to_attack_future.owner,current_ships_needed, simulation_distance))
  270 + if planet_to_attack_future.owner != player.ME:
  271 + if planet_to_attack.owner == player.NOBODY:
  272 + if current_ships_needed <= self.ships_available[source]:
  273 + source.send_fleet(planet_to_attack, current_ships_needed)
  274 + self.ships_available[source] -= current_ships_needed
  275 + break
  276 + else:
  277 + if current_ships_needed <= self.ships_available[source]:
  278 + source.send_fleet(planet_to_attack, current_ships_needed)
  279 + self.ships_available[source] -= current_ships_needed
  280 + break
  281 +
  282 + def doPostOffense(self):
  283 + log.info("Post-Offense phase")
  284 + if len(self.universe.enemy_planets) == 0:
  285 + return
  286 +
  287 + # cache closest and com enemy planet distances
  288 + closest_enemy_planet_distance_map = {}
  289 + com_enemy_planet_distance_map = {}
  290 + for planet in self.universe.my_planets:
  291 + closest_enemy_planet_distance_map[planet] = self.closest_enemy_planet_distance(planet)
  292 + com_enemy_planet_distance_map[planet] = self.com_enemy_planet_distance(planet)
  293 +
  294 + for source_planet in self.universe.my_planets:
  295 + if self.ships_available[source_planet] > 0:
  296 + log.info("Post-Offense for %s" % source_planet)
  297 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(source_planet) + p.id/1000000.0)
  298 + for dest_planet in my_nearest_planets:
  299 + distance = source_planet.distance(dest_planet)
  300 + if distance > 0 and closest_enemy_planet_distance_map[dest_planet] <= closest_enemy_planet_distance_map[source_planet]:
  301 + if com_enemy_planet_distance_map[dest_planet] < com_enemy_planet_distance_map[source_planet]:
  302 + source_planet.send_fleet(dest_planet, self.ships_available[source_planet])
  303 + self.ships_available[source_planet] = 0
  304 + break
  305 +
  306 +
  307 + def do_turn(self):
  308 + if len(self.universe.my_planets) == 0 or len(self.universe.enemy_planets) == 0:
  309 + return
  310 +
  311 + self.doPrep()
  312 + self.doDefense()
  313 + self.doOffense()
  314 + self.doPostOffense()
  315 +
  316 +
  317 +Game(MyBot, universe_class=Universe2, planet_class=Planet2)
318 MyBot_83.py
... ... @@ -0,0 +1,318 @@
  1 +from planetwars import BaseBot, Game
  2 +from planetwars.universe2 import Universe2
  3 +from planetwars.planet import Planet
  4 +from planetwars.planet2 import Planet2
  5 +from planetwars.universe import player, Fleet
  6 +from logging import getLogger, sys
  7 +import copy
  8 +from copy import copy
  9 +import planetwars.planet
  10 +import planetwars.planet
  11 +import time
  12 +import random
  13 +
  14 +log = getLogger(__name__)
  15 +
  16 +ATTACK_PROXIMITY_RATIO = 1.2
  17 +
  18 +# Planet score function adjustment
  19 +# Simulation based on distance, growth and cost - X turns ahead?
  20 +# Raise score of neutrals attacked by enemy first?
  21 +# Is multi-attack worth it?
  22 +# Move ships to the front lines!
  23 +# Slow growth if enemy home nearby
  24 +# Smart calculation if to attack neutral (can enemy steal it without losing)
  25 +# Strategy adjustment depending on my vs enemy ship count/production
  26 +# Currently over-expanding with no need to
  27 +
  28 +class MyBot(BaseBot):
  29 +
  30 + def closest_enemy_planet_distance(self, p):
  31 + return min((lambda ep:ep.distance(p))(ep) for ep in self.universe.enemy_planets)
  32 +
  33 + def average_enemy_planet_distance(self, p):
  34 + distance_sum = sum( [ planet.distance(p) for planet in self.universe.enemy_planets ] )
  35 + if len(self.universe.enemy_planets) == 0:
  36 + return -1
  37 + return distance_sum/len(self.universe.enemy_planets)
  38 +
  39 + def com_enemy_planet_distance(self, p):
  40 + return self.enemy_com.distance(p)
  41 +
  42 + def closest_my_planet_distance(self, p):
  43 + return min((lambda mp:mp.distance(p))(mp) for mp in self.universe.my_planets)
  44 +
  45 + def closest_my_planet_distance(self, p):
  46 + return min((lambda mp:mp.distance(p) if self.ships_available[mp] >0 else 1000000)(mp) for mp in self.universe.my_planets)
  47 +
  48 + def max_turns_remaining(self, fleets):
  49 + return -1 if len(fleets) == 0 else max((lambda f:f.turns_remaining)(f) for f in fleets)
  50 +
  51 + def enemy_fleets_attacking(self, planet):
  52 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner in player.NOT_ME ] )
  53 +
  54 + def my_fleets_attacking(self, planet):
  55 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner == player.ME] )
  56 +
  57 + def calc_home_dist(self):
  58 + self.my_home = list(self.universe.my_planets)[0]
  59 + self.enemy_home = list(self.universe.enemy_planets)[0]
  60 + self.home_dist = self.my_home.distance(self.enemy_home)
  61 +
  62 + def get_best_planets_to_attack(self, count=1, turns=30, prod_turns=100):
  63 + planet_score = {}
  64 + #log.info("Score eval for %s planets" % len(self.universe.not_my_planets))
  65 + for planet_to_attack in self.universe.not_my_planets:
  66 + log.info("Score eval for %s" % planet_to_attack)
  67 + planet_score[planet_to_attack] = 0
  68 +
  69 + planet_to_attack_future = planet_to_attack.in_future(turns)
  70 + if planet_to_attack_future.owner == player.ME:
  71 + continue
  72 +
  73 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  74 + for source in my_nearest_planets:
  75 + log.info("Score eval source %s" % source)
  76 + distance = source.distance(planet_to_attack)
  77 + if self.ships_available[source] <= 0 or distance >= turns:
  78 + continue
  79 + if planet_to_attack.owner == player.NOBODY and \
  80 + distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  81 + continue
  82 +
  83 + fleet_to_send = Fleet(self.universe,12345,1, self.ships_available[source], source.id, planet_to_attack.id, distance, distance)
  84 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  85 + if planet_to_attack_future.owner != player.ME:
  86 + continue
  87 +
  88 + for ships_to_send in range(1, self.ships_available[source]+1, 1):
  89 + fleet_to_send = Fleet(self.universe,12345,1, ships_to_send, source.id, planet_to_attack.id, distance, distance)
  90 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  91 + if planet_to_attack_future.owner == player.ME:
  92 + planet_score[planet_to_attack] = planet_to_attack_future.ship_count - ships_to_send + prod_turns*planet_to_attack.growth_rate
  93 + break
  94 + if planet_score[planet_to_attack] > 0:
  95 + break
  96 + sorted_planets = sorted(self.universe.not_my_planets, key=lambda p : planet_score[p] + p.id/1000000.0, reverse=True)
  97 + result = sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  98 + filtered_result = []
  99 + for p in result:
  100 + if planet_score[p] > 0:
  101 + filtered_result.append(p)
  102 + for p in filtered_result:
  103 + if planet_score[p] > 0:
  104 + log.info("Score for %s is %s" % (p,planet_score[p]))
  105 +
  106 + log.info("Score eval done: %s planets" % len(result))
  107 + return filtered_result
  108 +
  109 + def weakest_not_my_planets_distance_based(self, count=1):
  110 + sorted_planets = sorted(self.universe.not_my_planets, \
  111 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count)/self.closest_my_planet_distance(p)+p.id/1000000.0, reverse=True)
  112 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  113 +
  114 + def total_fleet_count_enroute(self, owner, planet):
  115 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner, destination = planet) ] )
  116 +
  117 + def effective_fleet_ship_count_enroute(self, owner, planet):
  118 + result = 0
  119 + for fleet in self.universe.find_fleets(destination = planet):
  120 + if fleet.owner == owner:
  121 + result += fleet.ship_count
  122 + else:
  123 + result -= fleet.ship_count
  124 + return result
  125 +
  126 + def total_fleet_ship_count(self, owner):
  127 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner) ] )
  128 +
  129 +
  130 + def weakest_not_my_planets_effective(self, count=1):
  131 + sorted_planets = sorted(self.universe.not_my_planets, \
  132 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count-self.total_fleet_count_enroute(player.ME, p)+self.total_fleet_count_enroute(player.NOT_ME, p)) + p.id/1000000.0, reverse=True)
  133 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  134 +
  135 + def invert_owner(self, owner):
  136 + if owner == player.ME:
  137 + return player.NOT_ME
  138 + else:
  139 + return player.ME
  140 +
  141 + # calculate how many ships are available or needed for each of my and enemy planets
  142 + def doPrep(self):
  143 + log.info("Prep phase")
  144 +
  145 + # calculate current high level metrics
  146 + self.my_total_ships_available = 0
  147 + self.my_total_ships = 0
  148 + self.my_total_growth_rate = 0
  149 + self.enemy_total_ships_available = 0
  150 + self.enemy_total_ships = 0
  151 + self.enemy_total_growth_rate = 0
  152 + self.ships_available = {}
  153 + self.ships_needed = {}
  154 + for planet in self.universe.my_planets | self.universe.enemy_planets:
  155 + if len(planet.attacking_fleets) == 0:
  156 + self.ships_available[planet] = planet.ship_count
  157 + self.ships_needed[planet] = 0
  158 + else:
  159 + simulation_distance = self.max_turns_remaining(planet.attacking_fleets | planet.reinforcement_fleets)
  160 + planet_timeline = planet.in_future_timeline(simulation_distance)
  161 + max_needed = 0
  162 + min_available = 1000000
  163 + log.info("timeline for %s: %s" % (planet, planet_timeline))
  164 + for step in planet_timeline:
  165 + owner = step[0]
  166 + ship_count = step[1]
  167 + if owner != planet.owner:
  168 + max_needed = max(max_needed, ship_count)
  169 + else:
  170 + min_available = min(min_available, ship_count)
  171 + if max_needed > 0:
  172 + # do we bail if we are going to lose this planet anyway?
  173 + self.ships_available[planet] = 0
  174 + self.ships_needed[planet] = max_needed
  175 + else:
  176 + self.ships_available[planet] = min_available
  177 + self.ships_needed[planet] = 0
  178 + if (planet.owner == player.ME):
  179 + self.my_total_ships_available += self.ships_available[planet]
  180 + self.my_total_growth_rate += planet.growth_rate
  181 + self.my_total_ships += planet.ship_count
  182 + else:
  183 + self.enemy_total_ships_available += self.ships_available[planet]
  184 + self.enemy_total_growth_rate += planet.growth_rate
  185 + self.enemy_total_ships += planet.ship_count
  186 + #log.info("avail ships for %s: %s" % (planet, self.ships_available[planet]))
  187 +
  188 +
  189 +
  190 + self.my_total_ships += self.total_fleet_ship_count(player.ME)
  191 + self.enemy_total_ships += self.total_fleet_ship_count(player.NOT_ME)
  192 +
  193 + # calculate enemy's center of mass
  194 + weighted_x = 0
  195 + weighted_y = 0
  196 + div = 0
  197 + for planet in self.universe.enemy_planets:
  198 + weighted_x += planet.position.x * self.ships_available[planet]
  199 + weighted_y += planet.position.y * self.ships_available[planet]
  200 + div += self.ships_available[planet]
  201 + if div == 0:
  202 + div = 1
  203 +
  204 + self.enemy_com = Planet(self.universe, 666, weighted_x/div, weighted_y/div, 2, 0, 0)
  205 +
  206 + log.info("MY STATUS: %s/%s - %s available" % (self.my_total_ships, self.my_total_growth_rate, self.my_total_ships_available))
  207 + log.info("ENEMY STATUS: %s/%s - %s available" % (self.enemy_total_ships, self.enemy_total_growth_rate, self.enemy_total_ships_available))
  208 + log.info("ENEMY COM: %s, %s" % (self.enemy_com.position.x, self.enemy_com.position.y))
  209 +
  210 + def doDefense(self):
  211 + log.info("Defense phase")
  212 + prioritized_planets_to_defend = sorted(self.universe.my_planets, key=lambda p : p.growth_rate + p.id/1000000.0, reverse=True)
  213 + for planet_to_defend in prioritized_planets_to_defend:
  214 + if self.ships_needed[planet_to_defend] > 0:
  215 + current_ships_needed = self.ships_needed[planet_to_defend]
  216 + log.info("Planet %s needs %s ships!" % (planet_to_defend, current_ships_needed))
  217 + # send reinforcements from closest planets
  218 + my_closest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_defend) + p.id/1000000.0)
  219 +
  220 + for source in my_closest_planets:
  221 + if source.id != planet_to_defend.id and self.ships_available[source] > 0:
  222 + ships_to_send = min(current_ships_needed, self.ships_available[source])
  223 + source.send_fleet(planet_to_defend, ships_to_send)
  224 + self.ships_available[source] -= ships_to_send
  225 + self.ships_needed[planet_to_defend] -= ships_to_send
  226 + current_ships_needed -= ships_to_send
  227 + if current_ships_needed <= 0:
  228 + break
  229 +
  230 +
  231 + def doOffense(self):
  232 + log.info("Offense phase")
  233 + #weakest_planets = self.universe.weakest_planets(player.NOT_ME,10)
  234 + #weakest_planets = self.weakest_not_my_planets_effective(10)
  235 + weakest_planets = self.get_best_planets_to_attack(10,15,50)
  236 + #weakest_planets = self.weakest_not_my_planets_distance_based(10)
  237 + #log.info("Weakest planets: %s" % weakest_planets)
  238 +
  239 + for planet_to_attack in weakest_planets:
  240 + log.info("Evaluating attack on %s" % planet_to_attack)
  241 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  242 + for source in my_nearest_planets:
  243 + if self.ships_available[source] <= 0:
  244 + continue
  245 + attack_distance = source.distance(planet_to_attack)
  246 +
  247 + # see if we can steal
  248 + steal = False
  249 + if planet_to_attack.owner == player.NOBODY and self.enemy_fleets_attacking(planet_to_attack) == 1 and \
  250 + self.my_fleets_attacking(planet_to_attack) == 0:
  251 + enemy_fleet = list(self.universe.find_fleets(player.NOT_ME, destination = planet_to_attack))[0]
  252 + if attack_distance == (enemy_fleet.turns_remaining+1) and self.ships_available[source]>=(planet_to_attack.growth_rate+2) and \
  253 + enemy_fleet.ship_count == (planet_to_attack.ship_count+1):
  254 + log.info("Need to steal %s, fleet inbound %s" % (planet_to_attack,enemy_fleet))
  255 + steal = True
  256 + else:
  257 + continue
  258 +
  259 + if planet_to_attack.owner == player.NOBODY and \
  260 + steal == False and \
  261 + attack_distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  262 + continue
  263 +
  264 + simulation_distance = attack_distance
  265 + if planet_to_attack.owner == player.NOBODY:
  266 + simulation_distance = max(attack_distance, self.max_turns_remaining(planet_to_attack.attacking_fleets))
  267 + planet_to_attack_future = planet_to_attack.in_future(simulation_distance)
  268 + current_ships_needed = planet_to_attack_future.ship_count + 1
  269 + # we currently attack from a single planet within one move
  270 + log.info("Future eval for %s is %s, simul dist %s" % (planet_to_attack_future.owner,current_ships_needed, simulation_distance))
  271 + if planet_to_attack_future.owner != player.ME:
  272 + if planet_to_attack.owner == player.NOBODY:
  273 + if current_ships_needed <= self.ships_available[source]:
  274 + source.send_fleet(planet_to_attack, current_ships_needed)
  275 + self.ships_available[source] -= current_ships_needed
  276 + break
  277 + else:
  278 + if current_ships_needed <= self.ships_available[source]:
  279 + source.send_fleet(planet_to_attack, current_ships_needed)
  280 + self.ships_available[source] -= current_ships_needed
  281 + break
  282 +
  283 + def doPostOffense(self):
  284 + log.info("Post-Offense phase")
  285 + if len(self.universe.enemy_planets) == 0:
  286 + return
  287 +
  288 + # cache closest and com enemy planet distances
  289 + closest_enemy_planet_distance_map = {}
  290 + com_enemy_planet_distance_map = {}
  291 + for planet in self.universe.my_planets:
  292 + closest_enemy_planet_distance_map[planet] = self.closest_enemy_planet_distance(planet)
  293 + com_enemy_planet_distance_map[planet] = self.com_enemy_planet_distance(planet)
  294 +
  295 + for source_planet in self.universe.my_planets:
  296 + if self.ships_available[source_planet] > 0:
  297 + log.info("Post-Offense for %s" % source_planet)
  298 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(source_planet) + p.id/1000000.0)
  299 + for dest_planet in my_nearest_planets:
  300 + distance = source_planet.distance(dest_planet)
  301 + if distance > 0 and closest_enemy_planet_distance_map[dest_planet] <= closest_enemy_planet_distance_map[source_planet]:
  302 + if com_enemy_planet_distance_map[dest_planet] < com_enemy_planet_distance_map[source_planet]:
  303 + source_planet.send_fleet(dest_planet, self.ships_available[source_planet])
  304 + self.ships_available[source_planet] = 0
  305 + break
  306 +
  307 +
  308 + def do_turn(self):
  309 + if len(self.universe.my_planets) == 0 or len(self.universe.enemy_planets) == 0:
  310 + return
  311 +
  312 + self.doPrep()
  313 + self.doDefense()
  314 + self.doOffense()
  315 + self.doPostOffense()
  316 +
  317 +
  318 +Game(MyBot, universe_class=Universe2, planet_class=Planet2)
322 MyBot_85.py
... ... @@ -0,0 +1,322 @@
  1 +from planetwars import BaseBot, Game
  2 +from planetwars.universe2 import Universe2
  3 +from planetwars.planet import Planet
  4 +from planetwars.planet2 import Planet2
  5 +from planetwars.universe import player, Fleet
  6 +from logging import getLogger, sys
  7 +import copy
  8 +from copy import copy
  9 +import planetwars.planet
  10 +import planetwars.planet
  11 +import time
  12 +import random
  13 +
  14 +log = getLogger(__name__)
  15 +
  16 +ATTACK_PROXIMITY_RATIO = 1.2
  17 +
  18 +# Planet score function adjustment
  19 +# Simulation based on distance, growth and cost - X turns ahead?
  20 +# Raise score of neutrals attacked by enemy first?
  21 +# Is multi-attack worth it?
  22 +# Move ships to the front lines!
  23 +# Slow growth if enemy home nearby
  24 +# Smart calculation if to attack neutral (can enemy steal it without losing)
  25 +# Strategy adjustment depending on my vs enemy ship count/production
  26 +# Currently over-expanding with no need to
  27 +
  28 +class MyBot(BaseBot):
  29 +
  30 + def closest_enemy_planet_distance(self, p):
  31 + return min((lambda ep:ep.distance(p))(ep) for ep in self.universe.enemy_planets)
  32 +
  33 + def average_enemy_planet_distance(self, p):
  34 + distance_sum = sum( [ planet.distance(p) for planet in self.universe.enemy_planets ] )
  35 + if len(self.universe.enemy_planets) == 0:
  36 + return -1
  37 + return distance_sum/len(self.universe.enemy_planets)
  38 +
  39 + def com_enemy_planet_distance(self, p):
  40 + return self.enemy_com.distance(p)
  41 +
  42 + def closest_my_planet_distance(self, p):
  43 + return min((lambda mp:mp.distance(p))(mp) for mp in self.universe.my_planets)
  44 +
  45 + def closest_my_planet_distance(self, p):
  46 + return min((lambda mp:mp.distance(p) if self.ships_available[mp] >0 else 1000000)(mp) for mp in self.universe.my_planets)
  47 +
  48 + def max_turns_remaining(self, fleets):
  49 + return -1 if len(fleets) == 0 else max((lambda f:f.turns_remaining)(f) for f in fleets)
  50 +
  51 + def enemy_fleets_attacking(self, planet):
  52 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner in player.NOT_ME ] )
  53 +
  54 + def my_fleets_attacking(self, planet):
  55 + return sum( [ 1 for fleet in planet.attacking_fleets if fleet.owner == player.ME] )
  56 +
  57 + def calc_home_dist(self):
  58 + self.my_home = list(self.universe.my_planets)[0]
  59 + self.enemy_home = list(self.universe.enemy_planets)[0]
  60 + self.home_dist = self.my_home.distance(self.enemy_home)
  61 +
  62 + def get_best_planets_to_attack(self, count=1, turns=30, prod_turns=100):
  63 + planet_score = {}
  64 + #log.info("Score eval for %s planets" % len(self.universe.not_my_planets))
  65 + for planet_to_attack in self.universe.not_my_planets:
  66 + log.info("Score eval for %s" % planet_to_attack)
  67 + planet_score[planet_to_attack] = 0
  68 +
  69 + planet_to_attack_future = planet_to_attack.in_future(turns)
  70 + if planet_to_attack_future.owner == player.ME:
  71 + continue
  72 +
  73 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  74 + for source in my_nearest_planets:
  75 + log.info("Score eval source %s" % source)
  76 + distance = source.distance(planet_to_attack)
  77 + if self.ships_available[source] <= 0 or distance >= turns:
  78 + continue
  79 + if planet_to_attack.owner == player.NOBODY and \
  80 + distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  81 + continue
  82 +
  83 + fleet_to_send = Fleet(self.universe,12345,1, self.ships_available[source], source.id, planet_to_attack.id, distance, distance)
  84 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  85 + if planet_to_attack_future.owner != player.ME:
  86 + continue
  87 +
  88 + min_ships_to_send = 1
  89 + if len(planet_to_attack.attacking_fleets) == 0:
  90 + min_ships_to_send = planet_to_attack.ship_count+1
  91 +
  92 + for ships_to_send in range(1, self.ships_available[source]+1, 1):
  93 + fleet_to_send = Fleet(self.universe,12345,1, ships_to_send, source.id, planet_to_attack.id, distance, distance)
  94 + planet_to_attack_future = planet_to_attack.in_future(turns, fleet_to_send)
  95 + if planet_to_attack_future.owner == player.ME:
  96 + planet_score[planet_to_attack] = planet_to_attack_future.ship_count - ships_to_send + (prod_turns-distance)*planet_to_attack.growth_rate
  97 + break
  98 + if planet_score[planet_to_attack] > 0:
  99 + break
  100 + sorted_planets = sorted(self.universe.not_my_planets, key=lambda p : planet_score[p] + p.id/1000000.0, reverse=True)
  101 + result = sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  102 + filtered_result = []
  103 + for p in result:
  104 + if planet_score[p] > 0:
  105 + filtered_result.append(p)
  106 + for p in filtered_result:
  107 + if planet_score[p] > 0:
  108 + log.info("Score for %s is %s" % (p,planet_score[p]))
  109 +
  110 + log.info("Score eval done: %s planets" % len(result))
  111 + return filtered_result
  112 +
  113 + def weakest_not_my_planets_distance_based(self, count=1):
  114 + sorted_planets = sorted(self.universe.not_my_planets, \
  115 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count)/self.closest_my_planet_distance(p)+p.id/1000000.0, reverse=True)
  116 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  117 +
  118 + def total_fleet_count_enroute(self, owner, planet):
  119 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner, destination = planet) ] )
  120 +
  121 + def effective_fleet_ship_count_enroute(self, owner, planet):
  122 + result = 0
  123 + for fleet in self.universe.find_fleets(destination = planet):
  124 + if fleet.owner == owner:
  125 + result += fleet.ship_count
  126 + else:
  127 + result -= fleet.ship_count
  128 + return result
  129 +
  130 + def total_fleet_ship_count(self, owner):
  131 + return sum( [ fleet.ship_count for fleet in self.universe.find_fleets(owner) ] )
  132 +
  133 +
  134 + def weakest_not_my_planets_effective(self, count=1):
  135 + sorted_planets = sorted(self.universe.not_my_planets, \
  136 + key=lambda p : (1.0+p.growth_rate)/(1.0+p.ship_count-self.total_fleet_count_enroute(player.ME, p)+self.total_fleet_count_enroute(player.NOT_ME, p)) + p.id/1000000.0, reverse=True)
  137 + return sorted_planets[:count] if count < len(sorted_planets) else sorted_planets
  138 +
  139 + def invert_owner(self, owner):
  140 + if owner == player.ME:
  141 + return player.NOT_ME
  142 + else:
  143 + return player.ME
  144 +
  145 + # calculate how many ships are available or needed for each of my and enemy planets
  146 + def doPrep(self):
  147 + log.info("Prep phase")
  148 +
  149 + # calculate current high level metrics
  150 + self.my_total_ships_available = 0
  151 + self.my_total_ships = 0
  152 + self.my_total_growth_rate = 0
  153 + self.enemy_total_ships_available = 0
  154 + self.enemy_total_ships = 0
  155 + self.enemy_total_growth_rate = 0
  156 + self.ships_available = {}
  157 + self.ships_needed = {}
  158 + for planet in self.universe.my_planets | self.universe.enemy_planets:
  159 + if len(planet.attacking_fleets) == 0:
  160 + self.ships_available[planet] = planet.ship_count
  161 + self.ships_needed[planet] = 0
  162 + else:
  163 + simulation_distance = self.max_turns_remaining(planet.attacking_fleets | planet.reinforcement_fleets)
  164 + planet_timeline = planet.in_future_timeline(simulation_distance)
  165 + max_needed = 0
  166 + min_available = 1000000
  167 + log.info("timeline for %s: %s" % (planet, planet_timeline))
  168 + for step in planet_timeline:
  169 + owner = step[0]
  170 + ship_count = step[1]
  171 + if owner != planet.owner:
  172 + max_needed = max(max_needed, ship_count)
  173 + else:
  174 + min_available = min(min_available, ship_count)
  175 + if max_needed > 0:
  176 + # do we bail if we are going to lose this planet anyway?
  177 + self.ships_available[planet] = 0
  178 + self.ships_needed[planet] = max_needed
  179 + else:
  180 + self.ships_available[planet] = min_available
  181 + self.ships_needed[planet] = 0
  182 + if (planet.owner == player.ME):
  183 + self.my_total_ships_available += self.ships_available[planet]
  184 + self.my_total_growth_rate += planet.growth_rate
  185 + self.my_total_ships += planet.ship_count
  186 + else:
  187 + self.enemy_total_ships_available += self.ships_available[planet]
  188 + self.enemy_total_growth_rate += planet.growth_rate
  189 + self.enemy_total_ships += planet.ship_count
  190 + #log.info("avail ships for %s: %s" % (planet, self.ships_available[planet]))
  191 +
  192 +
  193 +
  194 + self.my_total_ships += self.total_fleet_ship_count(player.ME)
  195 + self.enemy_total_ships += self.total_fleet_ship_count(player.NOT_ME)
  196 +
  197 + # calculate enemy's center of mass
  198 + weighted_x = 0
  199 + weighted_y = 0
  200 + div = 0
  201 + for planet in self.universe.enemy_planets:
  202 + weighted_x += planet.position.x * self.ships_available[planet]
  203 + weighted_y += planet.position.y * self.ships_available[planet]
  204 + div += self.ships_available[planet]
  205 + if div == 0:
  206 + div = 1
  207 +
  208 + self.enemy_com = Planet(self.universe, 666, weighted_x/div, weighted_y/div, 2, 0, 0)
  209 +
  210 + log.info("MY STATUS: %s/%s - %s available" % (self.my_total_ships, self.my_total_growth_rate, self.my_total_ships_available))
  211 + log.info("ENEMY STATUS: %s/%s - %s available" % (self.enemy_total_ships, self.enemy_total_growth_rate, self.enemy_total_ships_available))
  212 + log.info("ENEMY COM: %s, %s" % (self.enemy_com.position.x, self.enemy_com.position.y))
  213 +
  214 + def doDefense(self):
  215 + log.info("Defense phase")
  216 + prioritized_planets_to_defend = sorted(self.universe.my_planets, key=lambda p : p.growth_rate + p.id/1000000.0, reverse=True)
  217 + for planet_to_defend in prioritized_planets_to_defend:
  218 + if self.ships_needed[planet_to_defend] > 0:
  219 + current_ships_needed = self.ships_needed[planet_to_defend]
  220 + log.info("Planet %s needs %s ships!" % (planet_to_defend, current_ships_needed))
  221 + # send reinforcements from closest planets
  222 + my_closest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_defend) + p.id/1000000.0)
  223 +
  224 + for source in my_closest_planets:
  225 + if source.id != planet_to_defend.id and self.ships_available[source] > 0:
  226 + ships_to_send = min(current_ships_needed, self.ships_available[source])
  227 + source.send_fleet(planet_to_defend, ships_to_send)
  228 + self.ships_available[source] -= ships_to_send
  229 + self.ships_needed[planet_to_defend] -= ships_to_send
  230 + current_ships_needed -= ships_to_send
  231 + if current_ships_needed <= 0:
  232 + break
  233 +
  234 +
  235 + def doOffense(self):
  236 + log.info("Offense phase")
  237 + #weakest_planets = self.universe.weakest_planets(player.NOT_ME,10)
  238 + #weakest_planets = self.weakest_not_my_planets_effective(10)
  239 + weakest_planets = self.get_best_planets_to_attack(10,15,50)
  240 + #weakest_planets = self.weakest_not_my_planets_distance_based(10)
  241 + #log.info("Weakest planets: %s" % weakest_planets)
  242 +
  243 + for planet_to_attack in weakest_planets:
  244 + log.info("Evaluating attack on %s" % planet_to_attack)
  245 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(planet_to_attack) + p.id/1000000.0)
  246 + for source in my_nearest_planets:
  247 + if self.ships_available[source] <= 0:
  248 + continue
  249 + attack_distance = source.distance(planet_to_attack)
  250 +
  251 + # see if we can steal
  252 + steal = False
  253 + if planet_to_attack.owner == player.NOBODY and self.enemy_fleets_attacking(planet_to_attack) == 1 and \
  254 + self.my_fleets_attacking(planet_to_attack) == 0:
  255 + enemy_fleet = list(self.universe.find_fleets(player.NOT_ME, destination = planet_to_attack))[0]
  256 + if attack_distance == (enemy_fleet.turns_remaining+1) and self.ships_available[source]>=(planet_to_attack.growth_rate+2) and \
  257 + enemy_fleet.ship_count == (planet_to_attack.ship_count+1):
  258 + log.info("Need to steal %s, fleet inbound %s" % (planet_to_attack,enemy_fleet))
  259 + steal = True
  260 + else:
  261 + continue
  262 +
  263 + if planet_to_attack.owner == player.NOBODY and \
  264 + steal == False and \
  265 + attack_distance > (self.closest_enemy_planet_distance(planet_to_attack) * ATTACK_PROXIMITY_RATIO):
  266 + continue
  267 +
  268 + simulation_distance = attack_distance
  269 + if planet_to_attack.owner == player.NOBODY:
  270 + simulation_distance = max(attack_distance, self.max_turns_remaining(planet_to_attack.attacking_fleets))
  271 + planet_to_attack_future = planet_to_attack.in_future(simulation_distance)
  272 + current_ships_needed = planet_to_attack_future.ship_count + 1
  273 + # we currently attack from a single planet within one move
  274 + log.info("Future eval for %s is %s, simul dist %s" % (planet_to_attack_future.owner,current_ships_needed, simulation_distance))
  275 + if planet_to_attack_future.owner != player.ME:
  276 + if planet_to_attack.owner == player.NOBODY:
  277 + if current_ships_needed <= self.ships_available[source]:
  278 + source.send_fleet(planet_to_attack, current_ships_needed)
  279 + self.ships_available[source] -= current_ships_needed
  280 + break
  281 + else:
  282 + if current_ships_needed <= self.ships_available[source]:
  283 + source.send_fleet(planet_to_attack, current_ships_needed)
  284 + self.ships_available[source] -= current_ships_needed
  285 + break
  286 +
  287 + def doPostOffense(self):
  288 + log.info("Post-Offense phase")
  289 + if len(self.universe.enemy_planets) == 0:
  290 + return
  291 +
  292 + # cache closest and com enemy planet distances
  293 + closest_enemy_planet_distance_map = {}
  294 + com_enemy_planet_distance_map = {}
  295 + for planet in self.universe.my_planets:
  296 + closest_enemy_planet_distance_map[planet] = self.closest_enemy_planet_distance(planet)
  297 + com_enemy_planet_distance_map[planet] = self.com_enemy_planet_distance(planet)
  298 +
  299 + for source_planet in self.universe.my_planets:
  300 + if self.ships_available[source_planet] > 0:
  301 + log.info("Post-Offense for %s" % source_planet)
  302 + my_nearest_planets = sorted(self.universe.my_planets, key=lambda p : p.distance(source_planet) + p.id/1000000.0)
  303 + for dest_planet in my_nearest_planets:
  304 + distance = source_planet.distance(dest_planet)
  305 + if distance > 0 and closest_enemy_planet_distance_map[dest_planet] <= closest_enemy_planet_distance_map[source_planet]:
  306 + if com_enemy_planet_distance_map[dest_planet] < com_enemy_planet_distance_map[source_planet]:
  307 + source_planet.send_fleet(dest_planet, self.ships_available[source_planet])
  308 + self.ships_available[source_planet] = 0
  309 + break
  310 +
  311 +
  312 + def do_turn(self):
  313 + if len(self.universe.my_planets) == 0 or len(self.universe.enemy_planets) == 0:
  314 + return
  315 +
  316 + self.doPrep()
  317 + self.doDefense()
  318 + self.doOffense()
  319 + self.doPostOffense()
  320 +
  321 +
  322 +Game(MyBot, universe_class=Universe2, planet_class=Planet2)
51 batch.sh
... ... @@ -0,0 +1,51 @@
  1 +#!/bin/bash
  2 + for file in example_bots/*.jar
  3 +
  4 + do
  5 + player_1_counter=0
  6 + player_1_turn_counter=0
  7 +
  8 + player_2_counter=0
  9 + player_2_turn_counter=0
  10 +
  11 + draw_counter=0
  12 +
  13 + maps_played=0
  14 +
  15 + echo "Bot: $file"
  16 + for i in {1..100}
  17 + do
  18 + RES=`java -jar tools/PlayGame.jar maps/map$i.txt 1000 200 log.txt "java -jar $file" "python MyBot.py" 2>&1 | tail -n 3 | grep "Turn\|Player"`
  19 +
  20 + TURN=`echo $RES | grep -i turn | sed 's/.*urn \([0-9]*\).*/\1/'`
  21 +
  22 + RES2=`echo $RES | grep -i player | sed 's/.*ayer \([0-9]*\).*/\1/'`
  23 +
  24 + if [ "$RES2" = "1" ] ; then
  25 + player_1_counter=`expr $player_1_counter + 1`
  26 + player_1_turn_counter=`expr $player_1_turn_counter + $TURN`
  27 + else
  28 + if [ "$RES2" = "2" ] ; then
  29 + player_2_counter=`expr $player_2_counter + 1`
  30 + player_2_turn_counter=`expr $player_2_turn_counter + $TURN`
  31 + else
  32 + draw_counter=`expr $draw_counter + 1`
  33 + fi
  34 + fi
  35 +
  36 + maps_played=`expr $maps_played + 1`
  37 + #echo "map: $i - Winner: $RES2 - Turns: $TURN"
  38 + #sleep 1
  39 + done
  40 + if [ "$player_2_counter" != "0" ] ; then
  41 + avg_player_2_turn_counter=`expr $player_2_turn_counter / $player_2_counter`
  42 + fi
  43 + if [ "$player_1_counter" != "0" ] ; then
  44 + avg_player_1_turn_counter=`expr $player_1_turn_counter / $player_1_counter`
  45 + fi
  46 +
  47 +
  48 + echo "won against $file : $player_2_counter/$maps_played, avg turns: $avg_player_2_turn_counter"
  49 + echo "lost against $file : $player_1_counter/$maps_played, avg turns: $avg_player_1_turn_counter"
  50 + echo "tied against $file : $draw_counter/$maps_played"
  51 + done
51 best_batch.sh
... ... @@ -0,0 +1,51 @@
  1 +#!/bin/bash
  2 + for file in MyBot_85_*.py
  3 +
  4 + do
  5 + player_1_counter=0
  6 + player_1_turn_counter=0
  7 +
  8 + player_2_counter=0
  9 + player_2_turn_counter=0
  10 +
  11 + draw_counter=0
  12 +
  13 + maps_played=0
  14 +
  15 + echo "Bot: $file"
  16 + for i in {1..100}
  17 + do
  18 + RES=`java -jar tools/PlayGame.jar maps/map$i.txt 10000 200 log.txt "python MyBot_82.py" "python $file" 2>&1 | tail -n 3 | grep "Turn\|Player"`
  19 +
  20 + TURN=`echo $RES | grep -i turn | sed 's/.*urn \([0-9]*\).*/\1/'`
  21 +
  22 + RES2=`echo $RES | grep -i player | sed 's/.*ayer \([0-9]*\).*/\1/'`
  23 +
  24 + if [ "$RES2" = "1" ] ; then
  25 + player_1_counter=`expr $player_1_counter + 1`
  26 + player_1_turn_counter=`expr $player_1_turn_counter + $TURN`
  27 + else
  28 + if [ "$RES2" = "2" ] ; then
  29 + player_2_counter=`expr $player_2_counter + 1`
  30 + player_2_turn_counter=`expr $player_2_turn_counter + $TURN`
  31 + else
  32 + draw_counter=`expr $draw_counter + 1`
  33 + fi
  34 + fi
  35 +
  36 + maps_played=`expr $maps_played + 1`
  37 + #echo "map: $i - Winner: $RES2 - Turns: $TURN"
  38 + sleep 1
  39 + done
  40 + if [ "$player_2_counter" != "0" ] ; then
  41 + avg_player_2_turn_counter=`expr $player_2_turn_counter / $player_2_counter`
  42 + fi
  43 + if [ "$player_1_counter" != "0" ] ; then
  44 + avg_player_1_turn_counter=`expr $player_1_turn_counter / $player_1_counter`
  45 + fi
  46 +
  47 +
  48 + echo "won against $file : $player_2_counter/$maps_played, avg turns: $avg_player_2_turn_counter"
  49 + echo "lost against $file : $player_1_counter/$maps_played, avg turns: $avg_player_1_turn_counter"
  50 + echo "tied against $file : $draw_counter/$maps_played"
  51 + done
63 parse_game_state_url.py
... ... @@ -0,0 +1,63 @@
  1 +import sys
  2 +import urllib2
  3 +
  4 +"""Code, with no error checking, to parse a PlanetWars game into
  5 + a replayable code file. Argument is game page URL."""
  6 +def main(argv):
  7 + input_url = argv[0]
  8 + req = urllib2.Request(input_url)
  9 + response = urllib2.urlopen(req)
  10 + s = response.read()
  11 + PLAYBACK_START = "playback_string="
  12 + PLAYBACK_END = "\\n"
  13 + start_index = s.find(PLAYBACK_START) + len(PLAYBACK_START)
  14 + end_index = s.find(PLAYBACK_END, start_index)
  15 + if end_index == -1:
  16 + end_index = s.find('"', start_index)
  17 + s = s[start_index:end_index]
  18 + planets, moves = s.split("|")
  19 +
  20 + data = []
  21 + for p in planets.split(":"):
  22 + line = p.split(",")
  23 + if len(line) != 5:
  24 + print "bad line: %s" % p
  25 + x,y,o,n,r = line
  26 + data.append(line)
  27 +
  28 + np = len(data)
  29 +
  30 + moves = moves.split(":")
  31 +
  32 + print("# turn 1")
  33 + for i in xrange(np):
  34 + x,y,o,n,r = data[i]
  35 + print("P %s %s %s %s %s" % (x,y,o,n,r))
  36 + print("go\n")
  37 +
  38 + for (turn,f) in enumerate(moves):
  39 + print("# turn: %d" % (turn + 2))
  40 + xs = f.split(",")
  41 + for i in xrange(np):
  42 + x,y,o,n,r = data[i]
  43 + tmp = xs[i].strip().split(".")
  44 + if len(tmp) < 2:
  45 + print "error here: ", xs[i]
  46 + break
  47 + o,n = tmp
  48 + print("P %s %s %s %s %s" % (x,y,o,n,r))
  49 + for j in xrange(np,len(xs)):
  50 + u = xs[j].split(".")
  51 + if len(u) != 6:
  52 + #print "er: ", xs[j]
  53 + continue
  54 + o,n,s,d,t,r = u
  55 + print("F %s %s %s %s %s %s" % (o,n,s,d,t,r))
  56 + print("go\n")
  57 +
  58 +if __name__ == "__main__":
  59 + argv = sys.argv[1:]
  60 + main(argv)
  61 +
  62 +
  63 +
3  prev.sh
... ... @@ -0,0 +1,3 @@
  1 +#!/bin/bash
  2 +
  3 +java -jar tools/PlayGame.jar maps/map$1.txt 10000 200 log.txt "python MyBot_82.py --log old.log" "python MyBot.py --log current.log" | python visualizer/visualize_localy.py
6 replay.sh
... ... @@ -0,0 +1,6 @@
  1 +#!/bin/bash
  2 +# Re-playes the game by parsing it from a web page such as http://ai-contest.com/visualizer.php?game_id=4607884
  3 +# pass game URL as a parameter to this script
  4 +
  5 +python parse_game_state_url.py $1 | python MyBot.py --log MyBot.log
  6 +

0 comments on commit 0091192

Please sign in to comment.
Something went wrong with that request. Please try again.