Ejemplo n.º 1
0
    def play_out_by_heuristics(self, context_area, initial_positions,
                               previous_moves, list_players, my_index,
                               manhattan_cache, index_cache):

        start = clock()
        area, walls = self.initialize_play_out(context_area, initial_positions,
                                               previous_moves, list_players,
                                               my_index, index_cache)
        init_time = (clock() - start) * 1000

        current_positions = []
        for i in range(len(list_players)):
            current_positions.append(walls[i][-1])

        msg = ''
        # Check if it is an early end game
        if len(list_players) == 2:
            start = clock()
            voronoi_area, voronoi_spaces = compute_voronoi(
                area, current_positions, [0, 1], index_cache)
            voronoi_time = (clock() - start) * 1000
            #msg += 'voronoi: ' + str(round(voronoi_time,2)) + 'ms'

            if len(
                    walls[list_players[0]]
            ) >= 10 and voronoi_spaces[0] != 0 and voronoi_spaces[1] != 0:
                if not self.is_separeted:
                    r_x, r_y = current_positions[my_index][
                        0], current_positions[my_index][1]
                    g_x, g_y = current_positions[
                        1 - my_index][0], current_positions[1 - my_index][1]

                    #start = clock()
                    #distance = compute_path(area, current_positions[my_index], index_cache[r_x][r_y],current_positions[1 - my_index], index_cache[g_x][g_y], manhattan_cache, index_cache)
                    #path_time = (clock() - start) * 1000
                    #msg += ', path: ' + str(round(path_time,2)) + 'ms'

                    if voronoi_spaces[5] == 0:
                        self.is_separeted = True
                        #self.is_end_game = True

                if self.is_separeted:
                    start = clock()
                    my_articulation_points = detect_articulation_points(
                        area, initial_positions[my_index],
                        index_cache[initial_positions[my_index][0]][
                            initial_positions[my_index][1]], index_cache)
                    ennemy_articulation_points = detect_articulation_points(
                        area, initial_positions[1 - my_index],
                        index_cache[initial_positions[1 - my_index][0]][
                            initial_positions[1 - my_index][1]], index_cache)
                    articulation_separated_time = (clock() - start) * 1000
                    #msg += ', AP sep: ' + str(round(articulation_separated_time,2)) + 'ms'
                else:
                    start = clock()
                    my_articulation_points = detect_articulation_points(
                        area, initial_positions[my_index],
                        index_cache[initial_positions[my_index][0]][
                            initial_positions[my_index][1]], index_cache)
                    ennemy_articulation_points = my_articulation_points
                    articulation_time = (clock() - start) * 1000
                    #msg += ', AP: ' + str(round(articulation_time,2)) + 'ms'

                is_in_territory = False
                if self.is_separeted:
                    is_in_territory = len(my_articulation_points) > 0
                else:
                    for articulation in my_articulation_points:
                        if voronoi_area[articulation] == my_index:
                            is_in_territory = True
                            break

                if is_in_territory:
                    if len(walls[my_index]) < 2:
                        previous_pos = (-1, -1)
                    else:
                        previous_pos = walls[my_index][-2]
                    start = clock()
                    my_spaces = compute_tree_of_chambers(
                        area, voronoi_area, my_articulation_points,
                        current_positions[my_index], previous_pos, index_cache,
                        my_index)
                    tree_time = (clock() - start) * 1000
                    #msg += ', My tree: ' + str(round(tree_time,2)) + 'ms'
                else:
                    my_spaces = voronoi_spaces[my_index]

                is_in_territory = False
                if self.is_separeted:
                    is_in_territory = len(ennemy_articulation_points) > 0
                else:
                    for articulation in ennemy_articulation_points:
                        if voronoi_area[articulation] == (1 - my_index):
                            is_in_territory = True
                            break

                if is_in_territory:
                    if len(walls[1 - my_index]) < 2:
                        enn_previous_pos = (-1, -1)
                    else:
                        enn_previous_pos = walls[1 - my_index][-2]

                    start = clock()
                    ennemy_spaces = compute_tree_of_chambers(
                        area, voronoi_area, ennemy_articulation_points,
                        current_positions[1 - my_index], enn_previous_pos,
                        index_cache, (1 - my_index))
                    tree_time = (clock() - start) * 1000
                    #msg += ', Ennemy tree: ' + str(round(tree_time,2)) + 'ms'
                else:
                    ennemy_spaces = voronoi_spaces[1 - my_index]
            else:
                my_spaces = voronoi_spaces[my_index]
                ennemy_spaces = voronoi_spaces[1 - my_index]

            nb_walls = 0
            for i in walls:
                nb_walls += len(walls[i])

            msg += ', my: ' + str(
                voronoi_spaces[0]) + '/' + str(my_spaces) + ', enn: ' + str(
                    voronoi_spaces[1]) + '/' + str(
                        ennemy_spaces) + ', null: ' + str(
                            voronoi_spaces[5]) + ', wall: ' + str(nb_walls)
            msg += ', total: ' + str(my_spaces + ennemy_spaces +
                                     voronoi_spaces[5] + nb_walls)

            #print(msg, flush=True)
            return my_spaces, my_spaces + ennemy_spaces

        else:
            # Use Voronoi for now
            voronoi_area, voronoi_spaces = compute_voronoi(
                area, current_positions, list_players, index_cache)

            space_max = 0
            winner = None
            for player, space in voronoi_spaces.items():
                if space > space_max:
                    winner = player
            return winner == my_index, voronoi_spaces[my_index]
Ejemplo n.º 2
0
    def compute_direction(self, input):
        splitted = input.split('\n')
        nb_players, my_index = [int(i) for i in splitted[0].split()]

        if self.turn == 0:
            for i in range(nb_players):
                self.list_players.append(i)
                self.list_players_without_me.append(i)

            self.list_players_without_me.remove(my_index)

        for i in range(nb_players):
            # x0: starting X coordinate of lightcycle (or -1 if lost)
            # y0: starting Y coordinate of lightcycle (or -1 if lost)
            # x1: starting X coordinate of lightcycle (can be the same as X0 if you play before this player on the second turn)
            # y1: starting Y coordinate of lightcycle (can be the same as Y0 if you play before this player on the second turn)
            x0, y0, x1, y1 = [int(j) for j in splitted[i + 1].split()]

            if x0 != -1:
                self.current_move[i] = (x1, y1)

                if self.turn == 0:
                    self.previous_move[i] = (-1, -1)
                    self.current_move[i] = (x0, y0)
                    self.wall_cycles[i] = [(x0, y0)]
                    self.area[self.index_cache[x0][y0]] = False

                    if i < my_index:  # players playing before me have already made a move
                        self.previous_move[i] = (x0, y0)
                        self.current_move[i] = (x1, y1)
                        self.wall_cycles[i] = [(x1, y1)]
                        self.area[self.index_cache[x1][y1]] = False
                else:
                    self.previous_move[i] = self.current_move[i]
                    self.current_move[i] = (x1, y1)
                    self.wall_cycles[i].append((x1, y1))
                    self.area[self.index_cache[x1][y1]] = False
            else:
                # If player has lost, remove his wall from the game
                if i in self.current_move:
                    for case in self.wall_cycles[i]:
                        self.area[self.index_cache[case[0]][case[1]]] = True

                    del self.current_move[i]
                    del self.wall_cycles[i]

                    self.list_players.remove(i)
                    self.list_players_without_me.remove(i)

        offsets = [[1, 0], [-1, 0], [0, 1], [0, -1]]
        cur_pos = self.current_move[my_index]

        new_pos = {}
        previous_pos = {}
        for player in self.list_players:
            new_pos[player] = self.current_move[player]
            previous_pos[player] = self.wall_cycles[player][-1]

        max_space = 0
        max_new_direction = (0, 0)
        min_ennemies_space = inf

        for off_x, off_y in offsets:
            new_x = cur_pos[0] + off_x
            new_y = cur_pos[1] + off_y

            if 0 <= new_x < 30 and 0 <= new_y < 20 and self.area[
                    self.index_cache[new_x][new_y]]:
                previous_pos[my_index] = new_pos[my_index]
                new_pos[my_index] = (new_x, new_y)

                voronoi_area, voronoi_spaces = compute_voronoi(
                    self.area, new_pos, self.list_players, self.index_cache)

                articulation_points = {
                }  #Another solution is to detect which players are separated from each other with A*..
                availables_spaces = {}
                for player in self.list_players:
                    articulation_points[player] = detect_articulation_points(
                        self.area, new_pos[player], self.index_cache[
                            new_pos[player][0]][new_pos[player][1]],
                        self.index_cache)

                    if len(articulation_points[player]) == 0:
                        availables_spaces[player] = voronoi_spaces[player]
                    else:
                        availables_spaces[player] = compute_tree_of_chambers(
                            self.area, voronoi_area,
                            articulation_points[player], new_pos[player],
                            previous_pos, self.index_cache, my_index)

                ennemies_space = 0
                max_ennemi_space = 0
                for player in self.list_players_without_me:
                    if availables_spaces[player] > max_ennemi_space:
                        max_ennemi_space = availables_spaces[player]
                    #ennemies_space += availables_spaces[player]
                ennemies_space = max_ennemi_space
                #ennemies_space += voronoi_spaces[5]

                #print('player-' + str(my_index) + ' cur:' + str((cur_pos[0],cur_pos[1])) + ', new:' + str((new_x,new_y)) + ': ' + str(availables_spaces[my_index]) + '/' + str(ennemies_space) + ', ' + str(voronoi_spaces), flush=True)

                #First maximise my own space
                if availables_spaces[my_index] > max_space:
                    max_space = availables_spaces[my_index]
                    max_new_direction = (new_x, new_y)
                    min_ennemies_space = ennemies_space

                #Second minimize my ennemies space
                elif availables_spaces[my_index] == max_space:
                    if ennemies_space < min_ennemies_space:
                        min_ennemies_space = ennemies_space
                        max_new_direction = (new_x, new_y)

        if max_new_direction != (0, 0):
            self.opposite_direction = (max_new_direction[0] * -1,
                                       max_new_direction[1] * -1)

        direction = ''
        if max_new_direction[0] - cur_pos[0] > 0: direction = 'RIGHT'
        elif max_new_direction[0] - cur_pos[0] < 0: direction = 'LEFT'
        elif max_new_direction[1] - cur_pos[1] > 0: direction = 'DOWN'
        elif max_new_direction[1] - cur_pos[1] < 0: direction = 'UP'

        self.turn += 1

        return direction
Ejemplo n.º 3
0
    def compute_direction(self, input):
        splitted = input.split('\n')
        nb_players, my_index = [int(i) for i in splitted[0].split()]

        if self.turn == 0:
            for i in range(nb_players):
                self.list_players.append(i)
                self.list_players_without_me.append(i)

            self.list_players_without_me.remove(my_index)

        for i in range(nb_players):
            # x0: starting X coordinate of lightcycle (or -1 if lost)
            # y0: starting Y coordinate of lightcycle (or -1 if lost)
            # x1: starting X coordinate of lightcycle (can be the same as X0 if you play before this player on the second turn)
            # y1: starting Y coordinate of lightcycle (can be the same as Y0 if you play before this player on the second turn)
            x0, y0, x1, y1 = [int(j) for j in splitted[i + 1].split()]

            if x0 != -1:
                self.current_move[i] = (x1, y1)

                if self.turn == 0:
                    self.previous_move[i] = (-1,-1)
                    self.current_move[i] = (x0, y0)
                    self.wall_cycles[i] = [(x0, y0)]
                    self.area[self.index_cache[x0][y0]] = False

                    if i < my_index:  # players playing before me have already made a move
                        self.previous_move[i] = (x0, y0)
                        self.current_move[i] = (x1, y1)
                        self.wall_cycles[i] = [(x1, y1)]
                        self.area[self.index_cache[x1][y1]] = False
                else:
                    self.previous_move[i] = self.current_move[i]
                    self.current_move[i] = (x1,y1)
                    self.wall_cycles[i].append((x1, y1))
                    self.area[self.index_cache[x1][y1]] = False
            else:
                # If player has lost, remove his wall from the game
                if i in self.current_move:
                    for case in self.wall_cycles[i]:
                        self.area[self.index_cache[case[0]][case[1]]] = True

                    del self.current_move[i]
                    del self.wall_cycles[i]

                    self.list_players.remove(i)
                    self.list_players_without_me.remove(i)

        #Initial state evaluation
        init_voronoi_area, init_voronoi_spaces = compute_voronoi(self.area, self.current_move, self.list_players, self.index_cache)

        init_dist_from_me = {}
        r_index = self.index_cache[self.current_move[my_index][0]][self.current_move[my_index][1]]
        for player in self.list_players_without_me:
            g_index = self.index_cache[self.current_move[player][0]][self.current_move[player][1]]
            init_dist_from_me[player] = compute_path(self.area, self.current_move[my_index], r_index, self.current_move[player],
                                                     g_index, self.manhattan_cache, self.index_cache)

        init_previous_pos = {}
        for player in self.list_players:
            if len(self.wall_cycles[player]) < 2:
                init_previous_pos[player] = (-1,-1)
            else:
                init_previous_pos[player] = self.wall_cycles[player][-2]

        init_articulation_points = {}  # Another solution is to detect which players are separated from each other with A*..
        init_availables_spaces = {}
        for player in self.list_players:
            init_articulation_points[player] = detect_articulation_points(self.area, self.current_move[player],
                                                                     self.index_cache[self.current_move[player][0]][
                                                                         self.current_move[player][1]], self.index_cache)

            if len(init_articulation_points[player]) == 0:
                init_availables_spaces[player] = init_voronoi_spaces[player]
            else:
                init_availables_spaces[player] = compute_tree_of_chambers(self.area, init_voronoi_area,
                                                                             init_articulation_points[player], self.current_move[player],
                                                                             init_previous_pos, self.index_cache, player)
        init_availables_spaces[5] = init_voronoi_spaces[5]

        init_ennemies_space = 0
        for player in self.list_players_without_me:
            init_ennemies_space += init_availables_spaces[player]
        init_ennemies_space += init_voronoi_spaces[5]

        #Evaluation of the different possibles moves
        offsets = [[1, 0], [-1, 0], [0, 1], [0, -1]]
        cur_pos = self.current_move[my_index]

        new_pos = {}
        previous_pos = {}
        for player in self.list_players:
            new_pos[player] = self.current_move[player]
            previous_pos[player] = self.wall_cycles[player][-1]

        max_evaluation = -inf
        max_new_direction = (0,0)

        for off_x, off_y in offsets:
            new_x = cur_pos[0] + off_x
            new_y = cur_pos[1] + off_y

            if 0 <= new_x < 30 and 0 <= new_y < 20 and self.area[self.index_cache[new_x][new_y]]:
                previous_pos[my_index] = new_pos[my_index]
                new_pos[my_index] = (new_x, new_y)

                voronoi_area, voronoi_spaces = compute_voronoi(self.area, new_pos, self.list_players, self.index_cache)

                articulation_points = {} #Another solution is to detect which players are separated from each other with A*..
                availables_spaces = {}
                dist_from_me = {}
                r_index = self.index_cache[new_pos[my_index][0]][new_pos[my_index][1]]
                for player in self.list_players:
                    g_index = self.index_cache[new_pos[player][0]][new_pos[player][1]]
                    dist_from_me[player] = compute_path(self.area, new_pos[my_index], r_index, new_pos[player], g_index,
                                                        self.manhattan_cache, self.index_cache)

                    articulation_points[player] = detect_articulation_points(self.area, new_pos[player], self.index_cache[new_pos[player][0]][new_pos[player][1]], self.index_cache)

                    if len(articulation_points[player]) == 0:
                        availables_spaces[player] = voronoi_spaces[player]
                    else:
                        availables_spaces[player] = compute_tree_of_chambers(self.area, voronoi_area, articulation_points[player], new_pos[player], previous_pos, self.index_cache, player)
                availables_spaces[5] = voronoi_spaces[5]

                ennemies_space = 0
                for player in self.list_players_without_me:
                    ennemies_space += availables_spaces[player]
                ennemies_space += voronoi_spaces[5]

                evaluation = self.scoring(init_availables_spaces, availables_spaces, self.list_players, self.list_players_without_me, my_index,
                                     init_articulation_points, articulation_points, init_dist_from_me, dist_from_me, new_pos, init_dist_from_me, dist_from_me)

                #print('player' + str(my_index) + ' cur:' + str((cur_pos[0],cur_pos[1])) + ' =>' + str((new_x,new_y)) + ': init:' + str(init_availables_spaces[my_index]) + '/' + str(init_ennemies_space) + ', new: ' + str(availables_spaces[my_index]) + '/' + str(ennemies_space) + ', score: ' + str(evaluation ) + ', ' + str(voronoi_spaces), flush=True)

                if evaluation > max_evaluation:
                    max_evaluation = evaluation
                    max_new_direction = (new_x, new_y)

        #print('player' + str(my_index) + ' cur:' + str((cur_pos[0], cur_pos[1])) + ' =>' + str((max_new_direction[0], max_new_direction[1])), flush=True)

        if max_new_direction != (0, 0):
            self.opposite_direction = (max_new_direction[0] * -1, max_new_direction[1] * -1)

        direction = ''
        if max_new_direction[0] - cur_pos[0] > 0: direction = 'RIGHT'
        elif max_new_direction[0] - cur_pos[0] < 0: direction = 'LEFT'
        elif max_new_direction[1] - cur_pos[1] > 0: direction = 'DOWN'
        elif max_new_direction[1] - cur_pos[1] < 0: direction = 'UP'

        self.turn += 1

        return direction
Ejemplo n.º 4
0
    def evaluate(self, manhattan_cache, index_cache):
        '''
        Evaluate the score of the leaf (based on the space remaining for the players)
        '''

        my_index = 0  #TODO: make my_index a variable like for real game

        msg = ''
        start = clock()
        voronoi_area, voronoi_spaces = compute_voronoi(self.area,
                                                       self.positions, [0, 1],
                                                       index_cache)
        voronoi_time = (clock() - start) * 1000
        msg += 'voronoi: ' + str(round(voronoi_time, 2)) + 'ms'

        if not self.is_separeted:
            #r_x, r_y = self.positions[my_index][0], self.positions[my_index][1]
            #g_x, g_y = self.positions[1 - my_index][0], self.positions[1 - my_index][1]

            #start = clock()
            #distance = compute_path(self.area, self.positions[my_index], index_cache[r_x][r_y],
            #                        self.positions[1 - my_index], index_cache[g_x][g_y], manhattan_cache,
            #                        index_cache)
            #path_time = (clock() - start) * 1000
            # msg += ', path: ' + str(round(path_time,2)) + 'ms'

            if voronoi_spaces[2] == 0:
                self.is_separeted = True
                # self.is_end_game = True

        if self.is_separeted:
            start = clock()
            my_articulation_points = detect_articulation_points(
                self.area, self.positions[my_index], index_cache[
                    self.positions[my_index][0]][self.positions[my_index][1]],
                index_cache)
            ennemy_articulation_points = detect_articulation_points(
                self.area, self.positions[1 - my_index],
                index_cache[self.positions[1 - my_index][0]][self.positions[
                    1 - my_index][1]], index_cache)
            articulation_separated_time = (clock() - start) * 1000
            msg += ', AP sep: ' + str(round(articulation_separated_time,
                                            2)) + 'ms'
        else:
            start = clock()
            my_articulation_points = detect_articulation_points(
                self.area, self.positions[my_index], index_cache[
                    self.positions[my_index][0]][self.positions[my_index][1]],
                index_cache)
            ennemy_articulation_points = my_articulation_points
            articulation_time = (clock() - start) * 1000
            msg += ', AP: ' + str(round(articulation_time, 2)) + 'ms'

        is_in_territory = False
        if self.is_separeted:
            is_in_territory = len(my_articulation_points) > 0
        else:
            for articulation in my_articulation_points:
                if voronoi_area[articulation] == my_index:
                    is_in_territory = True
                    break

        if is_in_territory:
            start = clock()
            my_spaces = compute_tree_of_chambers(self.area, voronoi_area,
                                                 my_articulation_points,
                                                 self.positions[my_index],
                                                 self.prev_positions[0],
                                                 index_cache, my_index)
            tree_time = (clock() - start) * 1000
            msg += ', My tree: ' + str(round(tree_time, 2)) + 'ms'
        else:
            my_spaces = voronoi_spaces[my_index]

        is_in_territory = False
        if self.is_separeted:
            is_in_territory = len(ennemy_articulation_points) > 0
        else:
            for articulation in ennemy_articulation_points:
                if voronoi_area[articulation] == (1 - my_index):
                    is_in_territory = True
                    break

        if is_in_territory:
            start = clock()
            ennemy_spaces = compute_tree_of_chambers(
                self.area, voronoi_area, ennemy_articulation_points,
                self.positions[1 - my_index], self.prev_positions[1],
                index_cache, (1 - my_index))
            tree_time = (clock() - start) * 1000
            msg += ', Ennemy tree: ' + str(round(tree_time, 2)) + 'ms'
        else:
            ennemy_spaces = voronoi_spaces[1 - my_index]

        print(msg, flush=True)

        if my_spaces == 0:
            return -inf
        elif ennemy_spaces == 0:
            return inf
        else:
            self.score = my_spaces - ennemy_spaces