예제 #1
0
    def __init__(self, config, state):

        self.x_cells_count = config['x_cells_count']
        self.y_cells_count = config['y_cells_count']
        self.width = config['width']

        # changes inplace further
        self.start_points = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['territory']
        }
        my_position = state['players']['i']['position']
        self.end_point = normalize_point_cords(my_position, self.width)
        self.lines = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['lines']
        }

        self.map = initialize_map(self.x_cells_count, self.y_cells_count)

        for point in self.start_points:
            self.map[point[0]][point[1]] = 0

        self.path_to_territory = []
        self.n_steps_to_save = None
예제 #2
0
    def __init__(self, config, state):
        self.x_cells_count = config['x_cells_count']
        self.y_cells_count = config['y_cells_count']
        self.width = config['width']

        # changes inplace further
        self.visited_points = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['lines']
        }

        my_position = state['players']['i']['position']
        self.prev_location = normalize_point_cords(my_position, self.width)

        self.my_territory = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['territory']
        }

        self.enemy_points = set()
        for player_id, player_info in state['players'].items():
            if player_id != 'i':
                x, y = player_info['position']
                self.enemy_points.add(normalize_point_cords((x, y),
                                                            self.width))

        self.n_steps_to_enemy = None
        self.map = initialize_map(self.x_cells_count, self.y_cells_count)

        self.run_bfs_from_enemies()
예제 #3
0
    def compute_distance_to_second_enemy(self):

        end_points = set()
        for player_id, player_info in self.state['players'].items():
            if player_id != 'i' and player_id != self.enemy_id:
                x, y = player_info['position']
                end_points.add(normalize_point_cords((x, y), width=self.width))

        queue = deque(self.full_tail)
        visited = self.full_tail
        n_steps = 0
        while queue:
            n_steps += 1
            for _ in range(len(queue)):
                point = queue.popleft()

                for neighbor in get_neighbors(point):
                    if neighbor in visited:
                        continue

                    if not in_arena_bounds(neighbor):
                        continue

                    if neighbor in end_points:
                        self.n_steps_to_second_enemy = n_steps
                        return

                    visited.add(neighbor)
                    queue.append(neighbor)
예제 #4
0
    def compute_enemy_distance_to_territory(self):
        """
        считаем расстояние от текущей локации врага до его территории минуя его шлейф

        """
        if self.n_steps_to_enemy is None:
            return None

        enemy_id = self.line_cords_to_id[self.nearest_attack_point]
        self.enemy_id = enemy_id

        start_point = normalize_point_cords(
            self.state['players'][enemy_id]['position'], self.width)
        end_points = {
            normalize_point_cords((x, y), self.width)
            for x, y in self.state['players'][enemy_id]['territory']
        }
        visited = {
            normalize_point_cords((x, y), self.width)
            for x, y in self.state['players'][enemy_id]['lines']
        }

        if start_point in end_points:
            self.n_steps_for_enemy_save = 0
            return

        queue = deque([start_point])
        n_steps = 0

        while queue:
            n_steps += 1
            for _ in range(len(queue)):
                point = queue.popleft()

                for neighbor in get_neighbors(point):
                    if neighbor in visited:
                        continue

                    if not in_arena_bounds(neighbor):
                        continue

                    if neighbor in end_points:
                        self.n_steps_for_enemy_save = n_steps
                        return

                    visited.add(neighbor)
                    queue.append(neighbor)
예제 #5
0
    def on_tick(self, state):
        start_time = time.time()
        self.state = state
        self.risky_location = None
        self.move = None
        self.curr_position = state['players']['i']['position']
        self.curr_territory = state['players']['i']['territory']
        self.have_enemies = True if len(state['players']) > 1 else False

        moves = self.get_valid_moves()

        if self.in_territory_bounds():
            self.move = self.attack_attempt()
            if not self.move:
                self.move = self.leave_territory()
                # если следующая локация находится вне границ территории
                if self.risky_location:
                    threats_map = ThreatsMap(self.config, self.state)
                    if not threats_map.is_save_location(self.risky_location,
                                                        normalize=False):
                        moves = self.filter_dangerous_moves(moves, threats_map)
                        self.move = None
                # попытаться сделать случайный шаг в пределах своей территории
                if not self.move:
                    self.move = random.choice(moves) if moves else LEFT
        else:
            self.move = self.attack_attempt()
            if not self.move:
                routes_maker = RoutesMaker(self.config, self.state,
                                           self.prev_move)

                next_location = routes_maker.get_next_step()
                if next_location:
                    self.move = get_command_from_points(
                        normalize_point_cords(self.curr_position, self.width),
                        next_location)
                if not self.move or self.move not in moves:
                    saves_map = SavesMap(self.config, self.state)
                    saves_map.compute()
                    path_to_territory = saves_map.get_path_to_territory()
                    return_commands = path_to_commands(path_to_territory,
                                                       self.curr_position,
                                                       self.width)
                    if return_commands:
                        self.move, return_commands = follow_path(
                            return_commands)
                    if not self.move:
                        self.move = self.choose_arbitrary_move(
                            moves, saves_map)

        self.prev_move = self.move
        print(
            json.dumps({
                "command": self.move,
                "debug": f"time = {time.time()-start_time}"
            }))
예제 #6
0
    def __init__(self, config, state):
        self.state = state
        self.width = config['width']
        self.x_cells_count = config['x_cells_count']
        self.y_cells_count = config['y_cells_count']

        my_position = state['players']['i']['position']
        self.start_point = normalize_point_cords(my_position, self.width)
        self.lines = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['lines']
        }
        self.territory = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['territory']
        }

        self.line_cords_to_id = {}
        for player_id, player_info in state['players'].items():
            if player_id != 'i':
                for x, y in player_info['lines']:
                    self.line_cords_to_id[normalize_point_cords(
                        (x, y), self.width)] = player_id

        self.enemy_id = None

        self.map = initialize_map(self.x_cells_count, self.y_cells_count)
        self.second_map = initialize_map(self.x_cells_count,
                                         self.y_cells_count)

        self.nearest_attack_point = None

        self.n_steps_to_enemy = None
        self.n_steps_for_enemy_save = None

        self.n_steps_from_attack_point = None
        self.path_to_enemy = None
        self.path_from_enemy = None

        self.final_point = None
        self.full_tail = None

        self.n_steps_to_second_enemy = None
예제 #7
0
    def is_save_location(self, location, normalize=True):
        if normalize:
            x, y = normalize_point_cords(location, self.width)
        else:
            x, y = location

        if (x, y) in self.my_territory:
            return True

        if self.map[x][y] is not None and self.map[x][y] < 4:
            return False
        return True
예제 #8
0
    def __init__(self, config, state, prev_location):
        self.prev_location = prev_location
        self.state = state
        self.width = config['width']
        self.x_cells_count = config['x_cells_count']
        self.y_cells_count = config['y_cells_count']

        self.my_territory = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['territory']
        }
        self.enemy_points = set()
        self.enemy_territory = set()

        my_position = state['players']['i']['position']
        self.curr_pos = normalize_point_cords(my_position, self.width)

        # карта для bfs от вражеской территории до меня и bfs от меня до границ
        self.map = initialize_map(self.x_cells_count, self.y_cells_count)

        for player_id, player_info in state['players'].items():
            if player_id != 'i':
                x, y = player_info['position']
                self.enemy_points.add(normalize_point_cords((x, y),
                                                            self.width))
                for territory_point in player_info['territory']:
                    x_ter, y_ter = normalize_point_cords(
                        territory_point, self.width)
                    self.map[x_ter][y_ter] = 0
                    self.enemy_territory.add((x_ter, y_ter))

        # карта для поиска ближайшего пути до лучшей точки
        self.second_map = initialize_map(self.x_cells_count,
                                         self.y_cells_count)
        self.bordering_points_set = set()
        self.best_point = None
        self.path_to_point = None
예제 #9
0
    def choose_arbitrary_move(self, moves, saves_map):
        moves_info = {}
        for move in moves:
            next_point = get_next_point(self.curr_position, move, self.width)
            next_point = normalize_point_cords(next_point, self.width)
            moves_info[move] = saves_map.get_distance_from_point_to_territory(
                next_point)

        move_chosen = False

        while not move_chosen:
            move = random.choice(moves)
            if moves_info[move] is not None:
                move_chosen = True

        return move
예제 #10
0
    def __init__(self, config, state, prev_move):
        self.state = state
        self.x_cells_count = config['x_cells_count']
        self.y_cells_count = config['y_cells_count']
        self.width = config['width']
        self.prev_move = prev_move

        self.slows = {
            normalize_point_cords(bonus['position'], self.width)
            for bonus in state['bonuses'] if bonus['type'] == 's'
        }

        self.is_slow = any(bonus['type'] == 's'
                           for bonus in state['players']['i']['bonuses'])

        self.remaining_ticks = (
            (2500 - self.state['tick_num']) / config['speed']) - 1
        # self.remaining_ticks = float('inf')

        my_position = state['players']['i']['position']
        self.curr_position = normalize_point_cords(my_position, self.width)

        min_max = MinMax()
        self.my_territory, self.x_set, self.y_set = set(), set(), set()

        for cords in state['players']['i']['territory']:
            x, y = normalize_point_cords(cords, self.width)
            self.my_territory.add((x, y))
            self.x_set.add(x)
            self.y_set.add(y)
            min_max.update((x, y))

        self.min_max = min_max
        self.lines = {
            normalize_point_cords((x, y), self.width)
            for x, y in state['players']['i']['lines']
        }

        for point in self.lines:
            min_max.update(point)

        self.backward_direction = opposite_directions[self.prev_move]
        self.side_directions = SIDE_DIRECTIONS[prev_move]

        self.enemy_points = set()
        self.enemy_territory = set()
        for player_id, player_info in state['players'].items():
            if player_id != 'i':
                for x, y in player_info['territory']:
                    self.enemy_territory.add(
                        normalize_point_cords((x, y), self.width))

                x, y = player_info['position']
                self.enemy_points.add(normalize_point_cords((x, y),
                                                            self.width))

        if not self.enemy_points:
            self.map = initialize_map(self.x_cells_count,
                                      self.y_cells_count,
                                      initial_value=self.remaining_ticks)
        else:
            self.map = initialize_map(self.x_cells_count, self.y_cells_count)
            self.run_bfs_from_enemies()

        self.routes = []