Bonjour,
Je me présente : LaeTi nouvellement arrivée dans l’équipe des Dev de DOFUS pour m’occuper de l’IA. IA signifie Intelligence Artificielle, c’est ce qui permet aux monstres de combattre les joueurs. Le but est d’arriver à obtenir des comportements « intelligents ». Il ne suffit pas de dire « sanglier attaque le joueur 1 » ou «Prespic fait toujours telle séquence de sorts». On « mime » en quelque sorte le fonctionnement du cerveau du joueur. Pour cela, on a à notre disposition les mêmes informations qu’un joueur : une liste de sorts, des PA, des PM, une représentation du combat (les positions des différents personnages ainsi que certaines de leurs caractéristiques). Et pendant une réflexion intense, on construit une combinaison alliant sorts et déplacements qui nous donne un bon résultat.
Mon travail consiste donc à coder cette « réflexion intense » (également appelée algorithme) qui est commune à tous les monstres, à tous les sorts, à toutes les maps, à tous les types d’adversaires. Pour l’instant mon travail consiste à prendre un bug (comme le tofu qui ne fait rien au premier tour), à savoir ce qu’il aurait dû faire (bouger :D), à comprendre pourquoi il ne l’a pas fait (il était bien sur cette case) et à corriger ce comportement (il va là où il est aussi bien mais il bouge !!!). En plus, il faut être sûr que modifier ceci ne modifie pas cela (et si la bloqueuse faisait pareille … les sadidas rigoleraient moins !).
L’exemple du tofu est bien sûr un des cas les plus faciles. Le but du raisonnement est de choisir la meilleure combinaison de sorts-déplacements, selon les dégâts que l’on va infliger, notre comportement (le tofu frappe à distance et s’éloigne, le sanglier reste près d’un joueur), les effets er l’ordre des sorts (éviter de placer un arbre puis de faire un sort qui nécessite une ligne de vue, éviter de désenvoûter un allié qui vient de se booster), les zones des sorts (essayer de toucher plusieurs cibles grâce à la zone, même en visant une case vide) ...
Les objectifs : il faut que ça marche pour que Lichen puisse concocter des sorts encore plus diaboliques (qui a dis encore plus tordus …), pour que les comportements des invocations soient plus prévisibles (à vous de bien connaître vos invocations …) et pour que les monstres soient un peu plus difficiles à battre.
Les contraintes : il faut que ça aille vite (un tofu qui met 2 minutes à choisir si il attaque devant ou sur le côté est un tofu buggué !) et que ça marche dans tous les cas possibles.
Le fonctionnement de cet algorithme se découpe en plusieurs algorithmes : sélection des sorts possibles, construction des combinaisons possibles, choix de la meilleure combinaison.
La sélection des sorts possibles se fait en fonction des sorts joués aux tours précédents : si le sort a des contraintes de lancé (intervalle entre 2 lancés de ce sort, nombre d’invocations) on vérifie si à ce tour si on peut le lancer.
La construction des combinaisons possibles est en fonction des PA du monstre et du coût en PA de chaque sort (on a 4 PA, un sort qui coûte 3 PA et un sort qui coûte 2 PA les combinaisons possibles sont : le sort à 3 PA ou 2 fois le sort à 2 PA).
Pour le choix de la meilleure combinaison (c’est là que les choses se compliquent) : on prend chaque sort qu’on va tenter de faire sur chaque cible : on regarde si le sort est applicable à ce type de cible (nombre de lancé sur cette cible, sort à faire sur un allié alors que la cible est ennemi), si la cible est à portée du sort, si la cible est trop loin on regarde si avec nos PM on peut se mettre à portée. Pour les cibles où le sort est possible, on calcule un score qui dépend de l’effet du sort (perte de PdV : on calcule combien on peut en faire, invocation, boost les dommages d’un allié…), on passe au sort suivant de la combinaison et on recommence avec le sort suivant et toutes les cibles, ensuite on reprend le premier sort avec la seconde cible … l’illustration peut aider à comprendre (C = cible, S = score).

A chaque étape un score est calculé et le score final est la somme de ces scores. On calcule donc un score pour le sort 1 sur la cible 1 puis un pour le sort 2 pour la cible 1 et le résultat (S11) est la somme de ces scores.
Le calcul de score est une étape importante car c’est à ce moment là que le monstre prend en compte ses préférences : booster son invocateur plutôt que les alliés, frapper celui qui a une chance de mourir tout de suite, désenvoûter une cible, etc. On met des poids sur chaque action : plus une action est importante (soigner son invocateur), plus le poids de cette action est « lourd », et bien sûr plus une action est à éviter (désenvouter un ennemi qui a uniquement des malus), plus le poids de cette action diminue.
Et pour que ça fonctionne même si vous êtes nombreux, il y a un système de « répartition » des calculs : des threads. Pour l’utilisateur ce fonctionnement est transparent, alors que pour le programme cela permet d’exécuter en même temps plusieurs instructions. Pour résumer, dès qu’un calcul est demandé, c’est le premier thread qui va exécuter ce calcul. Si un autre calcul arrive et que le premier thread n’est pas encore libre, c’est le second qui va gérer ce calcul et ainsi de suite. Dès qu’un calcul est fini, le thread devient à nouveau libre.
Des correctifs et des améliorations sont actuellement sur la béta-test, et oui tester tous les cas possibles est impossible (enfin si mais on a d’autres développements sur le feu, comme un certain Dofus 2.0). En souhaitant prochainement voir ces changements sur les tous les serveurs.