Fonction d’évaluation échiquéenne en VBA

Excel VBA choisit le meilleur coup de pion : EvalMove, EvalDegreeFreedom, CtrlCenter

Excel VBA choisit le meilleur coup de pion : EvalMove, EvalDegreeFreedom, CtrlCenter


Créons une première fonction d’évaluation minimale, parcourons tous les premiers coups des Blancs pour noter chaque coup et trions selon le score. Affinons la fonction d’évaluation.

Une première fonction d’évaluation de la position

Le fichier compressé ChessVba05.zip (22 Ko) contient 3 modules .bas et 5 modules de classe .cls dans le répertoire Source05. La feuille Excel Chess05.xls avec l’échiquier graphique n’est pas fournie. Si vous ne l’avez pas déjà fait, vous pouvez vous construire la feuille de ce classeur Excel en suivant les instructions de l’article : Echiquier graphique dans Excel.

Par rapport au précédent .zip, le module ModChess a plusieurs nouvelles fonctions et procédures. Dans les modules de classes, toutes les méthodes commencent maintenant par une majuscule et les variables par une minuscule.

ChessVba05.zip

Ouvrir le classeur Chess05.xls comprenant l’Echiquier graphique dans Excel et ses modules importés de ChessVba05.zip.

Ouvrir le VBE : Visual Basic Editeur (Alt+F11)

Tout le code VBA est déjà saisi dans le module ModChess.

Des extraits sont cités afin de les commenter.

La fonction d’évaluation minimale est celle qui détecte le mat.

Function EvalMove(ByVal moveThis As Move) As Integer
Const valNoLegal = -10000, valMat = 1000, valCheck = 5

If boardMain.MakeAMove_Internal(moveThis) Then [vert]' Simule le coup à évaluer[/vert] EvalMove = valMat: Exit Function [vert]' Le Roi adverse est Echec et Mat ![/vert] End If End Function



Cependant avec une telle fonction d’évaluation, il faudrait chercher pendant des siècles en simulant tous les coups possibles dans une arborescence énorme.

Plus on rajoute des connaissances échiquéennes dans la fonction d’évaluation, plus on peut réduire la profondeur d’analyse. Comme pour le moment, on ne fait aucun recherche en profondeur, on doit ajouter quelques notions échiquéennes pour trouver le meilleur premier coup des Blancs.

La simulation dans un arbre des coups des deux joueurs est inévitable car la fonction d’évaluation ne sera jamais parfaite. Si on arrivait à créer la fonction d’évaluation parfaite, elle serait trop longue à exécuter. Il y a donc un compromis à trouver entre l’efficacité de la fonction d’évaluation et le temps nécessaire pour la calculer.


Evaluation du matériel

La première idée à laquelle on pense pour évaluer une position est de compter le nombre de pièces qui restent sur l’échiquier.

    valeurPiecesJoueur = joueur.{{SumValuePiece}}()
    valeurPiecesAdversaire = adversaire.SumValuePiece()
    delta = {{valeurPieces}}Joueur - valeurPiecesAdversaire [vert]' Material[/vert]
    score = score + delta



Dans la fenêtre d’Exécution immédiate (Ctrl+G) du VBE d’Excel, copier-coller et valider par ENTER l’initialisation du jeu d’Echecs :

DynamicContext

Calculons la somme des pièces sur l’échiquier pour les Blancs.

? boardMain.playerWhite.SumValuePiece()

3225

Si on recommence l’opération pour les Noirs, on trouvera la même somme des valeurs des pièces car le premier coup ne peut pas être une capture.


Degré de liberté = développement des pièces

Le conseil que l’on trouve dans l’ouverture d’une partie d’Echecs est qu’il faut développer les pièces. Mais comment peut-on traduire la notion de développement d’une pièce dans une fonction d’évaluation ?

Il y a la réponse dans Un générateur de coups d’Echecs en VBA. Le développement des pièces est relatif au nombre de coups dans une position. Plus on a de choix pour jouer, plus on a ses pièces développées. A l’opposé, moins on a de choix, plus les pièces sont enfermées ou se gênent mutuellement.

Pour évaluer le degré de liberté des Blancs, suite à un coup des Blancs, on appelle le générateur de coups des Blancs même si c’est aux Noirs de jouer. Et on compte le nombre de coups dans la liste des coups générés.

Dans le module ModChess, on trouve en ligne 581 la fin de la fonction EvalDegreeFreedom() :

    delta = {{nbrCoup}}Joueur - nbrCoupAdversaire [vert]' Degré de liberté[/vert]
    score = delta
    
[vert]' delta = distanceRoqueJoueur - distanceRoqueAdversaire ' score = score + delta ' ' delta = nbrMoveBlockPawnAdversaire - nbrMoveBlockPawnJoueur ' score = score + coeffBlockedPawn * delta[/vert]
EvalDegreeFreedom = score End Function [vert]' EvalDegreeFreedom[/vert]



Dans la fenêtre d’Exécution immédiate :

DbgBestMove

20 : e4=10, e3=10, d4=8, d3=7, Nf3=3, Nc3=3, c4=2, g4=1, g3=1, c3=1,

Na3=1, b3=1, b4=1, Nh3=1, a4=1, h4=1
, f4=0, f3=-1, a3=-1, h3=-1

Il est intéressant qu’avec juste la notion échiquéenne de degré de liberté, la fonction d’évaluation a noté 1.e2-e4 ! avec le meilleur score. Jouer au jeu d’Echecs, c’est noter chaque coup possible et trier la liste des coups jouables selon le score obtenu.


Contrôle du centre

On pourrait se dire que la fonction d’évaluation est suffisante pour trouver ce meilleur premier coup e4 mais d4 en position 3 devrait être avant e3 car d4 est meilleur que e3. On va donc raffiner progressivement l’évaluation de la position.

Enlever le premier caractère apostrophe de commentaire en début des lignes se trouvant en fin de la fonction d’évaluation EvalMove() pour activer le calcul du contrôle du centre.

    delta = EvalDegreeFreedom(joueur, adversaire)
    score = score + delta
  
controleCentreJoueur = CtrlCenter(joueur) controleCentreAdversaire = {{CtrlCenter}}(adversaire) [vert]' Contrôle du centre[/vert] delta = controleCentreJoueur - controleCentreAdversaire score = score + delta
boardMain.UndoMove_Internal [vert]' Annule le coup simulé pour son évaluation[/vert] EvalMove = score End Function [vert]' EvalMove[/vert]



Dans la fenêtre d’Exécution immédiate :

DbgBestMove

20 : e4=13, d4=12, e3=11, d3=8, Nf3=7, Nc3=7, c4=5, f4=3, c3=2, g3=1,

Na3=1, b3=1, b4=1, Nh3=1, a4=1, h4=1, g4=1
, f3=0, a3=-1, h3=-1

e3 a été rétrogradé en troisième position et on trouve les deux meilleurs coups e4 et d4 en tête.

CtrlCenter() évalue l’occupation du centre grâce à la fonction CanAttack(d5) ou e5 avec un coefficient supérieur à CanAttack(d4) ou e4 par les Blancs pour favoriser l’avance de deux cases des pions centraux.


Distance au petit roque

Activez le calcul de la différence de la distance au roque en fin de la fonction EvalDegreeFreedom().

C’est une mesure qui permet de favoriser la sortie du Cavalier g1 ou du Fou f1 pour faire le petit Roque.

    delta = nbrCoupJoueur - nbrCoupAdversaire [vert]' Degré de liberté[/vert]
    score = delta
    
delta = {{distanceRoque}}Joueur - {{distanceRoque}}Adversaire score = score + delta
[vert]' delta = nbrMoveBlockPawnAdversaire - nbrMoveBlockPawnJoueur ' score = score + coeffBlockedPawn * delta[/vert]
EvalDegreeFreedom = score End Function [vert]' EvalDegreeFreedom[/vert]



Dans la fenêtre d’Exécution immédiate :

DbgBestMove

20 : e4=14, d4=12, e3=12, Nf3=8, d3=8, Nc3=7, c4=5, f4=3, g3=2, c3=2,

Nh3=2, g4=2,
b4=1, Na3=1, a4=1, h4=1, b3=1, f3=0, a3=-1, h3=-1

Le Cavalier en f3 est passé devant d3. C’est une première étape pour faire le petit Roque. Il ne restera plus qu’à sortir le Fol espagnol de sa case de départ Ff1. Si Nf3 a gagné une position par rapport à d3, il reste encore derrière e3.

Notez que l’on a divisé par deux la zone violette des coups évalués à la même note 1 car g3 ou g4 comme e4 ou e3 libère le Fou f1 favorisant le petit Roque.


Pas de fou devant ses pions centraux

Finalement enlevons le dernier commentaire pour activer les lignes sur la différence nbrMoveBlockPawnAdversaire - nbrMoveBlockPawnJoueur.

    delta = nbrCoupJoueur - nbrCoupAdversaire [vert]' Degré de liberté[/vert]
    score = delta
    
delta = distanceRoqueJoueur - distanceRoqueAdversaire score = score + delta
delta = nbrMoveBlockPawnAdversaire - nbrMoveBlockPawnJoueur score = score + coeffBlockedPawn * delta [vert]' Pas de fou devant ses pions centraux[/vert]
EvalDegreeFreedom = score End Function [vert]' EvalDegreeFreedom[/vert]



Notez l’inversion de la différence : Adversaire - Joueur car il s’agit d’une pénalité ou malus.

Dans la fenêtre d’Exécution immédiate :

DbgBestMove

20 : e4=10, d4=8, Nf3=8, e3=8, Nc3=7, c4=5, d3=4, f4=3, g3=2, c3=2,

Nh3=2, g4=2, b4=1, Na3=1, a4=1, h4=1, b3=1, f3=0, a3=-1, h3=-1

Cf3 monte sur le podium avec la médaille de bronze.

En l’état, la fonction d’évaluation est capable de trouver les trois meilleurs coups dans l’ordre e4, d4, Cf3. La fonction a trouvé que les coups de Cavaliers Ch3 ?, Ca3 ?? sur les bords ne sont pas recommandés ainsi que les ouvertures peu orthodoxes g4 ou l’orang-outan b4.

Par contre la fonction ne sait pas prendre en compte l’intérêt de l’ouverture anglaise c4, ou le fianchetto en b3 car on a privilégié dans cette fonction le petit Roque.


Conclusion

Il est assez remarquable que les plus mauvais coups ont été rejetés en fin de liste tels que f3 qui affaiblit le Roi alors que l’on n’a pas représenté la notion de sécurité du Roi. Les coups a3 ?? et h3 ?? sur les ailes méritent leur score négatif car ils ne développent aucunes pièces.

La difficulté est dans l’ajustement des coefficients pour rendre relative telle mesure par rapport une autre. Souvent quand on progresse pour résoudre un problème en ajoutant une nouvelle connaissance échiquéenne, on peut retourner en arrière pour un autre problème qui avait été déjà résolu. Il faut alors faire des compromis.

En final on confiera à la simulation des coups dans l’arbre la recherche du meilleur coup validé en profondeur pour pallier les limites de la fonction d’évaluation.

Par exemple, dans le degré de liberté du Fou, 2. Ff1-a6 ?? est comptabilité au même titre que le Fou espagnol 2. Ff1-b5 ! alors qu’un joueur humain exclurait 2. Fa6 à cause de la capture par le pion des Noirs 2... bxFa6. On pourrait le calculer dans la fonction d’évaluation mais le temps d’exécution de la fonction augmenterait. Lors de la simulation de la réponse Noire 2... bxFa6 dans l’arbre de recherche, le coup 2. Ff1-a6 ?? sera alors fortement pénalisé à cause de la perte du Fou grâce à l’évaluation du matériel.

En pratique, on utilise des bibliothèques d’ouverture (voir Livres d’ouverture) où la fonction d’évaluation et la recherche dans l’arbre sont court-circuitées. On a préféré montrer le principe de la fonction d’évaluation dès le premier coup.


Précédent : Ca bouge sur l’échiquier d’Excel

Suivant :

Posté le 3 septembre 2011 par Matt