def compute_state(ship, game_map, me): """BUT: retourner un vecteur qui représente bien l'état de la partie""" sight_window = 17 array_halite = np.zeros(145) array_ship = np.zeros(145) array_dropoff = np.zeros(145) counter = 0 for i in range(-(sight_window//2), sight_window//2 + 1): for j in range(-(sight_window//2) + abs(i), sight_window//2 - abs(i) + 1): cell = game_map[Position(i + ship.position.x, j + ship.position.y)] array_halite[counter] = cell.halite_amount if cell.structure: if cell.structure.id == me.shipyard.id or cell.structure.id in me._dropoffs: array_dropoff[counter] = 1 else: array_dropoff[counter] = -1 if cell.ship: if me.has_ship(cell.ship.id): array_ship[counter] = 1 else: array_ship[counter] = -1 counter += 1 my_dropoffs = list(me._dropoffs.values()) my_dropoffs.append(me.shipyard) distance_my_dropoffs = np.array([game_map.calculate_distance(ship.position, dropoff.position) for dropoff in my_dropoffs]) min_distance_dropoff = min(distance_my_dropoffs) position_closest_dropoff = my_dropoffs[np.argmin(distance_my_dropoffs)].position game_state = np.append(np.append(array_halite, array_ship), array_dropoff) interesting_values = np.array([len(me._dropoffs) + 1, len(me._ships), ship.position.x, ship.position.y, position_closest_dropoff.x, position_closest_dropoff.y, min_distance_dropoff, ship.halite_amount]) game_state = np.append(game_state, interesting_values) return game_state
def get_halite_amount(): hal = 0 for x, y in itertools.product(range(game.game_map.width), range(game.game_map.height)): hal += game.game_map[Position(x, y)].halite_amount return hal
game_map = game.game_map TURN += 1 if GAME_STATE == 0: MAP_SIZE = game_map.width logging.info("MAP SIZE : " + str(MAP_SIZE)) MAP_SIZE_DB = {64: 500, 56: 475, 48: 450, 40: 425, 32: 400} TURNCOUNT = MAP_SIZE_DB[MAP_SIZE] logging.info("TURNS : " + str(TURNCOUNT)) GAME_STATE = 1 if DEADLOCK: if not BLOCKADED: DEADLOCK = False logging.info("DEADLOCK Warning rescinded") if (game_map[me.shipyard.position + Position(*Direction.East)].is_occupied and game_map[me.shipyard.position + Position(*Direction.West)].is_occupied and game_map[me.shipyard.position + Position(*Direction.South)].is_occupied and game_map[me.shipyard.position + Position(*Direction.North)].is_occupied and game_map[me.shipyard.position].is_occupied): if DEADLOCK: BLOCKADED = True logging.info("DEADLOCK Detected") DEADLOCK = False else: DEADLOCK = True logging.info("DEADLOCK Warning")
def detup(tup): return Position(*tup)
def get_position_from_move(game, ship, move): move_offset = DIRECTIONS[move] return game.game_map.normalize(ship.position + Position(move_offset[0], move_offset[1]))
# 1. get the max loiter distance # 2. get the loiter multiple based on turn and max/min loiter distance # 3. get a random point on a circle an mult by the loiter multiple # 4. add the result to the current postion to get a destination loiterMult = get_loiter_multiple(game) logging.info( "Ship - backoff/loiter mult: {}".format(loiterMult)) # Debug metric #DebugMetrics["NavMults"].append((game.turn_number, round(loiterMult, 2))) # get a random point on a cicle randPi = random.random() * math.pi * 2 loiterOffset = Position( round(math.cos(randPi) * loiterMult + MaxLoiterDist), round(math.sin(randPi) * loiterMult + MaxLoiterDist)) #logging.info("Ship - backoff/loiter loiterOffset: {}".format(loiterOffset)) # Debug metric, can't use position because will be for diff ship/position every time #DebugMetrics["loiterOffsets"].append((loiterOffset.x, loiterOffset.y)) #DebugMetrics["loiterDistances"].append((game.turn_number, round(math.sqrt(loiterOffset.x ** 2 + loiterOffset.y ** 2), 2))) loiterPoint = ship.position + loiterOffset #logging.info("Ship - backoff/loiter point: {}".format(loiterPoint)) ship.path.append(loiterPoint) ship.status = "exploring"
ship_dict[ship.id] = 'returning' command_queue.append( ship.move(game_map.naive_navigate(ship, me.shipyard.position))) continue # If ship is on halite-rich cell, harvest it if game_map[ship.position].halite_amount >= 25: command_queue.append(ship.stay_still()) continue # Explore for closest cell with a good amount of halite else: closest_cell = (None, float('inf')) for cell in cells: map_cell = game_map[Position(cell[0], cell[1])] distance = game_map.calculate_distance(ship.position, map_cell.position) halite = map_cell.halite_amount if halite > 150 and distance < closest_cell[1]: closest_cell = (map_cell, distance) command_queue.append( ship.move( game_map.naive_navigate(ship, closest_cell[0].position))) continue # If the game is in the first 200 turns and you have enough halite, spawn a ship. # Don't spawn a ship if you currently have a ship at port, though - the ships will collide. if turns_left < 50: pass
for direction in position_dict: position = position_dict[direction] halite_amount = game_map[position].halite_amount if position_dict[direction] not in position_choices: if direction == Direction.Still: halite_amount *= 4 halite_dict[direction] = halite_amount directional_choice = max(halite_dict, key=halite_dict.get) position_choices.append(position_dict[directional_choice]) command_queue.append( ship.move( game_map.naive_navigate( ship, ship.position + Position(*directional_choice)))) if ship.halite_amount >= constants.MAX_HALITE * 0.9: ship_states[ship.id] = "depositing" elif ship_states[ship.id] == "depositing": move = game_map.naive_navigate(ship, me.shipyard.position) upcoming_position = ship.position + Position(*move) if upcoming_position not in position_choices: position_choices.append(upcoming_position) command_queue.append(ship.move(move)) if move == Direction.Still: ship_states[ship.id] = "collecting" else: position_choices.append(ship.position) command_queue.append(
def get_new_position(action, ship): return game_map.normalize( Position(ship.position.x + directions[a][0], ship.position.y + directions[a][1]))
def get_halite_move(game, ship, args=None): """ Get a move based on the surrounding cell with the most halite :param args None ... for now. :returns Returns a move letter on success, None if there is a collision. """ if args is None: args = {} move = "o" if DEBUG & (DEBUG_NAV): logging.info("Nav - ship {} is getting a density based move".format( ship.id)) moves = [] for blocks in game.game_map.get_cell_blocks( ship.position, 3, 3): # returns array of tuples [(direction), CellBlock] directional_offset = blocks[0] block = blocks[1] if block.get_max() > constants.MAX_HALITE * MINING_THRESHOLD_MULT: moves.append((directional_offset, block, block.get_mean())) sorted_blocks = sorted(moves, key=lambda item: item[2], reverse=True) if not sorted_blocks: move = get_random_move( game, ship) # ToDo: would be better to try a large search radius? if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} All surrounding cells have halite < {} . Returning random move: {}" .format(ship.id, constants.MAX_HALITE * MINING_THRESHOLD_MULT, move)) return move best_bloc_data = sorted_blocks[ 0] # (directional_offset, block, block mean value) max_cell_amount = best_bloc_data[1].get_max() if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} found {} valid halite cells with a the max cell containing {} halite" .format(ship.id, len(sorted_blocks), max_cell_amount)) for best_cell in best_bloc_data[1].get_cells(): if best_cell.halite_amount == max_cell_amount: break move_offset = best_bloc_data[0] new_position = game.game_map.normalize( ship.position.directional_offset(move_offset)) if DEBUG & (DEBUG_NAV): logging.info( "Nav - Ship {} best cell new_position: {}, offset: {}, value: {}". format(ship.id, new_position, move_offset, max_cell_amount)) normalized_position = game.game_map.normalize(new_position) if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} best cell normalized_position: {}".format( ship.id, normalized_position)) cell = game.game_map[normalized_position] # # collision resolution # if cell.is_occupied: game.collisions.append( (ship, cell.ship, Direction.convert(move_offset), normalized_position, resolve_halite_move)) # args = alt moves? if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} collided with ship {} at {} while moving {}". format(ship.id, cell.ship.id, normalized_position, Direction.convert(move_offset))) return None # # success # cell.mark_unsafe(ship) move = Direction.convert(move_offset) # blocks are guaranteed to have at least 1 cell that is minable. This is critical to avoid getting stuck # between two blocks each of which never modified. For a 3x3 block, add 'plus_one' assures that we move far # to reach the modifiable cell, thus prevent an endless movement between blocks move_plus_one = Position( best_cell.position.x, best_cell.position.y) # go one more move in the same direction if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} has a move_plus_one of {}".format( ship.id, move_plus_one)) ship.path.append(move_plus_one) return move
def get_next_pos_halite_amount(ship, game_map): next_pos_halite_amount = np.zeros(5) for index, direction in enumerate(directions): next_pos_halite_amount[index] = game_map[Position(ship.position.x + direction[0], ship.position.y + direction[1])].halite_amount return next_pos_halite_amount
# ship.move( # game_map.naive_navigate(ship, me.shipyard.position))) if game_map[ ship. position].halite_amount < constants.MAX_HALITE / 10 or ship.is_full: if ship.halite_amount > 600: command_queue.append( ship.move( game_map.naive_navigate(ship, me.shipyard.position))) #In the line under: #ship.position != me.shipyard.position and elif ship.halite_amount <= 600: pos = ship.position maximum = 0 for i in range(pos.x - 5, pos.x + 5): for j in range(pos.y - 5, pos.y + 5): if game_map[Position(i, j)].halite_amount > maximum: maximum = game_map[Position(i, j)].halite_amount max_pos = Position(i, j) command_queue.append( ship.move(game_map.naive_navigate(ship, max_pos))) # else: # command_queue.append( # ship.move( # random.choice([ Direction.North, Direction.South, Direction.East, Direction.West ]))) ############### How to mark unsafe????? # MapCell.mark_unsafe(game_map[ship.position]) # naive_navigate is doing this else: command_queue.append(ship.stay_still()) # If the game is in the first 200 turns and you have enough halite, spawn a ship.
ship_targets = {} def calculate_tile_value(halite_tile: Position, dropoff: Position): _inverse_point = dropoff - halite_tile distance = abs(_inverse_point.x) + abs(_inverse_point.y) return min(1000, game.game_map[halite_tile].halite_amount) * (0.9** distance) tileValues = [] for i in range(0, game.game_map.height): current_value = [] for j in range(0, game.game_map.width): current_value.append( calculate_tile_value(Position(i, j), game.me.shipyard.position)) tileValues.append(current_value) while True: game.update_frame() me = game.me game_map = game.game_map command_queue = [] direction_order = Direction.get_all_cardinals() + [Direction.Still] def _ship_needs_tile(ship): "Simply Writing out for clarity." if ship.id not in ship_states:
game.update_frame() # You extract player metadata and the updated map metadata here for convenience. me = game.me game_map = game.game_map # A command queue holds all the commands you will run this turn. You build this list up and submit it at the # end of the turn. command_queue = [] for ship in me.get_ships(): high_halite = [0, 0] for x in range(game_map.width): for y in range(game_map.height): if (game_map[Position(x, y)].halite_amount / 4**(game_map.calculate_distance( ship.position, Position(x, y))) > game_map[Position(*high_halite)].halite_amount / 4**(game_map.calculate_distance( ship.position, Position(*high_halite))) and len(me.get_ships()) * 0.5 < game_map.calculate_distance(me.shipyard.position, Position(x, y))): high_halite = [x, y] # For each of your ships, move randomly if the ship is on a low halite location or the ship is full. # Else, collect halite. if random.random() < 0.1: command_queue.append( ship.move(
def run(): global spent_so_far destinations = {} ships_des = {} while True: game.update_frame() # You extract player metadata and the updated map metadata here for convenience. me = game.me game_map = game.game_map turns_left = constants.MAX_TURNS - game.turn_number halite_left = get_halite_amount() halite_percent = halite_left / starting_halite_amount highs = [] # spots = PriorityQueue() for x, y in itertools.product(range(game_map.width), range(game_map.height)): highs.append(Position(x, y)) highs = sorted(highs, key=lambda p: game_map[p].halite_amount, reverse=True)[:150] positions_used = set() command_queue = [] ship_queue = me.get_ships() for do in me.get_dropoffs(): pos = do.position if pos not in dropoffs: dropoffs.append(pos) # top10 = [highs.get().position for _ in range(10)] # logging.info(top10) # sort ships by proximity to shipyard ship_queue = sorted( ship_queue, key=lambda s: game_map.calculate_distance(s.position, syp), reverse=True) # ship_queue = sorted(ship_queue, key=lambda s: s.id, # reverse=True) dropoff = False for ship in ship_queue: if ship.id not in first_seen: first_seen[ship.id] = game.turn_number ship.staying = False ship.returning = False if ship.position in destinations: del destinations[ship.position] if (constants.MAX_TURNS - game.turn_number) < 4 and ship.position in dropoffs: # ignore ship completely so that it can die ship.staying = True # should we build a drop-off? elif (len(ship_queue) >= 10 * len(dropoffs) and ship.position in highs and game_map.calculate_distance( ship.position, closest_dropoff(ship.position)) > 15 and me.halite_amount > constants.DROPOFF_COST - game_map[ship.position].halite_amount + ship.halite_amount and game.turn_number < constants.MAX_TURNS * 0.75 and halite_percent > 0.4 and # len(dropoffs) < 4 and not dropoff): dropoff = True spent_so_far += constants.DROPOFF_COST - game_map[ ship.position].halite_amount command_queue.append(ship.make_dropoff()) ship.staying = True positions_used.add(ship.position) # can it move? elif (game_map[ship.position].halite_amount * 0.1) > ship.halite_amount: # can't move, stay put # logging.info(f'ship {ship.id} staying with {ship.halite_amount} avaliable') move(ship.position, ship.position, ship, positions_used, command_queue) ship.staying = True elif ((ship.halite_amount > RETURN_AMOUNT) or (game_map.calculate_distance( ship.position, closest_dropoff(ship.position)) + 4 >= (constants.MAX_TURNS - game.turn_number))): returning.add(ship.id) ship.returning = True elif (ship.halite_amount + (game_map[ship.position].halite_amount * 0.25) > 1000): # its not worth staying on the square, just go home ship.returning = True returning.add(ship.id) # mark enemy ships if we don't control more than half the ships on the board total_num_of_ships = 0 for i in game.players: total_num_of_ships += len(game.players[i].get_ships()) if len(ship_queue) < total_num_of_ships: for i in game.players: if i == game.my_id: continue player = game.players[i] for ship in player.get_ships(): for d in Direction.get_all_cardinals() + [(0, 0)]: location = game_map.normalize( ship.position.directional_offset(d)) if game_map.calculate_distance( location, closest_dropoff(ship.position)) <= 1: pass # elif (ship.halite_amount > 950 and # len(game.players[ship.owner].get_ships()) < len(ship_queue)): # its fine to collide with a high halite ship and steal its halite # pass else: positions_used.add(location) for ship in ship_queue: if ship.position in dropoffs: returning.discard(ship.id) ship.returning = False elif ship.id in returning and not ship.staying: # move to drop-off # logging.info('move to dropoff') ship.returning = True if constants.MAX_TURNS - game.turn_number <= 10: collide = True else: collide = False move(closest_dropoff(ship.position), ship.position, ship, positions_used, command_queue, collide=collide, shortest=True) for ship in ship_queue: if ship.returning or ship.staying: continue elif (ship.halite_amount + (game_map[ship.position].halite_amount * 0.25) > RETURN_AMOUNT): # will staying make me cross over the line? ship.staying = True move(ship.position, ship.position, ship, positions_used, command_queue) else: logging.info(f'd {destinations}') highest_so_far = game_map[ship.position].halite_amount best = ship.position for p in highs: # p = game_map.normalize(p) if p in destinations: continue hal = game_map[p].halite_amount if p in dropoffs: hal = ship.halite_amount weighted = hal / ( game_map.calculate_distance(ship.position, p) + 1) if weighted > highest_so_far: best = p if p in destinations and destinations[p] != ship.id: # logging.info(f'nope on {p} for ship {ship.id}') continue p = best logging.info(f'Ship {ship.id} moving to position {p}') if ship.id in ships_des: if ships_des[ship.id] != p: if ships_des[ship.id] in destinations: del destinations[ships_des[ship.id]] else: logging.info( f'Mismatch. Expected {ships_des[ship.id]} in {destinations}' ) ships_des[ship.id] = p destinations[p] = ship.id # if p in dropoffs: # p. move(p, ship.position, ship, positions_used, command_queue, shortest=False) '''''' halite_collected = me.halite_amount + spent_so_far - 5000 ship_turns = 0 for id, turn in first_seen.items(): ship_turns += game.turn_number - turn collection_per_turn.append(halite_collected) if game.turn_number < 20: avg_per_ship_per_turn = 2000 else: # halite_diff = collection_per_turn[game.turn_number - 1] - \ # collection_per_turn[game.turn_number - 21] avg_per_ship_per_turn = halite_collected / ship_turns / 1.1 logging.info( f'turn {game.turn_number} has avg {avg_per_ship_per_turn}') # if (avg_per_ship_per_turn * turns_left >= 1400 and if (((turns_left > 150 and not NEW_SPAWN) or (avg_per_ship_per_turn * turns_left >= 1800 and NEW_SPAWN)) and me.halite_amount >= constants.SHIP_COST and not dropoff and halite_percent > 0.4 and syp not in positions_used): spent_so_far += constants.SHIP_COST command_queue.append(me.shipyard.spawn()) # Send your moves back to the game environment, ending this turn. logging.info(command_queue) game.end_turn(command_queue)
def detup(self, tup): return Position(*tup)
dropoff_positions = [ d.position for d in list(me.get_dropoffs()) + [me.shipyard] ] ship_positions = [s.position for s in list(me.get_ships())] for ship in me.get_ships(): logging.info(f"{ship.position},{ship.position + Position(-3, 3)}") logging.info(f"{game_map[ship.position + Position(-3, 3)]}") size = SIGHT_DISTANCE surroundings = [] for y in range(-1 * size, size + 1): row = [] for x in range(-1 * size, size + 1): current_cell = game_map[ship.position + Position(x, y)] if current_cell.position in dropoff_positions: drop_friend_foe = 1 else: drop_friend_foe = -1 if current_cell.position in ship_positions: ship_friend_foe = 1 else: ship_friend_foe = -1 halite = round( current_cell.halite_amount / constants.MAX_HALITE, 2)
for n, direction in enumerate(direction_order): position_dict[direction] = position_options[n] for direction in position_dict: position = position_dict[direction] halite_amount = game_map[position].halite_amount if position_dict[direction] not in position_choices: if direction == Direction.Still: halite_amount *= 4 halite_dict[direction] = halite_amount directional_choice = max(halite_dict, key=halite_dict.get) position_choices.append(position_dict[directional_choice]) command_queue.append(ship.move(game_map.naive_navigate(ship, ship.position+Position(*directional_choice)))) if ship.halite_amount >= constants.MAX_HALITE*0.9: ship_states[ship.id] = "depositing" elif ship_states[ship.id] == "depositing": # if sn/dn>8: # command_queue.append(ship.make_dropoff()) # sn-=1 # dn+=1 # else: if game_map.naive_navigate(ship, me.shipyard.position) != Direction.Still and len(game_map.get_unsafe_moves(ship.position, me.shipyard.position))>0: move = game_map.get_unsafe_moves(ship.position, me.shipyard.position)[0] upcoming_position = ship.position + Position(*move)
for n, direction in enumerate(direction_order): position_dict[direction] = position_options[n] for direction in position_dict: position = position_dict[direction] halite_amount = game_map[position].halite_amount if position_dict[direction] not in position_choices: if direction == Direction.Still: halite_amount *= 4 halite_dict[direction] = halite_amount directional_choice = max(halite_dict, key=halite_dict.get) position_choices.append(position_dict[directional_choice]) command_queue.append(ship.move(game_map.naive_navigate(ship, ship.position+Position(*directional_choice)))) if ship.halite_amount >= constants.MAX_HALITE*0.9: ship_states[ship.id] = "depositing" elif ship_states[ship.id] == "depositing": f=0 if len(me.get_dropoffs())>0: #dd = {} #for dropoff in me.get_dropoffs(): # dd[dropoff.id] = game_map.calculate_distance(ship.position, dropoff.position) #ddi = max(dd, key=dd.get) #if ddi in dd.keys(): # if game_map.calculate_distance(ship.position, me.shipyard.position)<dd[dropoff.id]: # move = game_map.naive_navigate(ship, me.shipyard.position) # upcoming_position = ship.position + Position(*move)
command_queue.append(ship.move(movement)) go_home[ship.id] = True elif game_map[ship.position].halite_amount < 10: directions = [ Direction.North, Direction.South, Direction.East, Direction.West ] random.shuffle(directions) for direction in directions: next_pos = (ship.position.x + direction[0], ship.position.y + direction[1]) if next_pos not in taken_position: break if not next_pos: command_queue.append(ship.stay_still()) else: movement = game_map.naive_navigate( ship, Position(next_pos[0], next_pos[1])) command_queue.append(ship.move(movement)) taken_position[next_pos] = True else: command_queue.append(ship.stay_still()) # Don't spawn a ship if you currently have a ship at port, though - the ships will collide. if args.unrestricted and game.turn_number <= 100 and me.halite_amount >= constants.SHIP_COST and not game_map[ me.shipyard].is_occupied: command_queue.append(me.shipyard.spawn()) # Send your moves back to the game environment, ending this turn. game.end_turn(command_queue)
while True: ship_status = {} move_near = False game.update_frame() me = game.me game_map = game.game_map command_queue = [] direction_order = [ Direction.North, Direction.South, Direction.East, Direction.West, Direction.Still ] shipyard_position = me.shipyard.position new_shipyard_position = tuple( (shipyard_position.x - 1, shipyard_position.y)) www = Position(shipyard_position.x - 1, shipyard_position.y) position_choices = [] ships_pos = [] # logging.info('\n\n \t\t {}'.format(me.get_ships())) for s in me.get_ships(): ships_pos.append(s.position) # logging.info('\n\n \t\t {}'.format(ships_pos)) count = 0 for ship in me.get_ships(): count += 1 # logging.info('\n\n \t\t\t\t\t Start'.format(position_choices)) # logging.info('\n\n \t\t\t\t\t Ship status: {} ID: {}'.format(ship_status, ship.id))
ship_surrounding_coord_haliteDB[direction] = halite_count if log_LEVEL == 'v': logging.info("Halite on-Board : " + str(ship.halite_amount)) logging.info( "Halite on-Origin-Cell : " + str(round(0.1 * game_map[ship.position].halite_amount, 2))) preferred_direction = max(ship_surrounding_coord_haliteDB, key=ship_surrounding_coord_haliteDB.get) if ship.halite_amount < round( 0.1 * game_map[ship.position].halite_amount, 2): preferred_direction = Direction.Still logging.info("Insufficient Halite to move. HALTING.") elif preferred_direction != Direction.Still and game_map[ ship.position + Position(*preferred_direction)].is_occupied: logging.info("Collision imminent...") while game_map[ship.position + Position( *preferred_direction)].is_occupied and len( ship_surrounding_coord_DB.keys()) > 0: logging.info("Attempting to reroute") logging.info("Possible Routes : " + str(ship_surrounding_coord_haliteDB)) logging.info("Elimintate route : " + str(preferred_direction)) ship_surrounding_coord_haliteDB.pop( preferred_direction, None) preferred_direction = max( ship_surrounding_coord_haliteDB, key=ship_surrounding_coord_haliteDB.get) if preferred_direction == Direction.Still:
def respond_to_sos(game, sos_call): """ pop event find all close ships to sos event eval the chance of reaching the event loc send ship based on capacity sos -> (s_id, halite, position) """ sos_position = sos_call["position"] sos_ship_id = sos_call["s_id"] sos_halite_lost = game.game_map[sos_position].halite_amount if DEBUG & (DEBUG_GAME): logging.info( "Game - Sos recieved from ship {} @ {}. There was {} halite lost.". format(sos_ship_id, sos_position, sos_halite_lost)) if sos_halite_lost < 300: if DEBUG & (DEBUG_GAME): logging.info( "Game - Sos disregarded from ship {} @ {}. Halite lost is {}, threshold is {}" .format(sos_ship_id, sos_position, sos_halite_lost, 500)) return False block_size = 12 block = CellBlock( game.game_map, Position(round(sos_position.x - block_size / 2), round(sos_position.y - block_size / 2)), block_size, block_size) cells = block.get_cells() enemies = [] friendlies = [] for cell in cells: if cell.is_occupied: distance = game.game_map.calculate_distance( cell.position, sos_position) if cell.ship.owner == game.me.id: if cell.ship.status != "returning": friendlies.append((cell.ship, distance)) else: enemies.append((cell.ship, distance)) friendlies.sort(key=lambda item: (item[1], item[0].halite_amount), reverse=True) enemies.sort(key=lambda item: (item[1]), reverse=True) # reward/risk # halite / ((f_best_dist * c1) + (e_cnt/f_cnt * c2) + (bf_dst/be_dst * c3)) c1,c2,c3 = .5,2,4 ??? if enemies: best_enemy = enemies[-1] best_enemy_ship = best_enemy[0] best_enemy_distance = best_enemy[1] responder = False for friendly_ship, friendly_distance in friendlies: if enemies: if friendly_ship.halite_amount < 500 and friendly_distance < best_enemy_distance: responder = friendly_ship responder.path.append(sos_position) break else: if friendly_ship.halite_amount < 900: responder = friendly_ship responder.path.append(sos_position) break if DEBUG & (DEBUG_GAME): if friendlies: logging.info( "Game - There are {} friendlies within {} moves of {}. The closest is ship {} @ {} away." .format(len(friendlies), block_size, sos_position, friendly_ship.id, friendly_distance)) else: logging.info( "Game - There are no friendlies within {} moves of {} with {} cargo capacity" .format(block_size, sos_position, 600)) if enemies: logging.info( "Game - There are {} enemies within {} moves of {}. The closest is ship {} @ {} away." .format(len(enemies), block_size, sos_position, best_enemy_ship.id, best_enemy_distance)) else: logging.info( "Game - There are no enemies within {} moves of {}".format( block_size, sos_position)) if responder and responder.assignments: if DEBUG & (DEBUG_GAME): logging.info( "Game - Ship {} diverted from assignment {} to respond to sos from ship {} @ {}" .format(responder.id, responder.assignments[-1], sos_ship_id, sos_position)) elif responder: if DEBUG & (DEBUG_GAME): logging.info( "Game - Ship {} assigned to respond to sos from ship {} @ {}" .format(responder.id, sos_ship_id, sos_position)) else: if DEBUG & (DEBUG_GAME): logging.info( "Game - There are no viable ships to respond to sos from ship {} @ {}" .format(sos_ship_id, sos_position)) #should the sos position be added as an assignment? return responder
mean = halite/5.0 mean_halite_at_all_locations.append((position, mean)) mean_halite_at_all_locations.sort(key=by_halite, reverse=True) dropoffs = mean_halite_at_all_locations[:10] return dropoffs # get the current positions where I have a ship def get_all_ship_positions(input_me): all_ships = [] for shp in input_me.get_ships(): all_ships.append(shp.position) return all_ships center_of_map = Position(round(game.game_map.width/2), round(game.game_map.width/2)) maximum_distance_possible = game.game_map.calculate_distance(center_of_map, Position(0, 0)) #(from center to edge) # logging.info("maximum distance is %s", maximum_distance_possible) target_lock = {} resource_dict = resource_graph(game) # collection of positions that the ships have chosen to take next next_positions = [] # collection of positions where the ships are collecting still_positions = [] # collection of positions where charged ships are charged_positions = [] # As soon as you call "ready" function below, the 2 second per turn timer will start. game.ready("TheDragonSlayerV6") # Now that your bot is initialized, save a message to yourself in the log file with some important information. # Here, you log here your id, which you can always fetch from the game object by using my_id.
def get_halite_move(game, ship, args=None): """ Get a move based on the surrounding cell with the most halite :param args None ... for now. :returns Returns a move letter on success, None if there is a collision. """ if args is None: args = {} move = "o" if DEBUG & (DEBUG_NAV_VERBOSE): logging.info("Nav - ship {} is getting a density based move".format( ship.id)) sorted_blocks = get_best_blocks(game, ship, 3, 3) if not sorted_blocks: old_threshold = ship.mining_threshold ship.mining_threshold = 25 if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} Best block search failed 1. All surrounding cells have halite < threshold({}). Setting mining_threshold to {} and retrying. t{}" .format(ship.id, old_threshold, ship.mining_threshold, game.turn_number)) sorted_blocks = get_best_blocks(game, ship, 3, 3) if not sorted_blocks: move = get_random_move( game, ship) # ToDo: would be better to try a large search radius? if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} Best block search failed 2. All surrounding cells have halite < threshold({}) . Returning random move: {}. t{}" .format(ship.id, ship.mining_threshold, move, game.turn_number)) return move best_bloc_data = sorted_blocks[ 0] # (directional_offset, block, block mean value) max_cell_amount = best_bloc_data[1].get_max() if DEBUG & (DEBUG_NAV_VERBOSE): logging.info( "Nav - ship {} found {} valid halite cells with a the max cell containing {} halite" .format(ship.id, len(sorted_blocks), max_cell_amount)) for best_cell in best_bloc_data[1].get_cells(): if best_cell.halite_amount == max_cell_amount: break move_offset = best_bloc_data[0] new_position = game.game_map.normalize( ship.position.directional_offset(move_offset)) normalized_position = game.game_map.normalize(new_position) cell = game.game_map[normalized_position] if DEBUG & (DEBUG_NAV_VERBOSE): logging.info( "Nav - Ship {} next cell: {}, offset: {}, value: {}".format( ship.id, normalized_position, move_offset, cell.halite_amount)) # # collision resolution # if cell.is_occupied: game.collisions.append( (ship, cell.ship, Direction.convert(move_offset), normalized_position, resolve_halite_move)) # args = alt moves? if DEBUG & (DEBUG_NAV): logging.info( "Nav - ship {} collided with ship {} at {} while moving {}". format(ship.id, cell.ship.id, normalized_position, Direction.convert(move_offset))) return None # # success # cell.mark_unsafe(ship) move = Direction.convert(move_offset) # blocks are guaranteed to have at least 1 cell that is minable. This is critical to avoid getting stuck # between two blocks each of which is never modified. For a 3x3 block, add 'plus_one' assures that we move # far enough to reach the modifiable cell, thus preventing an endless movement between blocks move_plus_one = Position( best_cell.position.x, best_cell.position.y) # go one more move in the same direction if cell.position != move_plus_one: if DEBUG & (DEBUG_NAV): logging.info( "Nav - Ship {} has a plus_one move of {}, halite: {}".format( ship.id, move_plus_one, max_cell_amount)) ship.path.append(move_plus_one) return move
# Start a crusade for ship in me.get_ships(): dropoff = get_closest_dropoff(ship, player, game_map) # Only the most worthless ships can join this crusade # If they have cargos less than half full # If they are close enough to an enemy dropoff to make it # If there not already 6 ships crusading # TODO: remove number constraint, and replace infinite loop with a 10 for loop if ship.halite_amount < constants.MAX_HALITE / 2.0 and game_map.calculate_distance(ship.position, dropoff.position) < constants.MAX_TURNS - (game.turn_number + 10) and len(targets.values()) < 6: # Target a location near the closest enemy dropoff yard = dropoff.position location = yard while location == yard or (targets.values() is not None and location in targets.values()): #logging.info("location is {}".format(location)) #logging.info("locations are {}".format(targets)) location = Position(yard.x, yard.y + random.randrange(-3,4,1) ) # Set the target location targets[ship.id] = location ship_status[ship.id] = "crusader" # logging.info("targets are {}".format(targets)) # If at endgame, toggle it and send the ships home. Crusading ships continue their noble work if game.turn_number == endgame_turn: current_game = Endgame() for ship in me.get_ships(): # The crusaders aren't coming back :) if ship_status[ship.id] != "crusader": ship_status[ship.id] = "returning"
def initTargets(self): cap = self.command.game.game_map.height for i in range(0, cap, 1): for j in range(0, cap, 1): self.targets.append([Position(i, j), None, None])
500: 64 } direction_Order = [Direction.North, Direction.South, Direction.East, Direction.West, Direction.Still] me = game.me game_map = game.game_map NUMBER_OF_PLAYERS = 0 ZONE_OF_INTEREST = [] min_halite_to_be_interesting = 1000 for y in range(map_Settings[constants.MAX_TURNS]): for x in range(map_Settings[constants.MAX_TURNS]): TOTAL_HALITE_START += game_map[Position(x,y)].halite_amount #for row in ZONE_OF_INTEREST: # temp_row_string = '' # for cell in row: # temp_row_string += f'{cell},' # logging.info(temp_row_string) logging.info(f"TOTAL_HALITE_START = {TOTAL_HALITE_START}.") NUMBER_OF_PLAYERS = len(game.players) logging.info(f"NUMBER_OF_PLAYERS = {NUMBER_OF_PLAYERS}.") while True: ship_stuck = {} ship_killing_possibility = {}
# logging.info('Each cell with all parametrs: \n\t\t {}\n'.format(dict_of_cells)) ########################################################################################### game = hlt.Game() game.ready("new_way") go_home = defaultdict(lambda: False) while True: game.update_frame() ########################################################################################### ########################################################################################### # How I can create Entities entity_1 = entity.Entity(0, 20, Position(10, 10)) # I've created Entity object ship = entity.Ship('me', 0, Position(10, 10), 666) # I've created Ship object shipyard = entity.Shipyard(1, 33, Position(30, 30)) dropoff = entity.Dropoff(0, 0, Position(10, 10)) # Our path is hlt.networking --> class Game --> initialize __init__ # game = hlt.Game() me = game.me # From __init__ --> generate Players game_map = game.game_map # From __init__ --> generate GameMap # GameMap generates MapCell object onto the line 178 (def _generate()) game_myid = game.my_id # From __init__ game_players = game.players # From __init__ other_players = [p for pid, p in game.players.items() if pid != game.my_id]
def get_density_move(game, ship): move = "o" if DEBUG & (DEBUG_NAV): logging.info("Nav - ship {} is getting a density based move".format( ship.id)) if not check_fuel_cost(game, ship): return move moves = [] for quadrant in get_surrounding_cell_blocks(game, ship, 3, 3): directional_offset = quadrant[0] block = quadrant[1] if block.get_max() > constants.MAX_HALITE * MINING_THRESHOLD_MULT: moves.append((directional_offset, block, block.get_mean())) sorted_blocks = sorted(moves, key=lambda item: item[2], reverse=True) if len(sorted_blocks) == 0: return get_random_move( game, ship ) # FIX ME FIX ME FIX ME FIX ME FIX ME FIX ME would be better to try a large search radius ??? best_bloc_data = sorted_blocks[0] max_cell = best_bloc_data[1].get_max() bc = best_bloc_data[1].get_cells() for best_cell in bc: if best_cell.halite_amount == max_cell: break move_offset = best_bloc_data[0] if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} moveOffset: {}".format( ship.id, move_offset)) new_position = game.game_map.normalize( ship.position.directional_offset(move_offset)) if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} new_position: {}".format( ship.id, new_position)) normalized_position = game.game_map.normalize(new_position) if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} normalized_position: {}".format( ship.id, normalized_position)) cell = game.game_map[normalized_position] if not cell.is_occupied: move = Direction.convert(move_offset) cell.mark_unsafe(ship) #game.game_map[ship.position].mark_safe() # if we were not able to find a usable dense cell, try to find a random one if move == "o": if DEBUG & (DEBUG_NAV): logging.info( "Nav - Ship {} Collision, trying to find a random move".format( ship.id)) lateral_offsets = Direction.laterals(move_offset) lateral_moves = list( map(lambda direction_offset: Direction.convert(direction_offset), lateral_offsets)) move = get_random_move(game, ship, lateral_moves) if move == "o": if DEBUG & (DEBUG_NAV): logging.info( "Nav - Ship {} Collision, unable to find a move".format( ship.id)) move_plus_one = Position( best_cell.position.x, best_cell.position.y) # go one more move in the same direction if DEBUG & (DEBUG_NAV): logging.info("Nav - Ship {} has a move_plus_one of {}".format( ship.id, move_plus_one)) ship.path.append(move_plus_one) return move