
Brain Mage
Je pense avoir bien bossé sur BASTON dernièrement, alors je fais une petite pause pour jeter un coup d’œil en arrière sur ce que j'ai réalisé en 2016... Déjà j'écris de moins en moins sur mon blog. Mauvais point. La faute à Facebook...
Et là, dans ce dossier, qu'est-ce que c'est... Mais !?
Pourquoi je n'ai jamais lâché cette nouvelle version de Renju of my Youth ?
Entre la gestion du chemin dans un labyrinthe et la réaction à un stimulus dans un jeu de combat, j'ai pas mal planché sur les décisions que devrait prendre l'ordinateur au Renju, parce qu'on n’est pas forcément toujours deux derrière un écran pour jouer à ce genre de jeu.
Concrètement, je calcule un "poids" pour chaque case libre et l'ordinateur pose sa pierre sur le meilleur résultat, ou sur un des meilleurs résultats en cas d'égalité. Voici ma petite formule pour calculer le poids d'une case. J’utilise une fonction que j'avais déjà mise au point pour déterminer si un coup est interdit ou non. Disons que c'est à l'ordinateur de jouer avec une pierre blanche :

Je scanne dans toutes les directions depuis une case donnée :
A = Nord / Sud
B = Nord-Ouest / Sud-Est
C = Ouest / Est
D = Sud-Ouest / Nord-Est
Le scan renvoie ces trois valeurs :
Line = Nombre de pierres alignées sans trous en comptant la pierre posée
Align = Pareil que Line mais avec un trou minimum d'écart entre deux pierres
Block = Nombre d'extrémités bloquées par une pierre adverse ou un bord
Sur cet exemple, les valeurs obtenues après la pose d'une pierre blanche sont :
A | B | C | D | |
Line | 1 | 1 | 1 | 1 |
Align | 3 | 2 | 1 | 1 |
Block | 0 | 1 | 0 | 0 |
À partir de ces données, je peux calculer un "poids blanc" pour cette case.
La formule est aux choix, je trouve que celle-ci fonctionne pas mal :
poids = 0;
for (sens in 0 ... 4) { poids += updateWeight(sens); }
avec
function updateWeight(sens:Int):Int { return Math.pow(Align[sens] - Block[sens], Line[sens]); }
Le "poids blanc" de cette case vaut donc (3 - 0) ^ 1 + (2 - 1) ^ 1 + (1 - 0) ^ 1 + (1 - 0) ^ 1 = 6
Maintenant imaginons que l'ordinateur pose une pierre noire au lieu d'une blanche pour obtenir le "poids noir" de cette même case:
A | B | C | D | |
Line | 1 | 1 | 1 | 1 |
Align | 1 | 1 | 1 | 1 |
Block | 0 | 0 | 0 | 0 |
Le "poids noir" de cette case vaut (1 - 0) ^ 1 + (1 - 0) ^ 1 + (1 - 0) ^ 1 + (1 - 0) ^ 1 = 4

J'estime que le meilleur endroit pour jouer doit avantager la couleur en cours tout en désavantageant la couleur adverse. Pour notre IA, il faut donc jouer sur une case avec un bon score pour sa couleur blanche, mais aussi avec un bon score pour la couleur noire. Alors pour déterminer quel est le meilleur endroit où jouer, il me suffit d'additionner le "poids blanc" multiplié par un bonus d'attaque et le "poids noir" des cases libres pour obtenir les poids totaux.
Le poids total de cette case est 6 * 2+ 4 = 16
En réitérant cette opération sur toutes les cases libres, je peux déterminer quelle est la meilleure case à jouer pour l'ordinateur.
Attention cependant, cette méthode ne prévoit pas plus d'un coup à l'avance, elle est donc faible contre un "quatre et trois" prévu par l'adversaire. On est loin des systèmes de réseau de neurones artificiels, mais je suis content du résultat : le but n'est pas de programmer un I.A. impossible à battre, mais contre laquelle on peut s'amuser.
Venez-vous mesurer à mon jeu(ou regarder deux IA se friter entre elles)
Un de ces quatre, je vais compiler cette nouvelle version pour Android TV...