def getdensity(self,pos,dist,inspire = False): total = 0 for x in range(pos.x - dist, pos.x + dist + 1): for y in range(pos.y - dist, pos.y + dist + 1): temp = self.normalize(hlt.Position(x, y)) total += self[temp].halite_amount return total / (dist * dist * 4)
def get_maxPosition(ship, hlt_map, planned_position, game): max_value = [0.0, 1.0, 2.0] max_key = {0.0: (0, 0), 1.0: (0, 0), 2.0: (0, 0)} for k in hlt_map: min_max = min(max_value) if k not in planned_position and hlt_map[k] > min_max: if hlt_map[k] not in max_key: max_key[hlt_map[k]] = k min_idx = max_value.index(min(max_value)) max_value[min_idx] = hlt_map[k] else: c = 0.01 while hlt_map[k] + c in max_key: c += c max_key[hlt_map[k] + c] = k min_idx = max_value.index(min(max_value)) max_value[min_idx] = hlt_map[k] + c del max_key[min_max] max_reward = 10000 desired_position = ship.position for key, position in max_key.items(): p = hlt.Position(position[0], position[1]) nav = game.game_map.aStar_plan(ship.position, p) home_nav = game.game_map.aStar_plan(p, me.shipyard.position) position_cost = (nav['cost'] + home_nav['cost']) / hlt_map[position] if position_cost < max_reward: max_reward = position_cost desired_position = p return desired_position
def get_area_arr(self): r = self.game_map.width % self.len q = int((self.game_map.width - r) / self.len) # q = num of area sections per dimension len_arr = [] idx = 0 n = 0 for i in range(q): if i < r: len = self.len + 1 else: len = self.len len_arr.append(len) if i != 0: idx += len self.idx_arr.append(idx) n += 1 for i in range(n - 1): i_arr = [] for j in range(n - 1): centroid_x = math.floor( (self.idx_arr[i] + self.idx_arr[i + 1]) / 2) centroid_y = math.floor( (self.idx_arr[j] + self.idx_arr[j + 1]) / 2) centroid = hlt.Position(centroid_x, centroid_y) len = len_arr[i] area_ij = Area(centroid, len) self.area_stats(area_ij) #self.area_arr.append(area_ij) i_arr.append(area_ij) self.tot_hal += area_ij.hal self.area_arr.append(i_arr)
def checked_positions(): """Generator for positions to check for ennemies""" for base_position in chain([me.shipyard], me.get_dropoffs()): x_shipyard = base_position.position.x y_shipyard = base_position.position.y for x in range(-search_range, search_range): for y in range(-search_range, search_range): yield hlt.Position(x=x_shipyard + x, y=y_shipyard + y)
def get_total_halite(game): halite = 0 for x in range(game.game_map.width): for y in range(game.game_map.height): p = hlt.Position(x, y) halite += game.game_map[p].halite_amount return halite
def get_info(game_map, occ_arr, hlt_amt, me): for y in range(game_map.height): for x in range(game_map.width): this_cell = game_map[hlt.Position(x, y)] occ_arr[x, y] = this_cell.is_occupied hlt_amt[x, y] = this_cell.halite_amount for ship in me.get_ships(): occ_arr[ship.position.x, ship.position.y] = 2 return occ_arr, hlt_amt
def log_density(self,dist): for row in self._cells: for cell in row: pos = cell.position total = 0 for x in range(pos.x - dist, pos.x + dist + 1): for y in range(pos.y - dist, pos.y + dist + 1): temp = self.normalize(hlt.Position(x, y)) total += self[temp].halite_amount
def area_stats(self, area): x1, y1, x2, y2 = area.boundaries area.hal = 0 area.n_enemies = 0 for i in range(x1, x2 + 1): for j in range(y1, y2 + 1): cell = self.game_map[hlt.Position(i, j)] area.hal += cell.halite_amount if cell.is_occupied and cell.ship.id is not self.my_id: area.n_enemies += 1
def spawn(yard): cost = self.constants.SHIP_COST if me.halite_amount >= cost: id = max(me._ships) + 1 if len(me._ships) else 0 pos = hlt.Position(yard.position.x, yard.position.y) me._ships[id] = hlt.entity.Ship(me, id, pos, 0) gmap[yard].ship = me._ships[id] me.halite_amount -= cost return True return False
def convert(ship): cell = gmap[ship] cost = self.constants.DROPOFF_COST if me.halite_amount >= cost and not cell.structure: id = max(me._dropoffs) + 1 if len(me._dropoffs) else 0 pos = hlt.Position(ship.position.x, ship.position.y) me._dropoffs[id] = hlt.entity.Dropoff(me, id, pos) cell.structure = me._dropoffs[id] me.halite_amount -= cost delete(ship) return True return False
def assign_targets(game, gs): p_dist = list(range(-2, 3)) map_values = {} for x in range(game.game_map.width): for y in range(game.game_map.height): p = hlt.Position(x, y) value = 0 # for this position get the surrounding cells and add up the halite values for dx in p_dist: for dy in p_dist: temp_p = hlt.Position(x + dx, y + dy) p_n = game.game_map.normalize(temp_p) value += game.game_map[p_n].halite_amount map_values[p] = value # now scale the values for each ship we want to assign max_dist = math.sqrt((game.game_map.width * game.game_map.width / 4) + (game.game_map.height * game.game_map.height / 4)) for g in gs: if game.me.has_ship(g.id): temp_map_vals = {} for pos, val in map_values.items(): dist = game.game_map.calculate_distance( game.me.get_ship(g.id).position, pos) d_value = 1 + ((dist / max_dist) * (GAP.DSCALE - 1)) temp_map_vals[pos] = val / d_value # now sort and assign sorted_d = sorted(temp_map_vals.items(), key=lambda x: x[1], reverse=True) g.seek_pos = sorted_d[0][0] map_values.pop(g.seek_pos, None)
def get_targets(game, n): p_dist = [-1, 0, 1] map_values = {} for x in range(game.game_map.width): for y in range(game.game_map.height): p = hlt.Position(x, y) value = 0 # for this position get the surrounding cells and add up the halite values for dx in p_dist: for dy in p_dist: temp_p = hlt.Position(x + dx, y + dy) p_n = game.game_map.normalize(temp_p) value += game.game_map[p_n].halite_amount dist = game.game_map.calculate_distance(game.me.shipyard.position, p) max_dist = math.sqrt( (game.game_map.width * game.game_map.width / 4) + (game.game_map.height * game.game_map.height / 4)) d_max = 3 d_value = 1 + ((dist / max_dist) * (d_max - 1)) value = value / d_value map_values[p] = value # sort map_values and return the best n positions sorted_d = sorted(map_values.items(), key=lambda x: x[1], reverse=True) targets = [] for i in range(n): targets.append(sorted_d[i][0]) return targets
def max_halite_within_distance(self, game_map, location, distance): max_halite_cell = location max_halite = 0 for dx in range(-distance, distance + 1): for dy in range(-distance, distance + 1): loc = game_map.normalize(location + hlt.Position(dx, dy)) if game_map.calculate_distance(location, loc) > distance: continue # pick cell with max halite cell_halite = game_map[loc].halite_amount if cell_halite > max_halite: max_halite_cell = loc max_halite = cell_halite return max_halite_cell
def parse_replay_file(file_name, player_name): print("Load Replay: " + file_name) with open(file_name, 'rb') as f: data = json.loads(zstd.loads(f.read()).decode('utf-8')) print("Load Basic Information") player = [p for p in data['players'] if p['name'] == player_name][0] player_id = int(player['player_id']) my_shipyard = hlt.Shipyard( player_id, ARBITRARY_ID, hlt.Position(player['factory_location']['x'], player['factory_location']['y'])) other_shipyards = [ hlt.Shipyard( p['player_id'], ARBITRARY_ID, hlt.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'] print("Load Cell Information") first_cells = [] for x in range(len(data['production_map']['grid'])): row = [] for y in range(len(data['production_map']['grid'][x])): row += [ hlt.MapCell(hlt.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(hlt.GameMap(new_cells, width, height)) print("Load Player Ships") 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): hlt.Ship(player_id, int(sid), hlt.Position(ship['x'], ship['y']), ship['energy']) for sid, ship in f['entities'][str(player_id)].items() } for f in data['full_frames']] print("Load Other Player Ships") other_ships = [{ int(sid): hlt.Ship(int(pid), int(sid), hlt.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']] print("Load Droppoff Information") 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( hlt.Dropoff( player_id, ARBITRARY_ID, hlt.Position(e['location']['x'], e['location']['y']))) else: new_them_dropoffs.append( hlt.Dropoff( e['owner_id'], ARBITRARY_ID, hlt.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))
DROP_TURNS = 200 # fitted (see ols and dropoff count script) DROP_ALPHA_BETA = { 32: {2: (-1.16, 1.28e-05), 4: (-0.65, 9.25e-06)}, 40: {2: (-1.87, 1.38e-05), 4: (-1.55, 1.23e-05)}, 48: {2: (-1.77, 1.45e-05), 4: (0.95, 2.56e-06)}, 56: {2: (1.33, 6.06e-06), 4: (-3.01, 1.26e-05)}, 64: {2: (-2.26, 1.07e-05), 4: (-3.91, 1.09e-05)}, }[width][num_players] if not warmup: INITIAL_HALITE = 0 for x in range(width): for y in range(width): position = hlt.Position(x, y) INITIAL_HALITE += game_map[position].halite_amount MAX_DROPS = np.floor(DROP_ALPHA_BETA[0] + INITIAL_HALITE * DROP_ALPHA_BETA[1]) # median last spawn turn from teccles games SPAWN_TURNS = { 32: {2: 300, 4: 145}, 40: {2: 318, 4: 197}, 48: {2: 336, 4: 204}, 56: {2: 369, 4: 223}, 64: {2: 375, 4: 291}, }[width][num_players] returning_ships = set() forced_return_ships = set()
def surrounding_ocean(ship, data_frame, area): # Ultimate list that will house the data of positionals around a ship. This is with the ship at origin. Consider this a "mask." # Once we have the area we need to convert back to the map positionals to query status / halite amount. gameMap = data_frame[0] ship_keys = list(data_frame[2].keys()) friendly_ships = data_frame[2] friendly_structures = list(data_frame[4]) enemy_ship_keys = list(data_frame[3].keys()) enemy_ship_data = data_frame[3] enemy_struc_data = data_frame[5] enemy_ships = [] for i in enemy_ship_keys: enemy_ships.append(enemy_ship_data[i].position) enemy_structures = [] for i in enemy_struc_data: enemy_structures.append(i.position) all_ships = [] for i in ship_keys: all_ships.append(friendly_ships[i].position) all_structures = [] for i in friendly_structures: all_structures.append(i.position) map_box = [] # converted "map cell" positions for yval in range(-1 * area, area + 1): row = [] for xval in range(-1 * area, area + 1): cell = gameMap[hlt.Position(ship.position.y, ship.position.x) + hlt.Position(xval, yval)] if cell.position in all_structures: structure_friend_foe = 1 elif cell.position in enemy_structures: structure_friend_foe = -1 else: structure_friend_foe = 0 if cell.position in all_ships: ship_friend_foe = 1 friendly_ship = all_ships.index(cell.position) friendly_ship = ship_keys[friendly_ship] ship_halite = friendly_ships[friendly_ship].halite_amount ships = round(ship_friend_foe * ship_halite / MAX_HALITE, 3) if ships > 1.000: ships = 1.000 elif cell.position in enemy_ships: ship_friend_foe = -1 enemy_ship = enemy_ships.index(cell.position) enemy_ship = enemy_ship_keys[enemy_ship] ship_halite = enemy_ship_data[enemy_ship].halite_amount ships = round(ship_friend_foe * ship_halite / MAX_HALITE, 3) if ships > 1.000: ships = 1.000 else: ship_friend_foe = 0 ships = 0 current_halite = round(cell.halite_amount / MAX_HALITE, 3) # logic to ensure that the value of halite never is greater than 1 if current_halite > 1: current_halite = 1.000 map_values = (current_halite, ships, structure_friend_foe) row.append(map_values) map_box.append(row) return map_box
#!/usr/bin/env python3 import hlt from hlt import constants from hlt.positionals import Direction import random import logging """ <<<Game Begin>>> """ game = hlt.Game() all_cells_collection = [hlt.Position(i, y) for i in range(game.game_map.width) for y in range(game.game_map.height)] game.ready("simple_rad_v1") logging.info("Successfully created bot! My Player ID is {}.".format(game.my_id)) """ <<<Game Loop>>> """ while True: game.update_frame() me = game.me game_map = game.game_map halite_map = {cell: game_map[cell].halite_amount for cell in all_cells_collection} # logging.info("{}.".format(all_cells_collection)) # logging.info("{}.".format(halite_map)) command_queue = [] direction_order = [Direction.North, Direction.South, Direction.East, Direction.West, Direction.Still] for ship in me.get_ships(): position_options = ship.position.get_surrounding_cardinals() + [ship.position] position_dict = {} halite_dict = {}
while U: Q.update_frame() me = Q.me u = Q.game_map q = F g = [] for M in V(0, u.height, 8): for C in V(0, u.width, 8): B = 0 K = (C, M) o = 0 for y in V(M, M + 8): for x in V(C, C + 8): L = u[hlt.Position(x, y)].halite_amount B += L if L > o: K = (x, y) o = L if B > 3000: g.append((K[0], K[1], B / (1 + u.calculate_distance( hlt.Position(C + 4, M + 4), me.shipyard.position)))) T = G(g, key=lambda x: x[2]) h = [] p = [me.shipyard.position] + [W.position for W in me.get_dropoffs()] for e in me.get_ships(): if e.position in p: plans[e.id] = c if plans.get(e.id) == 'return' or e.halite_amount > 700: plans[e.id] = 'return'
ship.position, me.shipyard.position): ship_status[ship.id] = "end of game" elif ship.halite_amount >= constants.MAX_HALITE * 0.70: ship_status[ship.id] = "returning" if ship.id in mission: del mission[ship.id] if ship_status[ship.id] == "exploring": if ship.id not in mission: maxP = get_maxPosition(ship, hlt_map, planned_position, game) move = game_map.aStar_navigate(ship, maxP) command_queue.append(ship.move(move)) planned_position.append((maxP.x, maxP.y)) mission[ship.id] = (maxP.x, maxP.y) else: maxP = hlt.Position(mission[ship.id][0], mission[ship.id][1]) move = game_map.aStar_navigate(ship, maxP) command_queue.append(ship.move(move)) planned_position.append(mission[ship.id]) if game_map[maxP].halite_amount <= 15: del mission[ship.id] logging.info( "Ship {} has {} halite and is {} to {} from {} by moving {}.". format(ship.id, ship.halite_amount, ship_status[ship.id], maxP, ship.position, move)) elif ship_status[ship.id] == "returning": if ship.position == me.shipyard.position: ship_status[ship.id] = "exploring" # elif me.halite_amount > constants.DROPOFF_COST:
v.ready("PriorityCollector") p("Successfully created bot! My Player ID is {}.".format(v.my_id)) b={} while f: v.update_frame() me=v.me u=v.game_map F=[] for j in A(0,u.height,8): for R in A(0,u.width,8): M=0 i=(R,j) W=0 for y in A(j,j+8): for x in A(R,R+8): L=u[hlt.Position(x,y)].halite_amount M+=L if L>W: i=(x,y) W=L if M>3000: F.append((i[0],i[1],M/(1+u.calculate_distance(hlt.Position(R+4,j+4),me.shipyard.position)))) O=a(F,key=lambda x:x[2]) G=[] for m in me.get_ships(): if m.position==me.shipyard.position: b[m.id]=w if b.get(m.id)=='return' or m.halite_amount>700: b[m.id]='return' x=me.shipyard.position V=u.naive_navigate(m,x)
if (me.halite_amount + ship.halite_amount ) > y2 * constants.DROPOFF_COST and game_map.calculate_distance( ship.position, me.shipyard.position) >= (4 / 3) * r and not built_drop: built_drop = True command_queue.append(ship.make_dropoff()) logging.info("Ship {} is being turned into a dropoff.".format( ship.id)) elif ship_status[ship.id] == "exploring": if ship.id not in mission: maxP = get_maxPosition(ship, hlt_map, planned_position, game) # if game_map[maxP].halite_amount > y*game_map[ship.position].halite_amount: move = game_map.aStar_navigate(ship, maxP) next_ = ship.position + hlt.Position(move[0], move[1]) next_location[ship.id] = (next_.x, next_.y) if game.turn_number > 1 and ship.id in current_location: prev_location[ship.id] = current_location[ship.id] if prev_location[ship.id] == next_location[ship.id]: move = (0, 0) current_location[ship.id] = (ship.position.x, ship.position.y) command_queue.append(ship.move(move)) planned_position.append((maxP.x, maxP.y)) mission[ship.id] = (maxP.x, maxP.y) else: maxP = hlt.Position(mission[ship.id][0], mission[ship.id][1]) move = game_map.aStar_navigate(ship, maxP) command_queue.append(ship.move(move))
def next_state(self, state, action): state = copy.deepcopy(state) gmap = state.game_map def idx(entity): return entity.position.y, entity.position.x def delete(ship): gmap[ship].ship = None ship.owner._ships.pop(ship.id) def mine(ship, inspired=False): if inspired: ratio = self.constants.INSPIRED_EXTRACT_RATIO else: ratio = self.constants.EXTRACT_RATIO cell = gmap[ship] gained = extracted = math.ceil(cell.halite_amount / ratio) if extracted == 0 and cell.halite_amount > 0: gained = extracted = cell.halite_amount if extracted + ship.halite_amount > self.constants.MAX_HALITE: extracted = self.constants.MAX_HALITE - ship.halite_amount if inspired: gained += gained * self.constants.INSPIRED_BONUS_MULTIPLIER if self.constants.MAX_HALITE - ship.halite_amount < gained: gained = self.constants.MAX_HALITE - ship.halite_amount ship.halite_amount += gained cell.halite_amount -= extracted def move(ship, direction, inspired=False): if inspired: ratio = self.constants.INSPIRED_MOVE_COST_RATIO else: ratio = self.constants.MOVE_COST_RATIO cell = gmap[ship] cost = round(cell.halite_amount / ratio) if ship.halite_amount >= cost: ship.position = gmap.normalize(ship.position + direction) cell.ship, gmap[ship].ship = None, ship ship.halite_amount -= cost return True return False def convert(ship): cell = gmap[ship] cost = self.constants.DROPOFF_COST if me.halite_amount >= cost and not cell.structure: id = max(me._dropoffs) + 1 if len(me._dropoffs) else 0 pos = hlt.Position(ship.position.x, ship.position.y) me._dropoffs[id] = hlt.entity.Dropoff(me, id, pos) cell.structure = me._dropoffs[id] me.halite_amount -= cost delete(ship) return True return False def spawn(yard): cost = self.constants.SHIP_COST if me.halite_amount >= cost: id = max(me._ships) + 1 if len(me._ships) else 0 pos = hlt.Position(yard.position.x, yard.position.y) me._ships[id] = hlt.entity.Ship(me, id, pos, 0) gmap[yard].ship = me._ships[id] me.halite_amount -= cost return True return False def is_inspired(ship): enemies = 0 open, closed = [], set() open.append((0, ship.position.y, ship.position.x)) while len(open): dist, j, i = open[0] cell = gmap._cells[j][i] closed.add((j, i)) open = open[1:] if cell.ship and cell.ship.owner is not ship.owner: enemies += 1 if enemies >= self.constants.INSPIRATION_SHIP_COUNT: return True if dist < self.constants.INSPIRATION_RADIUS: for dj, di in hlt.Direction.get_all_cardinals(): _j, _i = (j + dj) % gmap.height, (i + di) % gmap.width if (_j, _i) not in closed: open.append((dist + 1, _j, _i)) return False # ==== MY ACTIONS ==== # me = state.me for ship in me.get_ships(): a = action[idx(ship)] if a < 4: # move mv = hlt.Direction.get_all_cardinals()[a] if move(ship, hlt.Position(*mv), inspired=is_inspired(ship)): continue if a == 4: # make dropoff if convert(ship): continue mine(ship, inspired=is_inspired(ship)) # stay still if action[idx(me.shipyard)] == 6: # new ship spawn(me.shipyard) # ==== ENEMIES ==== # for id in state.players: if id != me.id: for ship in state.players[id].get_ships(): mine(ship, inspired=is_inspired(ship)) # stay still # ==== COLLISIONS ==== # collisions = {} all_ships = (s for p in state.players.values() for s in p.get_ships()) for ship in all_ships: # detect key, other = idx(ship), gmap[ship].ship if other and other is not ship: if key in collisions: collisions[key].append(ship) else: collisions[key] = [other, ship] for (j, i), collision in collisions.items(): # resolve cell = gmap._cells[j][i] h = cell.halite_amount + sum(s.halite_amount for s in collision) cell.halite_amount = min(h, hlt.constants.MAX_HALITE) for ship in collision: delete(ship) # ==== DROP HALITE ==== # for dropoff in me.get_dropoffs() + [me.shipyard]: # get halite cell = gmap[dropoff] me.halite_amount += cell.halite_amount cell.halite_amount = 0 if cell.ship: me.halite_amount += cell.ship.halite_amount cell.ship.halite_amount = 0 return state