### Subversion checkout URL

You can clone with HTTPS or Subversion.

commit 0091192e924ebf7c38cfd46e8cae2d57cdcb26fa 1 parent 85d92c8
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 +