Projet d`Informatique Algorithme MinMax en théorie des jeux

publicité
Projet d’Informatique
Algorithme MinMax en théorie des jeux
Contact : [email protected]
4 septembre 2008
1
La stratégie du MinMax
1.1
Contexte général
Ce projet se propose de se familiariser avec un algorithme classique d’intelligence artificielle appelé algorithme MinMax. Cet algorithme est utilisé
pour les jeux à deux joueurs, décrit en théorie des jeux comme étant à information complète et à somme nulle. C’est le cas notamment des échecs,
des dames, de l’othello, du puissance 4, et en règle générale de beaucoup de
jeu de plateau à deux joueurs.
→ Recherche Bibliographique : Qu’est ce qu’un jeu à information
complète ? A somme nulle ? Trouver des exemples de jeux ne satisfaisant pas
ces critères. Quelles peuvent être les méthodes utilisées pour faire jouer un
ordinateur à de tels jeux ?
1.2
1.2.1
Idée générale de l’algorithme MinMax
Notations
On notera dans toute la suite J1 et J2 les deux joueurs, et l’idée de
l’algorithme est ici énoncée indépendemment du type de jeu pourvu que
chaque joueur n’ait, à chaque tour, qu’un nombre fini de coups possibles.
On appelle configuration et on notera θ une description complète de l’état
de la partie à un instant donné : situation du jeu, mais aussi qui doit jouer,
et eventuellement comment (temps imparti, historique des coups, ...).
θ dépend bien évidemment du type de jeu :
– Pour un morpion, c’est simplement l’état de la grille (croix et ronds
déjà joués) ainsi que l’information “C’est à J1/2 de jouer”
– Pour un jeu d’échec, ce sera la position de toutes les pièces sur l’échéquier,
l’information “C’est à J1/2 de jouer”, mais aussi un historique des positions pour éviter les situations sans issues, et éventuellement le temps
de jeu restant par joueur (en cas de partie chronométrée).
1
On suppose également que l’on dispose d’une fonction d’évaluation Φ qui
associe à toute configuration θ une valeur numérique réelle. Φ(θ) quantifie la
certitude de gagner, étant donner l’état θ de la partie : plus la valeur rendue
par Φ est grande, plus la situation θ est favorable. Le but de toute partie
est donc, pour un joueur, de maximiser sa propre fonction d’évaluation et
de minimiser celle de l’autre. D’où l’idée et le nom de l’algorithme MinMax.
1.2.2
Coeur de l’algorithme
Supposons que le jeu soit dans la situation θ, et que J1 ait à jouer un
coup parmi n coups possibles pour amener le jeu dans une nouvelle situation
θi avec i ∈ [1, .., n], comme expliqué sur la figure 1. Si J1 joue un coup qui
θ
J1 joue
θ1
θn
θi
J2 joue
θ1,1
θ1,α1
θi,1
θ1,αi
θn,1
θn,αn
Fig. 1 – Schéma conceptuel du MinMax, expliqué pour un seul niveau d’analyse (i.e sur deux coups)
le mène dans la situation particulière θi , alors J2 , s’il joue intelligement, va
chercher à minimiser la fonction d’évaluation de J1 au coup suivant, c’est
à dire qu’il cherchera, parmi les αi coups à jouer à partir de θi , à choisir
θi,j telle que Φ(θi,j ) soit minimale. J1 à donc interêt à choisir le coup qui va
maximiser ce minimum, et donc de jouer la situation θi telle que :
Φ(θi ) = max min Φ(θi,j )
i∈[1,n] j∈[1,αi ]
1.3
(1)
Recursivité
Ce que nous venons de décrire sur un niveau d’analyse (2 coups), peut
être appliqué de façon récursive sur plusieurs niveaux. En effet, comme le
montre la figure 1 le déroulement d’une partie peut être vu comme un arbre :
– La racine (le sommet de l’arbre) correspond à l’état initial du jeu.
– Les noeuds à profondeurs paire correspondent aux noeuds où J1 doit
jouer, alors que c’est à J2 de jouer aux noeuds de profondeurs impaires.
2
– Chaque arc correspond à un coup joué et associe un état du jeu à la
profondeur
– Aux feuilles, tout en bas de l’arbre, se trouvent les fins de parties.
– Un chemin complet, allant de la racine à une feuille, décrit une partie
possible
On a peut alors étendre l’algorithme, noté F , en le faisant calculer le
meilleur coup à jouer sur n niveaux, de la façon suivante :


si θ est une feuille de l’arbre
Φ(θ)
F (θ) = maxi∈[1,n] F (θi ) si θ est un noeud joueur avec fils θ1,..,n
(2)


mini∈[1,n] F (θi ) si θ est un noeud opposant avec fils θ1,..,n
La récurrence peut être stoppée au bout de n niveaux, afin de jouer le
coup qui, après avoir analysé tous les coups possibles dans une profondeur
2n (car un niveau d’analyse est toujours un coup du joueur J1 et la réponse
de J2 ), va être le plus favorable.
2
2.1
Application au jeu de Nim
Principe du jeu de Nim
Le jeu de Nim (aussi appelé jeu des allumettes), est un jeu où sont
disposées sur le plateau N allumettes, par groupe de k. Chaque joueur peut
prendre autant d’allumettes qu’il le souhaite dans un groupe, puis c’est à
l’autre de jouer. Le joueur qui prend la dernière allumette à gagné.
Fig. 2 – Exemple de jeu de Nim avec 20 allumettes, réparties en 4 tas de 5
2.2
Exemple pratique
Sans rien coder, juste au papier et au stylo, vous réfléchirez aux principe
du MinMax récursif dans le cadre du jeu de Nim, comme détaillé sur la figure
3. Quelle est la fonction d’évaluation Φ pour un tel jeu ? Vous construirez,
sur une feuille, un exemple de partie en développant l’arbre de tous les coups
possibles et en indiquant la valeur de Φ en chaque noeud pour un départ avec
deux tas de 3 et 2 allumettes. Il est important de bien comprendre comment
l’algorithme opère avant d’aller plus loin, n’hésitez pas à me contacter si
vous avez des questions.
3
Fig. 3 – Exemple de l’algorithme du MinMax appliqué au jeu de nim dans
une situation avec 2 tas comportant respectivement 2 et 1 allumettes. On
a l’arbre des coups ainsi que la valeur de Φ pour chaque configuration.
L’algorithme est déroulé sur 2 niveaux d’analyses (4 coups), et l’on constate
que le coup à jouer, pour le joueur 1, est de ne prendre qu’une allumette
pour laisser deux tas de deux.
2.3
Travail demandé
Vous fournirez un code ***commenté*** (en C ou autre) permettant,
avec une interface graphique basique en mode console, de jouer au jeu de
Nim à deux ou seul contre l’ordinateur. Les contraintes à respecter sont les
suivantes :
→ Le choix du nombre d’allumette et de groupes devra être configurable.
Par défaut, on restera sur la version de la Figure 2 (4 groupes de 5),
→ On devra pouvoir choisir le type de jeu voulu (jeu à 2 ou jeu seul
contre l’ordinateur).
→ On devra pouvoir choisir quel joueur va commencer la partie, J1 ou
J2
→ Contre l’ordinateur, on envisagera plusieurs niveaux de difficultés :
Aléatoire
L’ordinateur joue au hasard
Facile
MinMax sur un niveau
Moyen
MinMax sur cinq niveaux
Difficile
MinMax sur dix niveaux
Imbattable ? (facultatif, voir dernière section)
2.4
Quelques pistes pour le code
Les indications données ici ne sont là qu’à titre informatif et il n’est donc
pas obligatoire de les suivre au pieds de la lettre. Réfléchissez juste bien à
votre code avant de vous lancer, et aux différentes fonctions qui vont être
4
nécessaires. Vous pouvez commencer par coder d’abord le jeu dans sa version 2 joueurs humains, utilisant a priori des fonctions telles que :
– config partie() → affiche un menu permettant de selectionner le
nombre de groupe et d’allumettes
– affiche plateau(θ) → affiche la configuration θ du jeu sur la console
– coups possibles(θ) → retourne, pour une configuration θ, tous les
coups jouables possibles. Si un joueur veut jouer un coup qui n’est pas
dans cette liste, le coup doit être interdit.
– joue coup(θ, humain) → joue un coup possible dans la configuration
θ, avec un booléen humain définissant si le coup est joué par un humain (auquel cas on doit prévoir une méthode de saisie du coup), ou
par l’ordinateur (via MinMax).
Pour ce qui est de la partie intelligence artificielle, via le MinMax, vous
aurez besoin de fonctions telles que :
– config level() → affiche un menu pour choisir le niveau de l’IA.
– eval coup(θ) → évalue la valeur de Φ pour une configuration. (On
supposera que Φ est à valeur dans [0, 1], rendant 0 pour un défaite et
1 pour une victoire).
– minmax(θ) → calcule le coup à jouer par minmax pour un seul niveau
d’analyse (2 coups).
– minmax n(θ,n) calcule le coup à jouer par minmax pour une anaylse
sur 2n coups.
3
Pour aller plus loin
Dans cette section, vous trouverez différentes pistes pour continuer le
projet. Vous pouvez les explorer dans l’ordre que vous voulez, en fonction
du temps que vous voulez leur accorder. Toutes font appel à des recherches
actives de votre part, mais je reste disponible pour toutes vos questions. L’algorithme MinMax, de par sa construction, est donc un algorithme exhaustif
qui construit l’arbre de toutes les configurations du jeu (pour une profondeur
d’analyse fixée) et choisit, a chaque coup, celui qui va minimiser les chances
de gagner de l’adversaire. Néanmoins, la construction d’un tel arbre n’est
pas possible dans tous les cas car lorsque trop de branches sont possibles, les
temps de calculs deviennent prohibitifs ! Pour s’en convaincre, vous pouvez
tester la réactivité de votre programme quand le nombre d’allumette devient
grand et/ou que la profondeur de l’analyse du MinMax augmente.
→ Recherche Bibliographique : Quelles sont les stratégies envisagées
pour faire face à ce problème ? Expliquer moi rapidement les intêrets de
5
ce que l’on appelle l’élagage alpha-beta. Que pourrait-on envisager d’autre
comme stratégies pour réduire l’exploration de tous les coups possibles ?
Dans le cas précis du jeu de Nim, n’y a-t-il pas une stratégie de jeu optimale ?
Essayer, si vous avez le temps, de mettre en oeuvre une telle technique
d’optimisation afin de pouvoir rendre votre programme réellement imbattable et rapide quelle que soit la complexité de départ. Vous pouvez aussi
essayer de vous lancer dans une interface graphique du jeu, à vous de voir.
3.1
Compte-rendu
Ce travail n’est important que dans la façon dont vous l’aborderez. Il
est important que vous fassiez quelques recherches par vous même sur l’algorithme, que vous en compreniez son fonctionnement et ses limites. Un
compte rendu intermédiaire sera attendu à mi parcours donc pensez à essayer
de rédiger votre rapport en même temps que votre code. Dans le rapport,
on trouvera une explication des fonctions importantes, une justification des
structures de données mises en place pour représenter l’état du jeu, etc...
Pas la peine de me recopier le code, vous me joindrez les fichiers en annexe.
Pour l’évaluation, seront prises en compte la clareté du rapport et du code,
ainsi que les éventuelles optimisations apportées à l’algorithme MinMax si
vous en avez eut le temps. Un tournoi de Nim entre vos programmes pourra
être envisagé si tout le monde à finit à temps.
Rappel pour le code : L’explication, avec des mots, et les commentaires
du code sont aussi important que le code lui même.
6
Téléchargement