def decide_convert_ship_position(ally_shipyard_positions, ships,
                                 size) -> Optional[Tuple[int]]:

    if len(ally_shipyard_positions) == 0:
        return None

    ships = [
        ship for ship in ships if ship.position not in ally_shipyard_positions
    ]
    far_away_ships = [
        ship for ship in ships if calculate_distance(
            ally_shipyard_positions[0], ship.position, size) >= 8
    ]
    if far_away_ships:
        heaviest_ship = max(far_away_ships, key=lambda ship: ship.halite)
        return heaviest_ship.position

    a_little_far_away_shps = [
        ship for ship in ships if calculate_distance(
            ally_shipyard_positions[0], ship.position, size) >= 5
    ]
    if a_little_far_away_shps:
        heaviest_ship = max(a_little_far_away_shps,
                            key=lambda ship: ship.halite)
        return heaviest_ship.position

    if ships:
        heaviest_ship = max(ships, key=lambda ship: ship.halite)
        return heaviest_ship.position
    return None
Esempio n. 2
0
def decide_direction_in_responsive_area(board, my_position, size, safe_directions, responsive_area, halite_thresholds):
    for halite_threshold in halite_thresholds:
        candidate_positions = [pos for pos in responsive_area if board.cells[pos].halite >= halite_threshold]
        if candidate_positions:
            destination = min(candidate_positions, key=lambda x: calculate_distance(x, my_position, size))
            return decide_direction(safe_directions, my_position, destination, size)
    return np.random.choice(safe_directions)
Esempio n. 3
0
def decide_direction_for_rich_position(board, ship, size, safe_directions, percentile_threshold, search_width):
    threshold = np.percentile([cell.halite for cell in board.cells.values()], percentile_threshold)
    search_range = [((ship.position[0] + i) % size, (ship.position[0] + j) % size) for i in range(search_width) for j in range(search_width)]
    target_map = {pos: board.cells[pos].halite for pos in search_range if board.cells[pos].halite >= threshold}
    if target_map:
        destination = min(target_map.keys(), key=lambda x: calculate_distance(x, ship.position, size))
        return decide_direction(safe_directions, ship.position, destination, size)
    return np.random.choice(safe_directions)
Esempio n. 4
0
def attack_heavy_target_ship2(safe_directions, enemy_ship_halites, my_halite, my_position, enemy_ship_ids, target_enemy_id, size):
    heavier_enemy_ship_positions = {k: v for k, v in enemy_ship_halites.items() if v > my_halite}
    heavier_target_enemy_ship_positions = {pos: halite for pos, halite in heavier_enemy_ship_positions.items() if enemy_ship_ids[pos] == target_enemy_id}
    heavier_target_close_enemy_ship_positions = {pos: halite for pos, halite in heavier_target_enemy_ship_positions.items()
                                                 if calculate_distance(pos, my_position, size) <= 100}
    if heavier_target_close_enemy_ship_positions:
        return attack_heaviest_ship(safe_directions, heavier_target_close_enemy_ship_positions, my_position, size)
    if heavier_target_enemy_ship_positions:
        return attack_heaviest_ship(safe_directions, heavier_target_enemy_ship_positions, my_position, size)
    if heavier_enemy_ship_positions:
        return attack_nearest_ship(safe_directions, enemy_ship_halites, my_position, size)
    return np.random.choice(safe_directions)
Esempio n. 5
0
    def decide_next_action(self):
        MAXIMUM_NUM_OF_SHIPYARDS = 2
        MINE_HALITE_WHEN_HALITE_UNDER_GROUND_IS_OVER = 100
        GO_SHIPYARD_WHEN_CARGO_IS_OVER = 500

        # 「最終ターン」かつ「haliteを500以上積んでいる」ならばconvertする
        if self._step == 398 and self._my_halite > 500:
            return ShipAction.CONVERT, 'final_convert'

        # 動ける場所がないならconvertする
        if len(self._safe_directions) == 0 and self._my_whole_halite > 500:
            return ShipAction.CONVERT, 'negative_convert'
        if len(self._safe_directions) == 0:
            return None, 'nothing_to_do'

        condition1 = len(self._ally_shipyard_ids) < min(self._get_required_shipyards(self._step), MAXIMUM_NUM_OF_SHIPYARDS)
        condition2 = self._my_whole_halite >= 500
        condition3 = 'stay' in self._safe_directions
        condition4 = self._my_position not in self._ally_shipyard_ids.keys()
        condition5 = (self._convert_ship_position is None) or (self._my_position == self._convert_ship_position)
        if condition1 and condition2 and condition3 and condition4 and condition5:
            return ShipAction.CONVERT, 'positive_convert'

        # その場にhaliteがたくさんあるなら拾う
        if self._halite_under > MINE_HALITE_WHEN_HALITE_UNDER_GROUND_IS_OVER and 'stay' in self._safe_directions:
            return None, 'mine'

        if len(self._ally_shipyard_ids) > 0:
            # 「序盤でない」かつ「haliteをたくさん載せている」ならshipyardsに帰る
            condition1 = self._my_halite > GO_SHIPYARD_WHEN_CARGO_IS_OVER and self._step > 80
            # 「shipyardの近くにいる」かつ「haliteをそこそこ載せている」ならshipyardに帰る
            # TODO: 複数shipyardに対応する
            condition2 = self._my_halite > 100 and calculate_distance(self._my_position, list(self._ally_shipyard_ids.keys())[0], self._size) <= 5
            if condition1 or condition2:
                direction = decide_direction_for_shipyard(ally_shipyard_ids=self._ally_shipyard_ids, my_position=self._my_position,
                                                          safe_directions=self._safe_directions, size=self._size)
                return direction_mapper[direction], 'go_home'

        # 閾値以上のhaliteがある場所を探す
        # TODO: boardはあまり使いたくないが・・・
        direction = decide_direction_in_responsive_area(board=self._board, my_position=self._my_position, size=self._size, safe_directions=self._safe_directions,
                                                        responsive_area=self._responsive_area, halite_thresholds=[100, 50, 25, 5, 0])
        return direction_mapper[direction], 'discover_halite'
Esempio n. 6
0
def decide_direction_for_shipyard(ally_shipyard_ids, my_position, safe_directions, size):
    destination = min(ally_shipyard_ids.keys(), key=lambda x: calculate_distance(x, my_position, size))
    return decide_direction(safe_directions, my_position, destination, size)
Esempio n. 7
0
def attack_nearest_shipyard(my_position, size, safe_directions, enemy_shipyard_positions):
    destination = min(enemy_shipyard_positions, key=lambda x: calculate_distance(x, my_position, size))
    return decide_direction(safe_directions, my_position, destination, size)