def play(self, turn, pid, planets, fleets): my_planets, their_planets, _ = aggro_partition(pid, planets) destination = min(their_planets, key=get_ships) orders = [] for planet in my_planets: orders.append(Order(planet, destination, planet.ships * 0.75)) return orders
def strong_to_weak(turn, pid, planets, fleets, train): my_planets, their_planets, _ = aggro_partition(pid, planets) if len(my_planets) == 0 or len(their_planets) == 0: return [] my_strongest = max(my_planets, key=get_ships) their_weakest = min(their_planets, key=get_ships) return [Order(my_strongest, their_weakest, my_strongest.ships * 0.75)]
def play(self, turn, pid, planets, fleets): def mine(x): return x.owner == pid my_planets, other_planets = partition(mine, planets) source = random.choice(my_planets) destination = random.choice(other_planets) return [Order(source, destination, source.ships / 2)]
def all_to_weak(turn, pid, planets, fleets, train): my_planets, their_planets, _ = aggro_partition(pid, planets) if len(my_planets) == 0 or len(their_planets) == 0: return [] destination = min(their_planets, key=get_ships) orders = [] for planet in my_planets: orders.append(Order(planet, destination, planet.ships * 0.75)) return orders
def __call__(self, turn, pid, planets, fleets, train): def mine(x): return x.owner == pid my_planets, other_planets = partition(mine, planets) if len(my_planets) == 0 or len(other_planets) == 0: return [] source = random.choice(my_planets) destination = random.choice(other_planets) return [Order(source, destination, source.ships / 2)]
def play(self, turn, pid, planets, fleets): my_planets, their_planets, neutral_planets = aggro_partition( pid, planets) other_planets = their_planets + neutral_planets their_weakest = min(their_planets, key=get_ships) my_total = sum(map(get_ships, my_planets)) destination = min(their_planets, key=get_ships) orders = [] for planet in my_planets: if random.random() < 0.5: def dist_to(other_planet): return turn_dist(planet, other_planet) closest = min(other_planets, key=dist_to) orders.append(Order(planet, closest, planet.ships * 0.75)) else: orders.append(Order(planet, their_weakest, planet.ships * 0.75)) return orders
def gships(pid, planet_data, cluster_data, t_dist, t_max, data, turn, train, planets, fleets, game_ratios): ''' Calculates the number of ships the cluster needs to send in order to capture/help the planet @param pid: player id @type: int @param planet_data: the planet to send the ships to with data e.g. planet_data['planet'] - return the ImmutablePlanet object @type: {'planet' : p, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0} @param cluster_data: Combined data of all planets that belong to this cluster e.g. cluster_data['cluster'] - return the cluster of [ImmutablePlanet] objects @type: {'cluster' : cluster, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0} @param t_dist: turn distance between planet and cluster (approximation / take max) @type: int @param t_max: max turn distance on the map @type: int @param data: dictionary of all planets information. Each inner dictionary value is accesed using a planet as key e.g. data[key][planet.id][t_max] - key = 'value' | 'value_d' data[key][planet.id] - key = 'influence_' + 'f' | 'e' | 'f_d' | 'e_d' @type: {'value' : {}, 'value_d' : {}, 'influence_f' : {}, 'influence_e' : {}, 'influence_f_d' : {}, 'influence_e_d' : {}} ''' # input data sanity check assert isinstance(pid, int) assert isinstance(planet_data, dict) assert isinstance(cluster_data, dict) assert isinstance(t_dist, int) assert isinstance(t_max, int) assert isinstance(data, dict) # -------------------------------------------------------------------- orders = [] ships_needed_to_send = data['value'][planet_data['planet'].id][t_dist] all_ships = 0.0 p_ships = {} for p in cluster_data['cluster']: all_ships += p.ships p_ships[p] = p.ships if all_ships < ships_needed_to_send: return orders percentage = ships_needed_to_send / all_ships for p in cluster_data['cluster']: orders.append( Order(p, planet_data['planet'], round(p.ships * percentage) + 1)) # we need to return an array of Order objects. The array can be empty. return orders
def GetOrderToPointToRootStateObjects(self, order): src = des = None for ps in self.rootplanets: if order.source.id == ps.id: src = ps for pd in self.rootplanets: if order.destination.id == pd.id: des = pd assert src is not None and des is not None, "Can't find planet in GetOrderToPointToRootStateObjects()" #self.PrintRootUniverse() #print Order(src, des, order.ships) return Order(src, des, order.ships)
def __call__(self, turn, pid, planets, fleets): self.pid = pid my_planets, other_planets = partition(lambda x: x.owner == pid, planets) sf = self.make_state_features(planets, fleets) self.last_state = [0] * (8 + 2 * DQN.buckets) if len(my_planets) == 0 or len(other_planets) == 0: return [] if random.random() < self.eps or len(DQN.memory) < DQN.mem_size: src, dst = random.choice(my_planets), random.choice(planets) else: src, dst = self.make_smart_move(planets, fleets, sf) # if the state was not 'no source' self.last_state = self.make_features(src, dst, *sf) if src == dst: return [] return [Order(src, dst, src.ships / 2)]
def GetMoves(self): """ Get all possible moves from this state. """ def mine(x): return x.owner == self.pid my_planets, other_planets = partition(mine, self.planets) res = [] for src in my_planets: for dst in other_planets: if dst.ships < src.ships / 2: res.append(Order(src, dst, src.ships / 2)) if len(res) == 0 and len(my_planets) > 0 and len(other_planets) > 0: res.append(None) ## src = max(my_planets, key=get_ships) ## dst = min(other_planets, key=get_ships) ## res.append(Order(src, dst, src.ships / 2)) return res
def select_move(pid, planets, fleets): assert pid == 1 or pid == 2, "what?" my_planets, other_planets = partition(lambda x: x.owner == pid, planets) your_planets, neutral_planets = partition(lambda x: x.owner != 0, other_planets) if len(my_planets) == 0: return [] # for i,p in enumerate(planets): # print "PLANET: ", i, p.id, "x=", p.x, "y=", p.y, p.owner, p.ships # weights wv = [ +3.0, # src ships -1.25, # dest ships +0.0, # my ships total +0.0, # your ships total +0.0, # neutral ship total +0.0, # my total growth +0.0, # your total growth -6.0, # distance , was -1.5 +0.0, # I own dest planet +30.0, # opponent owns dest planet +5, # neutral owns dest planet -1.0, # src growth +2.0, # dest growth ] # incoming ship buckets buckets = 10 weight_bucket = 2 # src incoming ship buckets for i in range(buckets): wv.append(-(i + 1) * weight_bucket) #wv.append(weight_bucket/(1+i)) #wv.append(-i*0.5) # dst incoming ship buckets for i in range(buckets): wv.append(-(i + 1) * weight_bucket) #wv.append(weight_bucket/(1+i)) #wv.append(-i*0.5) my_ships_total = 0 your_ships_total = 0 neutral_ships_total = 0 my_growth = 0 your_growth = 0 # tally ships and growth for p in planets: if p.id == 0: neutral_ships_total += p.ships elif p.id == pid: my_growth += p.growth my_ships_total += p.ships else: your_ships_total += p.ships your_growth += p.growth # compute maximal distance between planets max_dist = 0 for src in planets: for dst in planets: d = dist(src, dst) if d > max_dist: max_dist = d # incoming ship bucket matrix # incoming friendly ships count 1, incoming enemy ships count -1 # for each planet we tally incoming ship for time buckets 0..buckets-1 # where buckets refers to the maximum distance on the map tally = numpy.zeros((len(planets), buckets)) for f in fleets: # d = remaining distance d = dist(planets[f.source], planets[f.destination]) * \ (f.remaining_turns/f.total_turns) b = d / max_dist * buckets if b >= buckets: b = buckets - 1 tally[f.destination, b] += f.ships * (1 if f.owner == pid else -1) best_sum = float("-inf") best_orders = [] for src in my_planets: for dst in planets: if src == dst: continue fv = [] # planet totals fv.append(src.ships) fv.append(dst.ships) # ship total fv.append(my_ships_total) fv.append(your_ships_total) fv.append(neutral_ships_total) # growth fv.append(my_growth) fv.append(your_growth) # distance d = dist(src, dst) #print "PLANET DIST: ", src, dst #print "DIST: ", src.id, dst.id, d fv.append(d) # I own dst planet fv.append(1 if dst.id == pid else 0) # you own dst planet fv.append(1 if dst.id != 0 and dst.id != pid else 0) # neutral owns dst planet fv.append(1 if dst.id == 0 else 0) # growth fv.append(src.growth) fv.append(dst.growth) # incoming ship buckets (src) # print "incoming src", src.id, ": ", for i in range(buckets): fv.append(tally[src.id, i]) # print i, tally[src.id, i], #print # incoming ship buckets (dst) # print "incoming dst", dst.id, ": ", for i in range(buckets): fv.append(tally[dst.id, i]) #print tally[dst.id, i], #print assert len(fv) == len(wv), "lengths disagree " + str( len(fv)) + " " + str(len(wv)) # compute value (weights * features) sum = 0 for i, f in enumerate(fv): sum += f * wv[i] # print "Agent2: ", src.id, dst.id, sum # update best action (use tie-breaker?) if sum >= best_sum: if sum > best_sum: best_orders = [] best_sum = sum # best_orders.append(Order(src, dst, src.ships/2)) best_orders.append(Order(src, dst, src.ships * 0.45)) # print "#ORDERS: ", len(best_orders), best_order = random.choice(best_orders) #if best_order.source == best_order.destination: # print "SAME PLANET!" #print # print "AgentTest2: ", best_order return [best_order]
def select_move(pid, planets, fleets): assert pid == 1 or pid == 2, "what?" my_planets, other_planets = partition(lambda x: x.owner == pid, planets) if len(my_planets) == 0 or len(other_planets) == 0: return [] your_planets, neutral_planets = partition(lambda x: x.owner != 0, other_planets) # for i,p in enumerate(planets): # print "PLANET: ", i, p.id, "x=", p.x, "y=", p.y, p.owner, p.ships buckets = 10 # evolved from manually tuned parameters (agenttest.py) # much better! wv = [0.86775324593161407, -1.9010099177760116, 0.70433224708478814, 0.38139294338347268, 0.54156215783780215, -0.26850400844879657, 0.036186433238020135, -2.4578285185718509, -0.22894880101333545, 8.6048706141753843, 5.9310406603617754, -1.7418715081600573, 1.7733665060956196, 0.75099526122482629, -0.24516344621926955, -0.58245534282527744, -1.9683307387551237, -4.5097072412766952, -3.3414734358820031, -1.6702149156291219, -2.8390520001774457, -5.380093894197751, -5.3042483457349077, -1.4015940841792449, -0.8879621041490966, -2.3146041377067901, -0.75674029604322557, -2.194825427869195, -2.7245477291943003, -3.5719201691901739, -3.9302814137729709, -3.6712154408545712, -5.9446914488922378] # Friday Morning: # wv = [0.87228527101416398, -0.79126636923666871, # -0.34114544122826324, -1.2090512361564403, 1.4031361661285386, # 0.73674878406987754, -0.516640269495791, -3.1994083525469721, # -0.5745394282397579, -0.22981889285018697, -1.417569495893277, # -2.259612849650309, -1.417122273379628, 0.22398736570314653, # 1.1025017800623469, -2.3399564135382556, 0.46038305190135953, # -0.19313043611744043, 0.83489567169438406, -0.52030771008719445, # 1.5391963665964257, -0.87786985834090447, 1.2020126747923154, # 0.72289829744304113, -1.2814151831330289, 1.3404938004129179, # -0.58430476934010023, -2.2650232722412449, -0.47874802835808361, # -1.0517218313694681, -0.1941961917394518, -1.110827613720589, # -1.543892566692554] my_ships_total = 0 your_ships_total = 0 neutral_ships_total = 0 my_growth = 0 your_growth = 0 # tally ships and growth for p in planets: if p.id == 0: neutral_ships_total += p.ships elif p.id == pid: my_growth += p.growth my_ships_total += p.ships else: your_ships_total += p.ships your_growth += p.growth # compute maximal distance between planets max_dist = 0 for src in planets: for dst in planets: d = dist(src, dst) if d > max_dist: max_dist = d # incoming ship bucket matrix # incoming friendly ships count 1, incoming enemy ships count -1 # for each planet we tally incoming ship for time buckets 0..buckets-1 # where buckets refers to the maximum distance on the map tally = numpy.zeros((len(planets), buckets)) for f in fleets: # d = remaining distance d = dist(planets[f.source], planets[f.destination]) * \ (f.remaining_turns/f.total_turns) b = d/max_dist * buckets if b >= buckets: b = buckets-1 tally[f.destination, b] += f.ships * (1 if f.owner == pid else -1) best_sum = float("-inf") best_orders = [] for src in my_planets: for dst in planets: if src == dst: continue fv = [] # planet totals fv.append(src.ships) fv.append(dst.ships) # ship total fv.append(my_ships_total) fv.append(your_ships_total) fv.append(neutral_ships_total) # growth fv.append(my_growth) fv.append(your_growth) # distance d = dist(src, dst) #print "PLANET DIST: ", src, dst #print "DIST: ", src.id, dst.id, d fv.append(d) # I own dst planet fv.append(1 if dst.id == pid else 0) # you own dst planet fv.append(1 if dst.id != 0 and dst.id != pid else 0) # neutral owns dst planet fv.append(1 if dst.id == 0 else 0) # growth fv.append(src.growth) fv.append(dst.growth) # incoming ship buckets (src) # print "incoming src", src.id, ": ", for i in range(buckets): fv.append(tally[src.id, i]) # print i, tally[src.id, i], #print # incoming ship buckets (dst) # print "incoming dst", dst.id, ": ", for i in range(buckets): fv.append(tally[dst.id, i]) #print tally[dst.id, i], #print assert len(fv) == len(wv), "lengths disagree " + str(len(fv)) + " " + str(len(wv)) # compute value (weights * features) sum = 0 for i,f in enumerate(fv): sum += f*wv[i] # print "Agent2: ", src.id, dst.id, sum # update best action (use tie-breaker?) if sum >= best_sum: if sum > best_sum: best_orders = [] best_sum = sum best_orders.append(Order(src, dst, src.ships/2)) # print "#ORDERS: ", len(best_orders), best_order = random.choice(best_orders) #if best_order.source == best_order.destination: # print "SAME PLANET!" #print # print "AgentTest: ", best_order return [best_order]
def play(self, turn, pid, planets, fleets): my_planets, their_planets, _ = aggro_partition(pid, planets) my_strongest = max(my_planets, key=get_ships) their_weakest = min(their_planets, key=get_ships) return [Order(my_strongest, their_weakest, my_strongest.ships * 0.75)]
def __call__(self, turn, pid, planets, fleets): i = 1 sumparams = 0 while i < 11: sumparams += self.hotshot_params[i] i += 1 if sumparams > 1 - self.hotshot_params[12]: #print "adapt params", sumparams, self.hotshot_params[12] factor = (1 - self.hotshot_params[12]) / sumparams i = 1 while i < 11: self.hotshot_params[i] *= factor i += 1 my_planets, their_planets, neutral_planets = aggro_partition( pid, planets) orders = [] docked = 0 flying = 0 for planet in my_planets: docked += planet.ships for fleet in fleets: if fleet.owner == pid: flying += fleet.ships if flying + docked > 0: if float(flying) / float(flying + docked) > self.hotshot_params[11]: return [] for planet in my_planets: if planet.ships < self.hotshot_params[0] * 100: continue def dist_to(other_planet): return turn_dist(planet, other_planet) def highgrowth_of(other_planet): return other_planet.growth * 1000 - turn_dist( planet, other_planet) def lowgrowth_of(other_planet): return other_planet.growth * 1000 + turn_dist( planet, other_planet) def ease_of(other_planet): return other_planet.ships * 1000 + turn_dist( planet, other_planet) if len(neutral_planets) > 0: if self.hotshot_params[1] > 0: closest = min(neutral_planets, key=dist_to) orders.append( Order(planet, closest, planet.ships * self.hotshot_params[1])) if self.hotshot_params[2] > 0: high_growth = max(neutral_planets, key=highgrowth_of) orders.append( Order(planet, high_growth, planet.ships * self.hotshot_params[2])) if self.hotshot_params[3] > 0: low_growth = min(neutral_planets, key=lowgrowth_of) orders.append( Order(planet, high_growth, planet.ships * self.hotshot_params[3])) if self.hotshot_params[4] > 0: any = neutral_planets[random.randint( 0, len(neutral_planets) - 1)] orders.append( Order(planet, any, planet.ships * self.hotshot_params[4])) if self.hotshot_params[5] > 0: easy = min(neutral_planets, key=ease_of) orders.append( Order(planet, easy, planet.ships * self.hotshot_params[5])) if len(their_planets) > 0: if self.hotshot_params[6] > 0: closest = min(their_planets, key=dist_to) orders.append( Order(planet, closest, planet.ships * self.hotshot_params[6])) if self.hotshot_params[7] > 0: high_growth = max(their_planets, key=highgrowth_of) orders.append( Order(planet, high_growth, planet.ships * self.hotshot_params[7])) if self.hotshot_params[8] > 0: low_growth = min(their_planets, key=lowgrowth_of) orders.append( Order(planet, high_growth, planet.ships * self.hotshot_params[8])) if self.hotshot_params[9] > 0: any = their_planets[random.randint(0, len(their_planets) - 1)] orders.append( Order(planet, any, planet.ships * self.hotshot_params[9])) if self.hotshot_params[10] > 0: easy = min(their_planets, key=ease_of) orders.append( Order(planet, easy, planet.ships * self.hotshot_params[10])) return orders
def gships(pid, planet_data, clustr_data, t_dist, t_max, data, turn, train, planets, fleets, game_metrics): ''' Calculates the number of ships the cluster needs to send in order to capture/help the planet @param pid: player id @type: int @param planet_data: the planet to send the ships to with data @type: {'planet' : p, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0} @param cluster_data: Combined data of all planets that belong to this cluster @type: {'cluster' : cluster, 'value' : 0.0, 'value_d' : 0.0, 'influence_f' : 0.0, 'influence_e' : 0.0, 'influence_f_d' : 0.0, 'influence_e_d' : 0.0} @param t_dist: turn distance between planet and cluster (approximation / take max) @type: int @param t_max: max turn distance on the map @type: int @param data: dictionary of all planets information. Each inner dictionary value is accesed using a planet as key e.g. data[key][planet.id][t_max] - key = 'value' | 'value_d' data[key][planet.id] - key = 'influence_' + 'f' | 'e' | 'f_d' | 'e_d' @type: {'value' : {}, 'value_d' : {}, 'influence_f' : {}, 'influence_e' : {}, 'influence_f_d' : {}, 'influence_e_d' : {}} ''' # input data sanity check assert isinstance(pid, int) assert isinstance(planet_data, dict) assert isinstance(clustr_data, dict) assert isinstance(t_dist, int) assert isinstance(t_max, int) assert isinstance(data, dict) # -------------------------------------------------------------------- # create relation value 1 / 0.5 / 0 depending of the planet is neutral / friendly / enemy cluster_planet_relationship = 0.0 if pid == planet_data['planet'].owner: cluster_planet_relationship = 0.5 elif planet_data['planet'].owner == 0: cluster_planet_relationship = 1 # +1 to avoid division by 0 # we send data as ratios (planet under cluster) # all values are between 0 and 1; except "owner" and "t_dist" input = [# cluster data clustr_data['ships'], clustr_data['growth'], clustr_data['value'], #clustr_data['value_d'], clustr_data['influence_f'], clustr_data['influence_e'], clustr_data['influence_f_m'], clustr_data['influence_e_m'], #clustr_data['influence_f_md'], #clustr_data['influence_e_md'], # planet data planet_data['ships'], planet_data['growth'], planet_data['value'], #planet_data['value_d'], planet_data['influence_f'], planet_data['influence_e'], planet_data['influence_f_m'], planet_data['influence_e_m'], #planet_data['influence_f_md'], #planet_data['influence_e_md'], game_metrics['growth_r'], # overall growth ratio game_metrics['growth_er'], # overall growth ratio enemy game_metrics['ships_r'], # overall ship ratio cluster_planet_relationship, # read above for details t_dist / float(t_max)] assert not any(numpy.isnan(in_) or numpy.isinf(in_) for in_ in input) input_np = numpy.array(input, ndmin=2, dtype=config.floatX) # two output values. # 1. The certainty of this attack / help # 2. the percentage og ships to send from the cluster out_np = NNetwork.gships.predict(input_np, batch_size = 1) out = out_np[0][0] # reformat the output data assert not (numpy.isnan(out) or numpy.isinf(out)) orders = [] for p in clustr_data['cluster']: orders.append(Order(p, planet_data['planet'], int(p.ships / 2))) # if we are training, add pattern pattern = None if train: pattern = { 'in' : input_np, 'out' : out_np, 'reward' : 0.0, 'in_' : None, 'terminal' : False} # we need to return an array of Order objects. The array can be empty. return (out, orders, pattern, t_dist, planet_data['value'])