ia02 friscira muller_rapport

14
Jeu de Siam IA02 – Projet 2012 Création d’un système de jeu complet incluant une intelligence artificielle. ELSA FRISCIRA MARC MULLER Les éléphants et les rhinocéros s'affrontent dans une lutte sans merci. Les animaux se déplacent sur le plateau et poussent des montagnes selon des règles de rapport de force bien précises. Le but est d'être le premier joueur qui sort une montagne du plateau.

Upload: elsa-friscira

Post on 14-Jul-2015

144 views

Category:

Documents


0 download

TRANSCRIPT

Jeu de Siam IA02 – Projet 2012

Création d’un système de jeu complet incluant une intelligence

artificielle.

ELSA FRISCIRA

MARC MULLER

Les éléphants et les rhinocéros s'affrontent dans une lutte sans merci. Les animaux se déplacent

sur le plateau et poussent des montagnes selon des règles de rapport de force bien précises. Le

but est d'être le premier joueur qui sort une montagne du plateau.

Jeu de Siam

Introduction

Friscira Elsa – Muller Marc P a g e | 2

INTRODUCTION

Le projet de l’uv IA02 pour le semestre de printemps 2012 consiste à reproduire au moyen du

langage Prolog un logiciel permettant de jouer au jeu du Siam. Ce jeu devra permettre de

s’affronter entres humains ou bien de défier l’intelligence artificielle qui est à développer avec le

jeu.

Le jeu de Siam est un jeu où deux joueurs tentent de pousser des montagnes hors d’un plateau

de taille 5x5. Les pions peuvent se pousser entre eux et tenter de se bloquer. Malgré un plateau

de taille réduite, les possibilités de coup sont légions car chaque pion dispose également d’une

orientation sur sa case.

Nous allons présenter l’organisation de notre programme, décrire le fonctionnement des

prédicats principaux. Nous poursuivrons en présentant l’intelligence artificielle incluse et les

choix d’heuristiques faits. Enfin, nous présenterons les difficultés rencontrées au cours de ce

projet.

SOMMAIRE

Introduction ........................................................................................................................................................................ 2

Sommaire ............................................................................................................................................................................. 2

Note importante ................................................................................................................................................................ 3

I. Organisation du programme .................................................................................................................................... 4

II. Fichier BASE ................................................................................................................................................................... 4

A. Contenu ................................................................................................................................................................. 4

B. Explications ......................................................................................................................................................... 4

C. Structures de données ..................................................................................................................................... 6

III. Fichier Mécanismes ................................................................................................................................................... 7

A. Contenu ................................................................................................................................................................. 7

B. Explications ......................................................................................................................................................... 7

C. Structures de données ..................................................................................................................................... 8

IV. Fichier IA ........................................................................................................................................................................ 9

A. Contenu ................................................................................................................................................................. 9

B. Explications ......................................................................................................................................................... 9

V. Fichier Notation .......................................................................................................................................................... 11

A. Contenu ............................................................................................................................................................... 11

B. Explications ....................................................................................................................................................... 11

C. Conclusion sur l’IA .......................................................................................................................................... 13

Conclusion .......................................................................................................................................................................... 14

Jeu de Siam

Note importante

Friscira Elsa – Muller Marc P a g e | 3

NOTE IMPORTANTE

Nous commençons ce rapport par une note importante : nous nous sommes aperçus très peu de

temps avant le rendu du projet qu’une règle manquait à notre jeu. Il s’agit du fait qu’un pion

puisse rentrer sur le plateau en poussant un pion. Cette règle n’a pas été implémentée suite à

une incompréhension des règles du jeu (nous avions compris l’inverse !). Cependant, nous avons

réalisé notre erreur tard et avons décidé de ne pas la corriger pour deux raisons :

- ajouter si tard une règle dans le jeu serait le meilleur moyen de ne pas pouvoir la tester

entièrement et cela pourrait donc induire des instabilités ou des erreurs dans le jeu

- l’intelligence artificielle a été développée sans connaître cette règle, et il serait long de

lui en faire part tout en optimisant la pondération des heuristiques décrites dans la

partie V. Le jeu contre l’IA serait faussé.

Nous nous excusons donc de ce manque et souhaitons malgré cela un bon jeu au testeur de notre

programme.

Jeu de Siam

I. Organisation du programme

Friscira Elsa – Muller Marc P a g e | 4

I. ORGANISATION DU PROGRAMME

Notre programme Prolog est décomposé en quatre fichiers sources, contenant chacun une

section différente des mécanismes du jeu.

Pour lancer une partie du jeu, il faut tout d’abord charger chacun des quatre fichiers. Une fois

cette opération effectuée, il faut appeler le prédicat lancer_jeu/0 qui va alors présenter un menu

de jeu permettant de tester les différents types de parties !

| ?- lancer_jeu. ----- ----- ----- Choisissez le type de partie : - 1 : Humain contre humain - 2 : Humain contre IA - 3 : IA contre IA - 4 : Humain contre IA (version avec recherche de profondeur 2) - 5 : IA contre IA (version avec recherche de profondeur 2) - 6 : Humain contre IA (version avec recherche de profondeur 3) - 7 : IA contre IA (version avec recherche de profondeur 3) - 8 : Quitter

II. FICHIER BASE

A. Contenu

Le fichier s’intitule en réalité « ia02_friscira_muller_BASE.pl ». Dans ce premier fichier, on

retrouve les prédicats de base du jeu. Il s’agit principalement de :

- Le menu de lancement de partie

- Les prédicats de chargement et de sauvegarde du plateau de jeu

- La boucle de jeu

- Les prédicats d’affichage

B. Explications

1. La boucle de jeu

Le prédicat constituant la boucle de jeu est le prédicat jouer/0.

Ce prédicat commence par charger le plateau courant grâce au prédicat dynamique plateau/1 et

affiche ce plateau au joueur afin qu’il puisse étudier la situation.

Suite à cela, le prédicat utilise repeat/0 pour créer une boucle qui va permettre au joueur de saisir

un coup, jusqu’à ce que celui-ci soit valide. Dans cette boucle, nous demandons au joueur

d’entrer son coup sous la forme [Origine, Destination, Orientation], lisons ce coup et vérifions s’il

est possible grâce à coup_possible/3. Tant que le coup n’est pas possible, le prédicat renvoi faux

et la boucle recommence.

Si le coup est possible, on avance dans le prédicat jouer et on applique le coup du joueur.

Ensuite, on vérifie si le plateau résultant est vainqueur. Si tel est le cas, un message spécial

s’affiche, et la boucle de jeu s’interrompt car \+victoire renvoi faux. Le joueur se retrouve alors

Jeu de Siam

II. Fichier BASE

Friscira Elsa – Muller Marc P a g e | 5

sur le menu général du jeu, prêt à lancer une revanche ! Dans le cas contraire, si \+victoire

renvoi vrai, c'est-à-dire que personne n’a gagné, alors on trouve qui est le prochain jouer grâce à

autre_joueur/2 et on sauvegarde le plateau grâce à set_plateu/1. Enfin, on « cut » pour s’assurer

que l’itération suivante de boucle ne revienne pas en arrière et on rappelle le prédicat jouer/0.

Résumé :

- Chargement et affichage du plateau

- Lecture d’un coup possible

- Application du coup

- Vérification de fin de partie

- Changement de joueur, sauvegarde du plateau

Il existe deux autres versions de la boucle de jeu. La seconde version, nommée jouer_hu_ia/1 est

une version à deux clauses qui permet de jouer une partie humain contre IA. L’une des clauses

permet de faire jouer l’humain, celle-ci est strictement identique à jouer/0. L’autre clause permet

à l’IA de jouer, voici son fonctionnement :

Le début du tour se déroule de la même façon, on charge le plateau et on l’affiche. Ensuite, l’IA

fait appel à trouver_coup/4 qui est un prédicat qui va chercher le meilleur coup à jouer en

cherchant jusqu’à une certaine profondeur de coup. Une fois ce coup trouvé, la boucle de jeu

fonctionne similairement à celle du jeu humain.

La troisième version de la boucle de jeu est la version jouer_ia_ia/1 qui permet de faire jouer

l’ordinateur contre lui-même. Cette version ne contient qu’une seule clause strictement

identique à la clause du jeu IA du prédicat jouer_hu_ia/1 décrit ci-dessus.

Pour plus de détails, consulter le code documenté du fichier BASE.

2. L’affichage du plateau

Quelques mots sur l’affichage du plateau. Celui-ci est possible via l’appel d’afficher_plateau/1. Ce

prédicat en rappelle tout de suite un autre, qui est afficher_plateau/2 en lui communiquant la case

à partir de laquelle commencer l’affichage (le coin supérieur gauche). Le prédicat est constitué

de multiples clauses, qui permettent, au moyen de simples tests, de gérer les débuts et les fins de

lignes. En effet, si on affiche la première case d’une ligne, on trace le contour supérieur des

cases ; dans le même esprit, en fin de ligne, on trace la base de la ligne. Chaque appel réalise un

affichage et fait évoluer le numéro de case courante pour l’appel suivant.

Chaque case est affichée au moyen des prédicats afficher_case/2 et afficher_orientation/1.

Jeu de Siam

II. Fichier BASE

Friscira Elsa – Muller Marc P a g e | 6

Figure 1 : Aperçu du plateau de jeu initial

3. Autres prédicats

Le prédicat lancer_jeu/0 est le prédicat racine, a appeler pour lancer une partie du jeu. Il s’agit

d’un simple menu qui initialise le plateau et donne la main à une boucle de jeu.

Le prédicat membre_alea/2 permet de choisir un élément au hasard dans une liste. Cela sera très

utile pour choisir entre deux coups à jouer semblables.

C. Structures de données

Terminons l’analyse de ce fichier en présentant les structures de données introduites.

1. Plateau de jeu

La structure du plateau de jeu est la suivante : [E,R,M,J], c'est-à-dire une liste contenant tout

d’abord deux listes de pions E et R ou chacun des 5 éléments est de la forme [Case, Orientation].

La liste M est une liste des trois montagnes du jeu, par exemple [32,33,34] initialement. J est une

variable contenant l’identifiant du joueur courant, par exemple ‘e’ pour éléphant ou ‘r’ pour

rhinocéros.

Exemple : [ [ [51,n],[23,s],[0,n],[12,o],[0,n] ],[ [11,e],[0,n],[35,o],[36,s],[0,n] ],[33,55,34],'e'] est

un plateau ou chaque camp dispose de trois pions sur le plateau et ou c’est au joueur e de jouer.

2. Coup

Un coup est une action effectuée par un joueur à un tour. Le coup est représenté par la liste

suivante : [Origine, Destination, Orientation] avec Origine la position du pion à déplacer,

Destination la position à laquelle envoyer ce pion et Orientation l’orientation d’arrivée du pion.

Exemple : [0, 11, 'n'] est le coup qui consiste à entrer un pion sur le plateau en 11 vers le Nord.

Jeu de Siam

III. Fichier Mécanismes

Friscira Elsa – Muller Marc P a g e | 7

III. FICHIER MECANISMES

A. Contenu

Le fichier s’intitule en réalité « ia02_friscira_muller_MECANISMES.pl ». Dans ce second fichier, on

retrouve les prédicats permettant de vérifier que les coups sont possibles et de les appliquer. Il

s’agit principalement de vérifier :

- L’orientation d’un coup

- La validité des déplacements

- L’état de la case d’arrivée

- Les entrées/sorties du plateau

- Les poussées et les rapports de force

- La fin de partie

B. Explications

Le prédicat central de ce nouveau fichier est le prédicat coup_possible/3. Son rôle est de s’assurer

que compte tenu d’un plateau donné, un coup est possible, et, si tel est le cas, de fournir les

mouvements résultants de ce coup (un coup simple ne provoquera qu’un mouvement, un coup

impliquant une poussée provoquera une liste de mouvement de translation). Cette liste de

mouvements fournie par coup_possible/3 sera nommée dans le projet « Impact ».

1. Coup possible, fonctionnement général

Le prédicat contient plusieurs clauses. Outre les trois premières qui sont des cas limites (comme

celui de quitter la partie ou de faire du surplace), intéressons-nous surtout aux deux dernières

clauses. On commence par vérifier le coup c'est-à-dire confirmer qu’il est bien orthogonal. On

s’assure en suite que le pion à déplacer appartient au joueur courant.

Si la case d’arrivée est libre, le prédicat est achevé et on renvoi un impact composé uniquement

du coup. En revanche, si la case de destination est occupée, on est redirigé sur la dernière clause

qui va, elle, engager une démarche pour vérifier que la poussée est possible. Après avoir vérifié

que le pion était déjà dans l’orientation souhaitée pour la poussée, on construit une liste de

poussée (cf. structures de données) et on vérifie que le rapport de force est en la faveur du

joueur, si oui, on renvoie un impact contenant tous les déplacements, sinon, coup_possible est

faux.

La première clause permet de quitter le jeu, la seconde d’empêcher de bouger de 0 vers 0, et la

troisième d’empêcher de rester sur place sans changer d’orientation.

2. Construction de liste de poussée

Il est nécessaire dans le cas d’une poussée de se construire une liste de poussée permettant

d’évaluer le rapport de force. Pour ce faire, on utilise le prédicat construire_liste_pions/4. Ce

prédicat utilise le plateau, l’origine de la poussée et son orientation pour construire notre

fameuse liste de poussée.

Le fonctionnement est le suivant : on étudie la case sur laquelle on est. En fonction de

l’orientation du pion qui s’y trouve, on ajoute à la liste de poussée un élément contenant un ‘+’,

ou ‘-‘, un espace ou un ‘M’. Puis, on calcule quelle est la case suivante dans la poussée et on

Jeu de Siam

III. Fichier Mécanismes

Friscira Elsa – Muller Marc P a g e | 8

rappelle le prédicat. En fin de récursion, on a construit une liste contenant chaque pion sur son

chemin et sa contribution à la poussée (positive, négative, neutre ou montagne).

3. Evaluation du rapport de force

Quand on dispose d’une liste de poussée, on peut utiliser le prédicat calculer_force/3 pour nous

dire si la poussée est possible. Calculer force analyse la liste de poussée dans l’ordre, et entretien

deux compteurs : l’un de force et l’autre de poids. La force augmente et diminue pour chaque

pion ayant une contribution positive ou négative. Le poids augmente pour chaque montagne. A

chaque itération, la force doit surpasser le poids (>=) et en fin de calcul, la force doit être non

nulle.

4. Détection de fin de partie

Le prédicat victoire/4 permet de vérifier si le plateau est vainqueur. Le prédicat commence par

vérifier qu’une montagne a bien été sortie du plateau grâce à montagne_hors_limite/2. Ensuite, il

cherche qui a gagné en commençant par rechercher l’animal « poussant », c'est-à-dire le pion

ayant une contribution positive le plus proche de la montagne qui a été sortie. Enfin, il utilise

equipe/4 pour savoir à quel camp appartenait ce pion.

C. Structures de données

Quelques structures de données nouvelles ont été introduites.

1. Impact

Un impact est une liste de mouvements que l’on récupère grâce à coup_possible/3. Cette liste de

mouvements peut donc ensuite être appliquée à un plateau pour déplacer un par un chacun des

pions impactés par un coup. Chaque élément de la liste Impact contient l’origine du pion, sa

destination et son orientation d’arrivée.

Exemple : [ [11, 21, ‘n’], [21, 31, ’e’], [31, 41, ’e’]] est un Impact ou trois pions sont déplacés, à

priori par le premier d’entre eux, situé en 11.

2. Liste de poussée

Une liste de poussée est une structure permettant de décrire une ligne/colonne de poussée.

Chaque élément est caractérisé par la position du pion, sa contribution à la poussée et son

orientation. L’orientation n’a pas de réelle utilité dans les prédicats qui analysent une poussée,

MAIS permet de très facilement reconstruire un impact à partir d’une liste de poussée.

Exemple : [ [52, '+', 's'], [42, ' ', 'e'], [32, '+', 's'], [22, '-', 'n'], [52, 'M', 'M'] ] est une liste composée

de quatre pions et une montagne. Deux des pions contribuent positivement au mouvement (‘+’)

tandis qu’un autre gêne le mouvement (‘-‘) et qu’un autre est neutre (‘ ‘).

Jeu de Siam

IV. Fichier IA

Friscira Elsa – Muller Marc P a g e | 9

IV. FICHIER IA

A. Contenu

Le fichier s’intitule en réalité « ia02_friscira_muller_IA.pl ». Dans ce troisième fichier, on retrouve

les prédicats en charge de gérer l’intelligence artificielle du jeu, c'est-à-dire :

- Trouver les coups potentiels

- Filtrer les coups pour réduire la combinatoire

- Construire un arbre de recherche du meilleur coup

B. Explications

Nous allons présenter trois prédicats centraux.

1. Trouver les coups possibles

Le prédicat coups_possible/3 est un prédicat en mesure de trouver pour un plateau donné tous

les coups possibles avec leurs impacts respectifs et les plateaux générés par ces impacts.

Ce prédicat commence par lister tous les coups potentiels pour le joueur courant, c’est à dire en

proposant chaque déplacement orthogonal pour chaque pion et chaque orientation (et les cas de

rotation sur place), ainsi que les coups d’entrée ou de sortie de plateau. C’est le prédicat

coups_potentiels_joueur/2 qui créé cette longue liste.

Ensuite, coups_possible demande à réduire la quantité de ces coups. En effet, il existe

naturellement des doublons et des coups inutiles dont on peut se séparer pour atténuer la masse

de coups à envisager. C’est le prédicat reduire_coups_possibles/3 qui est en charge de ce travail, et

qui est expliqué dans la partie suivante (2.).

Une fois les coups filtrés pour ne conserver que ceux qui semblent intéressants, un second

filtrage permet de ne conserver que ceux qui sont effectivement possibles compte tenu de

plateau de jeu. Enfin, le prédicat retourne les coups, impacts et plateaux de jeux issus des coups

possibles.

2. Réduire le nombre de coups possibles

Pour réduire le nombre de coups possibles, le prédicat reduire_coups_possibles/3 utilise une

succession de sous-prédicats effectuant un traitement particulier.

La première tâche est de supprimer les doublons. En effet, si le joueur dispose de deux pions

hors du plateau, la liste des coups potentiels contient les mêmes mouvements pour chacun de

ces pions.

La seconde tâche consiste à nettoyer les coups qui sortent du plateau pour n’en conserver qu’un

par pion, puisqu’il est strictement identique qu’un pion en 55 sorte vers le haut ou vers la droite.

La troisième tâche consiste à supprimer les rotations inutiles. Le prédicat

supprimer_rotations_inutiles/3 analyse pour chaque rotation sur place si elle a du sens. Une telle

rotation n’a du sens que si le pion jouxte une case occupée. Ce choix est discutable car sur plus

d’un tour, une rotation sur place peut changer le déroulement d’une partie, mais nous

choisissons de filtrer ces coups pour réduire la combinatoire du jeu. Si je suis en case 11, s’il n’y

Jeu de Siam

IV. Fichier IA

Friscira Elsa – Muller Marc P a g e | 10

a personne en 12 et en 21, alors je ne conserve pas les coups opérant une rotation sur moi-

même.

La quatrième étape consiste à filtrer les déplacements ayant la même destination mais une

orientation différente afin de ne conserver qu’une orientation d’arrivée si l’on juge que celle-ci

n’a pas d’importance pour le jeu. C'est-à-dire, que si je suis en 31, et que je vais en 32, alors si

toutes les cases autour de mon arrivée sont vides, je ne vais pas garder les quatre coups me

conduisant en 32, mais seulement celui qui conserve mon orientation actuelle. Encore une fois,

ce choix est discutable sur le long terme, mais c’est un sacrifice que nous consentons.

3. Trouver le meilleur coup à jouer

Le prédicat trouver_coup/4 fait le lien avec le dernier fichier, il permet de choisir le meilleur coup

à jouer en analysant les coups possibles futurs.

Fonctionnement général : pour le plateau passé en argument, on va chercher tous les coups

possibles et les plateaux résultants, et on va rappeler notre prédicat récursivement sur chacun

de ces plateaux. On communique au prédicat le niveau courant de recherche. On peut par

exemple appeler le prédicat avec un niveau de 3, et à chaque appel récursif, ce nombre est

décrémenté. On atteindra donc le bas de l’arbre en 3 appels.

Une fois le bas de l'arbre atteint (Niveau = 1), on note chaque plateau possible grâce au prédicat

noter_plateau/2 qui sera présenté en V et on retient le coup qui a généré le meilleur plateau. On

fait remonter sa note au niveau de récursion supérieur.

On utilise ensuite un fonctionnement « minimax ». A chaque niveau, le prédicat va soit retenir la

note maximale, soit la note minimale (avec le coup qui l'a générée et la note en question). En

alternant minimisation et maximisation, on simule le fait que quand A prévoit son coup, il tente

de maximiser ses coups et part du principe que B va maximiser lui aussi ses propres coups, ce

qui revient à minimiser le coup du point de vue de A. Avec un simple test de parité sur Niveau,

on sait donc si le prédicat doit faire le min ou le max des coups possibles à son niveau.

Une fois revenu au niveau le plus haut de la recherche, on retient donc le Coup de base qui a

conduit à la solution (feuille de l'arbre) la plus intéressante au travers d’une recherche à N

niveaux.

Jeu de Siam

V. Fichier Notation

Friscira Elsa – Muller Marc P a g e | 11

V. FICHIER NOTATION

A. Contenu

Le fichier s’intitule en réalité « ia02_friscira_muller_NOTATION.pl ». Dans ce dernier fichier, on

retrouve les prédicats en mesure de noter un plateau en suivant plusieurs heuristiques :

- Le plateau conduit il à une fin de partie ?

- Le joueur dispose-t-il d’un nombre adéquat de pions sur le plateau ?

- Quel joueur domine au sens des poussées ? Existe-t-il un statuquo ?

- Quel joueur dispose des poussées avantageuses, c’est à dire déplaçant une montagne

proche du bord ?

B. Explications

La notation du plateau est effectuée par le prédicat noter_plateau/2 qui associe une note à un

plateau. Pour ce faire, il calcule quatre notes intermédiaires et effectue une somme pondérée de

ces notes. C’est la pondération choisie pour chaque note qui va modifier le comportement de l’IA

et lui dicter ses priorités.

Plus une note est basse, moins le plateau est à l’avantage du joueur courant, plus la note est

haute, plus le joueur a intérêt à atteindre cet état.

Décrivons dans les sous-parties suivantes chacune des quatre heuristiques.

1. Plateau victorieux

C’est le prédicat un_vainqueur/2 qui est responsable du calcul de cette première note. Pour ce

faire, le prédicat vérifie si le plateau est victorieux, et si le joueur gagnant est le joueur courant

ou sn adversaire. La note associée peut donc être de 0 si personne ne gagne, ou de +/-1000 selon

qui gagne. Cette note très haute permet de classer automatiquement un plateau gagant ou

perdant comme le meilleur ou le pire plateau à jouer.

2. Nombre de pions

Nous partons du constat qu’il est possible d’optimiser le nombre de pions de chaque joueur sur

le plateau pour augmenter ses chances de gagner. Le prédicat des_pions_sur_le_plateau/2 permet

d’associer une note qui est fonction du nombre de pion qu’un joueur possède. En effet, avoir peu

de pions est gênant (0,1), en avoir trop est aussi une mauvaise chose ! En effet, si tous mes pions

sont sur le plateau, alors je ne pourrai pas en ajouter un à la dernière minute pour bloquer une

poussée ennemie. Avoir 2, 3 ou 4 pions sur le plateau optimise progressivement la note de

sortie.

En observant l’IA jouer, vous pourrez constater que dans certains cas un peu bouchés de fin de

partie, l’IA pense à sortir un pion pour pouvoir le re-rentrer ailleurs par la suite. De la même

façon, il arrive qu’en début de partie, l’IA cherche à rentrer au moins 2 ou 3 pions avant de

commencer à réellement pousser. Vous pouvez modifier ce comportement en atténuant ou

renforçant la pondération de la note N2 dans le prédicat noter_plateau/2 (de base, 0.3).

Jeu de Siam

V. Fichier Notation

Friscira Elsa – Muller Marc P a g e | 12

3. Balance des poussées

Cette heuristique est constituée du prédicat orientation_visavis_montagnes/2. Ce prédicat un peu

complexe utilise les findall/3 pour se créer une liste de toutes les poussées possibles sur le

plateau pour chaque joueur. Le but est de connaître le nombre de montagnes que chaque joueur

est en mesure de pousser. Chaque poussée donne à son joueur une note positive, et à l’autre une

note négative. Si chaque joueur pousse autant de montagne, alors il y a statuquo.

Cette heuristique permet, entre deux plateaux, de se rendre compte que dans un cas, on bloque

une poussée ennemie (note globale nulle) alors que dans l’autre cas, chaque joueur peut pousser

quelque chose.

La création de ces listes de poussée n’est cependant pas aisée, car même si un pion peut pousser

quelque chose, rien ne nous dit qu’il s’agit forcément d’une montagne ou, pire, que nous sommes

réellement le gagnant dans cette poussée (si un ennemi est dans le bon sens et plus près de la

montagne, c’est à lui qu’appartient cette poussée).

Voici donc un findall utilisé et commenté :

findall(LPions,( member([Ori,Sens],E), % (1) construire_liste_pions([E,R,M,J],LPions,Ori,Sens), % (2) length(LPions,A), % (3) A>1, % (4) calculer_force(LPions,0,0), % (5) derniere_montagne(LPions,Limite), % (6) chercher_camp_pousseur(E,R,M,Ori,Sens,Limite,'e') % (7) ),ListeE),

- 1 : on sélectionne un pion du joueur E

- 2 : on construit la liste de poussée en face de ce pion

- 3 : on calcule la longueur de cette liste

- 4 : si le pion était orienté vers une case vide, la liste de poussée ne contient que lui, on ne

s’y intéresse pas

- 5 : on vérifie que la poussée est possible

- 6 : on récupère la position de la montagne la plus au bord de la poussée (s’il n’y a pas de

montagne, le prédicat est faux, on ne compte pas cette poussée « inutile »).

- 7 : on regarde si la poussée est bien gagnée par un joueur E

On répète la même opération pour le joueur R afin de disposer d’une liste par joueur ! On peut

ensuite appliquer une note à chacun en fonction du nombre de poussées et savoir qui est le

maître de la savane !

Notons qu’avant de comptabiliser les poussées, on supprime les poussées doublons. Exemple : si

j’ai un pion en 11, un pion en 21 et une montagne en 31 et que mes deux pions sont vers le nord,

alors j’aurai une liste de poussée pour le pion 11 et une liste pour le pion 21, ce qui va

augmenter ma note à tort. On utilise donc eliminer_poussees_identiques/3 qui est capable de

détecter et filtrer ces poussées identiques.

Jeu de Siam

V. Fichier Notation

Friscira Elsa – Muller Marc P a g e | 13

Cette heuristique est très utile dans la note finale du plateau, elle permet de montrer à l’IA qu’un

coup va bloquer l’adversaire ou qu’un simple changement d’orientation va retourner la partie. Si

vous désirez jouer sur ce facteur, il est possible de modifier la pondération de la note N3 u

prédicat noter_plateau/2.

4. Intérêt des poussées

L’heuristique précédente ne serait pas complète sans l’ajout important réalisé par

montagnes_en_poussee_proche_bord/2, un prédicat au nom mystérieux mais qui permet d’ajouter

une dimension « d’utilité » au calcul des poussées.

En effet, pousser une montagne depuis le coin inférieur droit vers le haut est moins intéressant

que pousser une montagne située à une ou deux cases du bord. Pour prendre en compte cette

logique, nous réutilisons le mécanisme de construction des listes de poussées décrit dans la

partie ci-dessus mais y ajoutons un calcul de la distance entre la montagne la plus au bord ‘une

poussée et le bord du plateau situé dans la direction de poussée.

Encore une fois, c’est un findall/3 qui va nous permettre de créer ces listes. Pour chaque liste de

poussée, on va utiliser distance_bord_selon_orientation/3 pour connaître la distance restante à

parcourir en faisant bien attention à l’orientation. Exemple : une montagne en 25, poussée vers

le nord est certes à 0 case du bord droit du plateau, mais nous calculons la distance par rapport

au bord haut du plateau, soit 3 cases.

Cette heuristique associe à chaque distance une note qui est inversement proportionnelle au

carré de la distance (15/D² pour être exact).

Cette note permet à l’IA de choisir de pousser les « bonnes » lignes ou colonnes pour maximiser

ses chances de victoire, c’est à dire en rapprochant une montagne du bord, plutôt qu’en poussant

un peu n’importe où.

Vous pouvez jouer sur cette note en modifiant la pondération de la note N4 dans le prédicat

noter_plateau/2 (de base, pondération = 1.5).

C. Conclusion sur l’IA

Comme nous venons de le présenter, l’IA est capable de noter un plateau en tenant compte de

plusieurs paramètres qui nous paraissent importants. Néanmoins, cela ne fait pas de l’IA une

créature (de la savane) pensante et ne saurait lui permettre de jouer à la perfection. Nous

estimons cependant avoir réussi notre pari en proposant une IA qui joue bien, même en ne

prévoyant qu’à un coup !

Il est possible de jouer contre l’IA avec 1, 2 ou 3 coups de prévision. Notons que la version à 3

coups demande un temps de calculs de 5 à 25 secondes par tour. La façon dont l’optimisation est

effectuée est responsable de ce temps :

- Notre notation de plateau est un peu gourmande en calculs vu la masse de données

vérifiées

- Notre algorithme de recherche inspiré du minimax n’est pas optimisé vu qu’il vérifie

tous les coups à chaque niveau plutôt que de générer coup par coup et de s’arrêter dans

une branche en fonction des notes déjà collectées.

Jeu de Siam

Conclusion

Friscira Elsa – Muller Marc P a g e | 14

CONCLUSION

Ce projet P12 aura été très intéressant pour plusieurs raisons. Tout d’abord pour l’importante

auto-formation en Prolog qu’il a constitué pour nous. Le projet nous a été confié alors que nous

ne disposions d’aucune compétence dans le domaine et nous avons donc appris énormément,

du simple affichage du plateau aux algorithmes récursifs de recherches de coups ou de notation

de plateau.

Un autre intérêt du projet a été de pouvoir aborder les mécanismes de programmation logique

permettant de créer un jeu en formalisant ses règles ainsi que de la manière de concevoir une

intelligence artificielle en mesure de générer et de tester des coups.

Néanmoins, nous avons rencontré de nombreuses difficultés : manque de connaissance du

Prolog au début, apprentissage douloureux des mécanismes récursifs, des coupures, difficulté

de débogage des prédicats complexes.

Le bilan de ce projet n’en reste pas moins extrêmement positif !