def get_distance_dictionary(): dist_dict = {} for i in range(game_map.width): for j in range(game_map.height): pos = positionals.Position(i, j) dist_dict[(i, j)] = game_map.calculate_distance( me.shipyard.position, positionals.Position(i, j)) return dist_dict
def get_target(self, scope): halite_list = [] for x in range(self.game_map.width): for y in range(self.game_map.height): halite_list.append( (positionals.Position(x, y), self.game_map[positionals.Position(x, y)].halite_amount)) sorted_list = sorted(halite_list, key=lambda t: t[1]) top_targets = sorted_list[-10:-1] return random.choice(top_targets)[0]
def get_halite_dictionary(): halite_dict = {} for i in range(game_map.width): for j in range(game_map.height): pos = positionals.Position(i, j) halite_dict[(i, j)] = game_map[pos].halite_amount return halite_dict
def get_attack_list(): atck_list = [] for i in range(game_map.width): for j in range(game_map.height): pos = positionals.Position(i, j) if game_map[pos].has_structure and pos != me.shipyard.position: atck_list.append((i, j)) return atck_list
def input_for_ship(self, game_map, ship, my_other_ships, other_ships, my_dropoffs, other_dropoffs, turn_number, rotation=0): #output: input training data N=10; nearbyhalite = np.zeros((2*N+1,2*N+1)); nearbymyship= np.zeros((2*N+1,2*N+1)); nearbyenemyship= np.zeros((2*N+1,2*N+1)); for i in range(ship.position.x-N,ship.position.x+N): for j in range(ship.position.y-N,ship.position.y+N): nearbyhalite[i-(ship.position.x-N)][j-(ship.position.x-N)]=game_map[game_map.normalize(positionals.Position(i,j))].halite_amount; myshippos=set(); for myship in my_other_ships: myshippos.add(my_other_ships); for i in range(ship.position.x-N,ship.position.x+N): for j in range(ship.position.y-N,ship.position.y+N): if game_map.normalize(positionals.Position(i,j)) in myshippos: nearbymyship[i-(ship.position.x-N)][j-(ship.position.x-N)]=1; enemyship=set(); for othership in other_ships: enemyship.add(othership.position); for i in range(ship.position.x-N,ship.position.x+N): for j in range(ship.position.y-N,ship.position.y+N): if game_map.normalize(positionals.Position(i,j)) in enemyship: nearbyenemyship[i-(ship.position.x-N)][j-(ship.position.x-N)]=1; wid = game_map.width if wid == 56: maxturn = 476 if wid == 40: maxturn = 426 if wid == 32: maxturn= 401 if wid == 64: maxturn= 501 if wid == 48: maxturn = 451 #get relative coordinate of nearest dropoff site for dropoff in my_dropoffs(): dis2 = game_map.calculate_distance(ship.position, dropoff.position); if dis > dis2: dis = dis2 tarx = dropoff.position.x-ship.position.x tary = dropoff.position.y-ship.position.y #periodic boundary condition if tarx>wid/2:tarx=tarx-wid; if tarx<-wid/2:tarx=tarx+wid; if tary>wid/2:tary=tary-wid; if tary<-wid/2:tary=tary+wid; return [nearbyhalite,nearbyenemyship,nearbymyship,turn_number,maxturn,ship.halite_amount,tarx,tary]
def get_most_halite(ship): if ship.id in standing_farming_orders: if ship.position == positionals.Position(standing_farming_orders[ship.id][0], standing_farming_orders[ship.id][1]) and game_map[ship.position].halite_amount < constants.MAX_HALITE / 10: del standing_farming_orders[ship.id] if ship.id in standing_farming_orders: return positionals.Position(standing_farming_orders[ship.id][0], standing_farming_orders[ship.id][1],) else: a = get_efficient_halite() ord = True while ord: b = max(a, key=a.get) if b in standing_farming_orders.values(): del a[b] else: ord = False pos = positionals.Position(b[0], b[1]) standing_farming_orders[ship.id] = b return pos '''
def _find_dropoff_destination(self): me = self.game.me game_map = self.game.game_map radii = 32 def check_sparsity(pos): for dropoff_location in self.dropoff_locations: dist = game_map.calculate_distance(pos, dropoff_location) if dist < 12: return False return True def check_halite_density(pos, width=6): halite_amount = 0 for i in range(-round(width / 2), round(width / 2), 1): for j in range(-round(width / 2), round(width / 2), 1): curr_cell = game_map[new_pos] curr_halite_amount = curr_cell.halite_amount halite_amount += curr_halite_amount return halite_amount destination = None best_halite_amount = -987654321 for i in range(-round(radii / 2), round(radii / 2), 1): for j in range(-round(radii / 2), round(radii / 2), 1): new_pos = game_map.normalize(me.shipyard.position + positionals.Position(i, j)) dist = game_map.calculate_distance(me.shipyard.position, new_pos) if dist < 12: continue # Skip the ones that are too close. halite_amount = check_halite_density(new_pos, width=6) if halite_amount > best_halite_amount and check_sparsity( new_pos): destination = new_pos best_halite_amount = halite_amount if destination: self.dropoff_locations.append(destination) return destination
def get_move_order(ship): if check_end_is_nigh() and ship_status[ship.id] != "attacking": a = game_map.get_unsafe_moves( ship.position, me.shipyard.position) next_move = a[0] return ship.move(next_move) elif ship_status[ship.id] == "attacking": if ship.id not in standing_attack_orders: standing_attack_orders[ship.id] = atck_list.pop() att_loc = standing_attack_orders[ship.id] att_pos = positionals.Position(att_loc[0], att_loc[1]) next_move = game_map.naive_navigate(ship, att_pos) logging.info("target is {}.".format(att_pos)) return ship.move(next_move) else: att_pos = positionals.Position( standing_attack_orders[ship.id][0], standing_attack_orders[ship.id][1]) next_move = game_map.naive_navigate(ship, att_pos) return ship.move(next_move) elif ship_status[ship.id] == "returning" or ship.is_full: next_move = game_map.naive_navigate(ship, me.shipyard.position) if ship.id in standing_farming_orders: del standing_farming_orders[ship.id] for enemy in enemy_ships: if game_map.calculate_distance(ship.position, me.shipyard.position) == 1: if enemy.position == me.shipyard.position: a = game_map.get_unsafe_moves( ship.position, me.shipyard.position) next_move = a[0] logging.info("DEFENDING!!!") return ship.move(next_move) if next_move == Direction.Still: if random.random() < 0.5: reroute = random.choice(cardinal_dir) rerouted_move = game_map.naive_navigate( ship, ship.position.directional_offset(reroute)) return ship.move(rerouted_move) return ship.move(next_move) else: return ship.move(next_move) elif ship_status[ship.id] == "exploring": if game_map[ship.position].halite_amount < constants.MAX_HALITE / 10: next_move = game_map.naive_navigate(ship, get_most_halite(ship)) if next_move == Direction.Still: reroute = random.choice(cardinal_dir) rerouted_move = game_map.naive_navigate( ship, ship.position.directional_offset(reroute)) return ship.move(rerouted_move) else: return ship.move(next_move) else: return ship.stay_still() elif ship_status[ship.id] == "start_exploring": next_move = game_map.naive_navigate(ship, get_most_halite(ship)) if next_move == Direction.Still: a = get_safe_moves(ship.position) if len(a) != 0: b = random.randint(0, len(a) - 1) next_move = game_map.naive_navigate( ship, ship.position.directional_offset(a[b])) return ship.move(next_move) else: next_move = random.choice( [Direction.North, Direction.South, Direction.East, Direction.West]) return ship.move(next_move) return ship.move(rerouted_move) else: return ship.move(next_move) else: logging.info("ERROR!!! {}.".format( ship_status[ship.id]))
def parse_replay_file(file_name): with open(file_name, 'rb') as f: data = json.loads(zstd.loads(f.read())) constants.set_dimensions(data["production_map"]["width"], data["production_map"]["height"]) player_id = int(file_name.split("-")[-1][:-4]) player_name = name_dict[player_id] if player_id in name_dict else None player = [p for p in data['players'] if " ".join(p['name'].split(" ")[:-1]) == player_name] if len(player) > 0: player = player[0] else: print(f"Skipping {file_name}") return [] player_id = int(player["player_id"]) my_shipyard = entity.Shipyard(player_id, ARBITRARY_ID, positionals.Position(player['factory_location']['x'], player['factory_location']['y'])) other_shipyards = [ entity.Shipyard(p['player_id'], ARBITRARY_ID, positionals.Position(p['factory_location']['x'], p['factory_location']['y'])) for p in data['players'] if int(p['player_id']) != player_id] width = data['production_map']['width'] height = data['production_map']['height'] first_cells = [] for x in range(len(data['production_map']['grid'])): row = [] for y in range(len(data['production_map']['grid'][x])): row += [game_map.MapCell(positionals.Position(x, y), data['production_map']['grid'][x][y]['energy'])] first_cells.append(row) frames = [] for f in data['full_frames']: prev_cells = first_cells if len(frames) == 0 else frames[-1]._cells new_cells = copy.deepcopy(prev_cells) for c in f['cells']: new_cells[c['y']][c['x']].halite_amount = c['production'] frames.append(game_map.GameMap(new_cells, width, height)) moves = [{} if str(player_id) not in f['moves'] else {m['id']: m['direction'] for m in f['moves'][str(player_id)] if m['type'] == "m"} for f in data['full_frames']] ships = [{} if str(player_id) not in f['entities'] else { int(sid): entity.Ship(player_id, int(sid), positionals.Position(ship['x'], ship['y']), ship['energy']) for sid, ship in f['entities'][str(player_id)].items()} for f in data['full_frames']] other_ships = [ {int(sid): entity.Ship(int(pid), int(sid), positionals.Position(ship['x'], ship['y']), ship['energy']) for pid, p in f['entities'].items() if int(pid) != player_id for sid, ship in p.items()} for f in data['full_frames']] first_my_dropoffs = [my_shipyard] first_them_dropoffs = other_shipyards my_dropoffs = [] them_dropoffs = [] for f in data['full_frames']: new_my_dropoffs = copy.deepcopy(first_my_dropoffs if len(my_dropoffs) == 0 else my_dropoffs[-1]) new_them_dropoffs = copy.deepcopy(first_them_dropoffs if len(them_dropoffs) == 0 else them_dropoffs[-1]) for e in f['events']: if e['type'] == 'construct': if int(e['owner_id']) == player_id: new_my_dropoffs.append( entity.Dropoff(player_id, ARBITRARY_ID, positionals.Position(e['location']['x'], e['location']['y']))) else: new_them_dropoffs.append( entity.Dropoff(e['owner_id'], ARBITRARY_ID, positionals.Position(e['location']['x'], e['location']['y']))) my_dropoffs.append(new_my_dropoffs) them_dropoffs.append(new_them_dropoffs) return list(zip(frames, moves, ships, other_ships, my_dropoffs, them_dropoffs))
def _search_surrounding(self, ship, radii, find_mine=False): """ Search within the radii for 1. # of enemies around me 2. sum of distance from the enemies 3. # of allies around me 4. sum of distance from the allies 5. sum of halites in the search area, 6. closest mine with acceptable amount of halites. and update ship_status """ me = self.game.me game_map = self.game.game_map num_enemies = 0 sum_dist_enemies = 0 num_allies = 0 sum_dist_allies = 0 sum_halites = 0 best_mine = None best_mine_distance = 987654321 best_net_profit = -987654321 best_amount = 0 home_pos = self.ship_status[ship.id][HOME].position curr_pos = ship.position for i in range(-round(radii / 2), round(radii / 2), 1): for j in range(-round(radii / 2), round(radii / 2), 1): new_pos = game_map.normalize(curr_pos + positionals.Position(i, j)) dist = game_map.calculate_distance(curr_pos, new_pos) curr_cell = game_map[new_pos] curr_halite_amount = curr_cell.halite_amount if not curr_cell.is_empty: if (curr_cell.has_structure and curr_cell.structure.owner == me.id) \ or (curr_cell.is_occupied and curr_cell.ship.owner == me.id): num_allies += 1 sum_dist_allies += dist else: # enemy num_enemies += 1 sum_dist_enemies += dist sum_halites += curr_halite_amount # Update mine only when # 1. Deloading # 2. Newly made ship # 3. The current mine is deprecated if find_mine and (self.ship_status[ship.id][ACTION] == DELOAD or (self.ship_status[ship.id][ACTION] == FORAGE and \ (self.ship_status[ship.id][MINE] is None or self.ship_status[ship.id][MINE].halite_amount == 0))): net_profit = self.check_if_valid_mine( ship, new_pos, 2) # TODO experiment with this if net_profit > best_net_profit: best_net_profit = net_profit best_mine = curr_cell best_mine_distance = dist best_amount = curr_halite_amount if best_mine: self.mine_targets[ship.id] = best_mine self.ship_status[ship.id][MINE] = best_mine self.ship_status[ship.id][MINE_ARCHIVE] = best_amount return num_enemies, sum_dist_enemies, num_allies, sum_dist_allies, \ sum_halites
def _search_surrounding(self, ship, radii): """ Search within the radii for 1. # of enemies around me 2. sum of distance from the enemies 3. # of allies around me 4. sum of distance from the allies 5. sum of halites in the search area, 6. closest mine with acceptable amount of halites. and update ship_status """ me = self.game.me game_map = self.game.game_map num_enemies = 0 sum_dist_enemies = 0 num_allies = 0 sum_dist_allies = 0 sum_halites = 0 best_mine = None best_mine_distance = 987654321 best_net_profit = -987654321 home_pos = self.ship_status[ship.id][HOME].position curr_pos = ship.position for i in range(-round(radii / 2), round(radii / 2), 1): for j in range(-round(radii / 2), round(radii / 2), 1): new_pos = curr_pos + positionals.Position(i, j) dist = game_map.calculate_distance(curr_pos, new_pos) curr_cell = game_map[new_pos] curr_halite_amount = curr_cell.halite_amount if not curr_cell.is_empty: if (curr_cell.has_structure and curr_cell.structure.owner == me.id) \ or (curr_cell.is_occupied and curr_cell.ship.owner == me.id): num_allies += 1 sum_dist_allies += dist else: # enemy num_enemies += 1 sum_dist_enemies += dist sum_halites += curr_halite_amount if ship.position == home_pos and self.ship_status[ship.id][ACTION] == FORAGE and \ (abs(i) >= 5 and abs(j) >= 5): # normalized_halite_amount = curr_halite_amount * 1.2 if curr_halite_amount >= self.max_halite / 2 else curr_halite_amount net_profit = (ship.halite_amount * (0.9 ** dist) + \ curr_halite_amount * 0.92) * (0.9 ** game_map.calculate_distance(new_pos, home_pos)) if net_profit >= 50 and net_profit > best_net_profit and curr_cell not in self.targets.values( ): best_net_profit = net_profit best_mine = curr_cell best_mine_distance = dist if best_mine: self.targets[ship.id] = best_mine self.ship_status[ship.id][MINE] = best_mine self.ship_status[ship.id][DIST_MINE] = best_mine_distance self.ship_status[ship.id][NET_PROF] = best_net_profit return num_enemies, sum_dist_enemies, num_allies, sum_dist_allies, \ sum_halites