Bonjour,
J'ai codé une IA se basant sur l'algorithme min-max (et élagage alpha/beta) pour un jeu de plateau nommé le jeu du Neutron.
Cependant cet algorithme nécessite une fonction d'évaluation de la "valeur" du plateau afin de déterminer si tel ou tel coup est bon ou pas, j'aimerais donc afin que mon bot soit le meilleur possible que cette fonction soit la plus précise possible.
Cette fonction regarde la position des pions sur le plateau et selon plusieurs coefficients augmente ou diminue la valeur du plateau, pour avoir une bonne fonction je me suis dit qu'à la manière d'une "selection naturelle" je pourrais attribuer aléatoirement des coefficients à plusieurs bot et voir lequel réussit le mieux puis réitérer l'opération en prenant cette fois ci des coefficients voisins de celui qui a bien réussi.
Mais je ne sais pas comment savoir lequel réussit le mieux, dois-je les faire jouer tous les uns contre les autres ? ou bien plutôt tous les faire jouer contre le même bot qui serait le meilleur de la génération précédente ?
les règles (qui sont simples) se trouvent ici : https://fr.wikipedia.org/wiki/Neutron_(jeu)
Je précise que je code sous python et voici mon code :
Code Python : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
A=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
import random
 
 
def possible(pion):
    return  pion[0] >= 0 and pion[0] < 5 and pion[1] < 5 and pion[1] >= 0
 
def libreneutron(plateau):
    """Renvoie le nombre d'espace libre autour du neutron"""
    L, neutron, compteur = [], plateau[10], 0
    for i in A:
        if possible((neutron[0] + i[0], neutron[1] + i[1])) or (neutron[0] + i[0], neutron[1] + i[1]) not in plateau:
            compteur+=1
    return compteur
 
def f(n,plateau):
    """Renvoie la liste positions possibles du n-ieme suite à son déplacement"""
    L = []
    for i in A :
        pion, compteur = plateau[n], 0
        while possible((pion[0] + i[0], pion[1] + i[1])) and not (pion[0] + i[0], pion[1] + i[1]) in plateau :
            pion =(pion[0] + i[0], pion[1] + i[1])
            compteur += 1
        if compteur > 0:
            L += [pion]
    return L
 
def CalcTour(damier, joueur):
    """Renvoie les plateaux possibles après le tour du joueuer en question"""
    neutron, tour = [Damier[:10] + [pion] for pion in f(10, damier)], []
    for jeu in neutron:
        for k in range(5 * joueur, 5 * (joueur + 1)):
            tour += [jeu[:k] + [pion] + jeu[k + 1:] for pion in f(k, jeu)]
    return tour
 
def minmax(plateau, prof, joueur, noeud, j, coeff, alpha, beta):
 
    if perdu(plateau) or prof == 0 :
        return evaluation(plateau, j, coeff)
 
    if noeud == "Max":
        m = -float("inf")
        for jeu in CalcTour(plateau, joueur):
            m = max(m, minmax(jeu, prof - 1, (joueur+1)%2 , "min",j, coeff, alpha, beta))
            if m > beta :
                return m
            alpha = max(alpha , m)
 
    else:
        m = float("inf")
        for jeu in CalcTour(plateau, joueur):
            m = min(m, minmax(jeu, prof - 1, (joueur + 1) % 2, "Max", j, coeff, alpha, beta))
            if m < alpha :
                return m
            beta = min(beta , m)
 
    return m
 
def perdu(plateau):
    return plateau[-1][0] == 0 or plateau[-1][0] == 4 or libreneutron(plateau) == 0
 
 
def evaluation(plateau, j, coeff):
    x1, x2, x3, x4, x5 = coeff
 
    if plateau[-1][0] == 0:
        return -x5 * j + ((j + 1) % 2) * x1
 
    elif plateau[-1][0]==4:
        return x5 * j - ((j + 1) % 2) * x1
 
    score = 0
    t1 = t2 = 5
    for compteur, p in enumerate(plateau[:10]):
        if p[0 ]== 4 * (-j + 1) and compteur < 5:
            score+=x2
            t1-=1
        if p[0]== 4 * (-j + 1) and compteur > 4:
            score+=x3
            t1-=1
        if p[0]==4 * j and compteur < 5:
            score-=x2
            t2-=1
        if p[0] == 4 * j and compteur > 4:
            score -= x3
            t2 -= 1
    score += (- 2 * j + 1) * t1 * x4
    score += (2 * j - 1) * t2 * x4
    score += librerneutron(plateau) * x5
    return score
 
 
def IA(plateau, prof, j, coeff):
    L = []
    tour = CalcTour(plateau, j)
    for jeu in tour:
        L += [minmax(jeu, prof-1,(j + 1) % 2, "min", j, coeff, - float('inf'), float("inf"))]
    indices = [i for i, x in enumerate(L) if x == max(L)]
    position = random.randint(0, len(indices) - 1)
    return tour[indices[position]]
 
def combat(bot1,bot2):
    plateau, compteur = [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (4, 0), (4, 1), (4, 2), (4, 3), (4, 4), (2, 2)], 0
    while not perdu(plateau) and compteur<150:
        if compteur % 2 == 0:
            plateau = IA(plateau, 2, 0, bot1)
        else :
            plateau = IA(plateau, 2, 1, bot2)
        compteur += 1
 
    if plateau[10][0] == 0:
        return 2
    if plateau[10][0] == 4:
        return -2
    if autourneutron(plateau) == 8:
        if (compteur + 1) % 2 == 0:
            return 2
        else :
            return -2
    return 0

Merci de votre lecture et de votre aide