Ejemplo n.º 1
0
def height(g_prec, g_next, action):
    """ Heuristique qui retourne la hauteur du dernier coup joué.

       Paramètres :
                - grid_prec : instance State.State : Etat du jeu avant le coup 'action'.
                - grid_next : instance State.State : Etat du jeu après le coup 'action'.
                - action : dictionnaire de la forme {"choose" : kind, "rotate" : rotation, "hor_move" : move} :
                    action à jouer.

        retour :
            int : hauteur du dernier coup"""

    kind = action["choose"]
    rotation = action["rotate"]
    hor_move = action["hor_move"]

    p = Piece.Piece.factory(kind, copy.copy(Piece.Piece.centers_init[kind]))
    etat = State.State(g_prec.grid)
    hauteur = 0
    for _ in range(rotation):
        p.rotate()

    if (State.is_piece_accepted_abscisse(
            p, p.center[0] + p.block_control[0] + hor_move)):
        p.center[0] += hor_move
        r = etat.drop_piece(p, 0)
        for b in p.blocks:
            h_tmp = p.center[1] + b[1]
            if h_tmp > hauteur:
                hauteur = h_tmp
        return hauteur
    return gp.TAILLE_Y_LIMITE - 1
Ejemplo n.º 2
0
def basic_smart_ia(state) :
    """ Stratégie IA aléatoire smart : Elle joue aléatoirement, sauf si elle peut prendre une ligne.
    Dans ce cas, elle complète la ligne;

    Paramètres :
        - state :  instance State.State : etat du jeu

    Retour :
        Un play de la forme {"hor_move":hor_move, "rotate":rotat, "choose":piece}"""
    pieces = copy.copy(state["pieces"])
    scores = []
    compteur = 0

    for kind in pieces :
        for rotation in range(0,4,1) :
            for move in range(-5,7,1) :
                play = {"choose":kind, "rotate":rotation, "hor_move":move}
                grid_tmp = State.State(copy_grid(state["grid"]))
                p = Piece.Piece.factory(kind, copy.copy(Piece.Piece.centers_init[kind]))
                for _ in range(rotation) :
                    p.rotate()
                if(State.is_piece_accepted_abscisse(p, p.center[0] + p.block_control[0] + move)) :
                    p.center[0] += move
                    r = grid_tmp.drop_piece(p, 0)
                    scores += [[play, grid_tmp.score[0]]]

    scores.sort(key=lambda x : x[1], reverse=True)
    best = scores[0][1]
    best_plays = []
    for s in scores :
        if s[1] >= best :
            best_plays += [s]
    play_send = random.choice(best_plays)[0]
    return play_send
Ejemplo n.º 3
0
def erosion(g_prec, g_next, action):
    """ Heuristique : (nombre de line réalisée par action)*(nombre de block de la piece détuits).

    Paramètres :
                - grid_prec : instance State.State : Etat du jeu avant le coup 'action'.
                - grid_next : instance State.State : Etat du jeu après le coup 'action'.
                - action : dictionnaire de la forme {"choose" : kind, "rotate" : rotation, "hor_move" : move} :
                    action à jouer.
       
    retour :
        - int : (nombre de line réalisée par action)*(nombre de block de la piece détuits) """
    kind = action["choose"]
    rotation = action["rotate"]
    hor_move = action["hor_move"]

    #on recréer la piece et l'état précédent
    p = Piece.Piece.factory(kind, copy.copy(Piece.Piece.centers_init[kind]))
    etat = State.State(g_prec.grid)
    hauteur = 0
    for _ in range(rotation):
        p.rotate()

    #si elle dépasse, return 0
    if (not State.is_piece_accepted_abscisse(
            p, p.center[0] + p.block_control[0] + hor_move)):
        return 0

    #on descend la piece
    p.center[0] += hor_move
    while not etat.is_piece_blocked(p):
        p.center[1] -= 1

    #on calcul tous les indices d'ordonne de la piece qui est tombé
    indices_ordonnee_piece = []
    for block in p.blocks:
        indices_ordonnee_piece += [int(p.center[1] + block[1])]
        etat.grid[int(p.center[0] + block[0])][int(p.center[1] +
                                                   block[1])] = p.color
    set_ordonnee_piece = list(set(indices_ordonnee_piece))

    #on compte le nombre de block détruit et le nombre de ligne réalisées.
    nb_block_detruit = 0
    nb_lines_complete = 0
    for j in set_ordonnee_piece:
        line_complete = True
        for i in range(gp.TAILLE_X):
            if etat.grid[i][j] == Block.Block.Empty:
                line_complete = False
        if line_complete:
            nb_lines_complete += 1
            nb_block_detruit += indices_ordonnee_piece.count(j)

    return nb_lines_complete * nb_block_detruit
Ejemplo n.º 4
0
    async def hor_move_piece(self, move):
        """Déplace la pièce courante horizontalement selon move.

        Attributs :
            - move : int / Réprésente le mouvement horizontale de la pièce
                    move > 0 : déplacement à droite
                    move < 0 : déplacement à gauche"""
        if State.is_piece_accepted_abscisse(self.current_piece,
                                            self.current_abscisse + move):
            self.current_abscisse = self.current_abscisse + move
            self.current_piece.center[0] += move
Ejemplo n.º 5
0
    def format_state(self, state):
        """
        Formats the state so that it can be used by tensorforce.
        :param state: dictionary containing information about the game, send by the server.
        :return: list containing the heuristics values. Represents the state.
        """

        state_bis = State.State(state['grid'])
        heuristics_values = self.evaluate_heuristics(self.heuristics, None,
                                                     state_bis, None)

        # selectable pieces as a one-shot vector
        pieces_one_hot = self.format_pieces(state['pieces'])

        # state used by tensorforce
        state_formatted = heuristics_values + pieces_one_hot

        print('{}, {}'.format(heuristics_values, pieces_one_hot))
        return state_formatted
Ejemplo n.º 6
0
    def __init__(self, gid, nb_players, nb_turn, nb_choices):
        """Créer une nouvelle Game.

        Attributs :
            - gid : int / ID de la Game.
            - nb_players : int / Nombre de joueurs dans la partie
            - nb_turn : int / Nombre de tour maximum dans la partie
            - nb_choice : int / Nombre de différentes pieces présentées aux joueurs à chaque tours 

        Retourne :
            - Game : nouvelle game"""
        super().__init__(gid)
        self.grid = State.State()
        self.actual_turn = 0
        self.actual_player = 0
        self.actual_pieces = list()
        self.step = "init"
        self.current_piece = None
        self.current_abscisse = None
        self.nb_turn = nb_turn
        self.nb_choices = nb_choices
        self.nb_players = nb_players
Ejemplo n.º 7
0
def agregate_height(g_prec, g_next, action):
    """ Heuristique : Somme de la hauteur de chaque colonne.
        
        Paramètres :
                - grid_prec : instance State.State : Etat du jeu avant le coup 'action'.
                - grid_next : instance State.State : Etat du jeu après le coup 'action'.
                - action : dictionnaire de la forme {"choose" : kind, "rotate" : rotation, "hor_move" : move} :
                    action à jouer.

        retour :
            - int : somme de la heuteur de chaque colonne de g_next """
    etat = State.State(g_next.grid)
    somme = 0
    for i in range(gp.TAILLE_X):
        ordonnes = list(range(gp.TAILLE_Y_LIMITE - 1))
        ordonnes.reverse()
        for j in ordonnes:
            if etat.grid[i][j] != Block.Block.Empty:
                #première case de la colonne qui n'est pas vide
                somme += j
                break
    return somme
Ejemplo n.º 8
0
    def __init__(self,
                 name,
                 load_file=None,
                 is_stats=False,
                 file_stats=None,
                 train_adversary_level=2,
                 nb_batches=5000,
                 nb_games_per_batch=2,
                 layer_size=15,
                 nb_layers=3):
        """
        :param name: name of the IA/
        :param load_file: path and name of the model to load (without any extension).
        :param is_stats: boolean which tells whether the statistics are enabled.
        :param file_stats: name of the file where the statistics are written.
        :param train_adversary_level: integer indicating the AI to train against (corresponds to level in AICreator).
        :param nb_batches: number of batches. A batch is a group of successive games on which the ratio
        (nb_won_games / nb_games_per_batch) is computed and saved in score.txt.
        :param nb_games_per_batch: number of games per batch.
        :param layer_size: size of a neural network layer.
        :param nb_layers: number of layers in the neural network.
        """

        super().__init__(name, load_file)

        self.current_game_is_finish = None
        self.first_game = True

        # score
        self.score_self_old, self.score_self_new = 0, 0
        self.score_other_old, self.score_other_new = 0, 0
        self.file_scores = open('scores.txt', 'w')

        # AI parameters
        self.heuristics = [
            Heuristic.line_transition, Heuristic.column_transition,
            Heuristic.hidden_empty_cells, Heuristic.wells, Heuristic.holes,
            Heuristic.highest_column, Heuristic.columns_heights
        ]

        state = State.State()
        heuristics_sizes = [
            heuristic(state, state, None) for heuristic in self.heuristics
        ]
        self.nb_heuristics = len(flatten(heuristics_sizes))
        print('self.nb_heuristics', heuristics_sizes)
        self.train_adversary_level = train_adversary_level

        # iteration
        self.nb_batches = nb_batches
        self.nb_games_per_batch = nb_games_per_batch
        self.iteration = 0

        # neural network
        self.layer_size = layer_size
        self.nb_layers = nb_layers
        network_spec = [
            dict(type='dense', size=self.layer_size, activation='relu')
        ] * self.nb_layers

        self.agent = DQNAgent(states_spec={
            'shape': (self.nb_heuristics + NOMBRE_DE_PIECES, ),
            'type': 'float'
        },
                              actions_spec={
                                  'hor_move': {
                                      'type': 'int',
                                      'num_actions': 11
                                  },
                                  'rotate': {
                                      'type': 'int',
                                      'num_actions': 4
                                  },
                                  'choose': {
                                      'type': 'int',
                                      'num_actions': 3
                                  }
                              },
                              network_spec=network_spec)

        # loading of a saved model
        if load_file is not None:
            self.load(load_file)

        # stats
        self.is_stats = is_stats
        self.my_stats = None
        self.file_stats = file_stats
        self.pid_stats = None
Ejemplo n.º 9
0
def best_move(heuristic, weights, state):
    """ Teste toutes les coups et retourne le meilleurs selon les heuristiques et 
        l'état du jeu.
        
        Paramètres :
            - heuristic : liste de fonction : chaque fonction de la liste représente une heuristic
                et est de la forme : fonction(grid_prec, grid_next, action) .
            - weights : liste de poids (float) : cette liste doit être de la même taille que heuristic.
                Chaque poids indicé i dans la liste sera associé à l'heuristique indicée i.
            - state :  instance State.State : représente l'état du jeu au moment de choisir le l'action

        Retour :
            dictionnaire de la forme {"choose" : kind, "rotate" : rotation, "hor_move" : move} :
               Représente la meilleur action calculée en fonction des heuristiques."""
    pieces = copy.copy(state["pieces"])
    scores_valid = []
    scores_non_valid = []
    compteur = 0

    for kind in pieces:
        for rotation in range(0, 4, 1):
            for move in range(-5, 5, 1):
                play = {"choose": kind, "rotate": rotation, "hor_move": move}
                grid_tmp = State.State(copy_grid(state["grid"]))
                grid_prec = State.State(copy_grid(state["grid"]))
                p = Piece.Piece.factory(
                    kind, copy.copy(Piece.Piece.centers_init[kind]))
                for _ in range(rotation):
                    p.rotate()
                if (State.is_piece_accepted_abscisse(
                        p, p.center[0] + p.block_control[0] + move)):
                    p.center[0] += move
                    r = grid_tmp.drop_piece(p, 0)
                    if r:
                        #ne prends pas en compte les coups perdants
                        scores_valid += [[
                            play,
                            evaluate_play(grid_prec, grid_tmp, play, weights,
                                          heuristic)
                        ]]
                    else:
                        #prends tous les coups perdants
                        scores_non_valid += [[
                            play,
                            evaluate_play(grid_prec, grid_tmp, play, weights,
                                          heuristic)
                        ]]

    scores = []
    if len(scores_valid) > 0:
        #On ne veut choisir un play que parmis ceux qui ne font pas perdre
        scores = scores_valid
    else:
        #s'il n'existe pas de play valid, alors on doit en choisir un parmis tous ceux qui font perdre
        scores = scores_non_valid

    scores.sort(key=lambda x: x[1], reverse=True)
    best = scores[0][1]
    best_plays = []
    for s in scores:
        if s[1] >= best:
            best_plays += [s]
    play_send = random.choice(best_plays)[0]
    return play_send
Ejemplo n.º 10
0
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty
               ],
               [
                   Block.Block.Red, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Red, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty, Block.Block.Empty, Block.Block.Empty,
                   Block.Block.Empty
               ]]

    action = {"hor_move": 1, "choose": 'L', "rotate": 1}
    # etat = State.State(my_grid)
    # etat.score[0] = 125
    # etat.score[1] = 168
    # print(etat)
    # etat2 = State.State(my_grid)
    # etat2.score[0] = 125
    # etat2.score[1] = 365
    # print(score(etat, etat2, None))

    etat = State.State(my_grid)
    #print(etat)
    #print("Erosion : ", erosion(etat, None, action))