Ce document est la documentation technique du projet d'études pratiques réalisé dans le cadre de la 3\ieme année de formation à l'\textsc{insa} de Rennes.
Ce document est la documentation technique du projet d'études pratiques ``Jeu du Pingouin'' réalisé dans le cadre de la 3\ieme année de formation à l'\textsc{insa} de Rennes.
Le projet est composé de deux parties: une intelligence artificielle codée en C++ et une interface graphique codée en Javafx; Dans ce document on va souvent appeler l'intelligence artificielle IA ou MCTS (pour Monte Carlo Tree Search, le nom de l'algorithme de recherche utilisé).
Le projet est composé de deux parties: une intelligence artificielle codée en C++ et une interface graphique codée en JavaFX. Dans ce document, les abréviations IA ou MCTS (pour Monte Carlo Tree Search, le nom de l'algorithme de recherche utilisé) vont être souvent utilisées pour évoquer l'intelligence artificielle.
Dans la section dédiée à l'IA on va voir comment on peut implémenter un jeu pour qu'il puisse utiliser le MCTS pour jouer contre un humain et ensuite voir comment le Jeu du Pingouin est implémenté.
Dans la section dédiée à l'IA, nous allons voir comment implémenter un jeu pour qu'il puisse utiliser le MCTS pour jouer contre un humain. Ensuite, nous présenterons comment le Jeu du Pingouin est implémenté.
\subsection*{Auteurs et license}
La partie MCTS a été codée par Pascal \textsc{Garcia}, notre encadrant. Notre groupe a codé la partie Jeu du Pinguin (\verb|penguin.cpp penguin.hpp|) et la partie Interface Graphique (dossier \verb|GUI|).
Toutes les parties sont licenciées par une licence MIT, avec attribution aux auteur respectifs.
Toutes les parties sont sous licence MIT, avec attribution aux auteur respectifs.
Dans l'interface graphique on utilise une bibliothèque JSON pour java: org.json. On peut trouver la librairie à l'adresse \url{http://mvnrepository.com/artifact/org.json/json}: \verb|Copyright (c) 2002 JSON.org|
le copyright complet peut être trouvé dans le fichier \verb|GUI/main/Main.java|
Dans l'interface graphique, une bibliothèque JSON pour Java est utilisée: org.json. La librairie est accessible à l'adresse \url{http://mvnrepository.com/artifact/org.json/json}: \verb|Copyright (c) 2002 JSON.org|
le copyright complet est présent dans le fichier \verb|GUI/main/Main.java|
\newpage
\section{Implémentation d'un jeu}
\subsection{Implémentation d'un nouveau jeu: l'interface game}
Tous les fichiers dont on va parler ici se trouvent dans le dossier \verb|AI/src|
Tous les fichiers évoqués dans cette section se situent dans le dossier \verb|AI/src|.
\paragraph*{}Un jeu jouable par le MCTS n'est rien d'autre qu'une classe qui implémente l'interface \verb|game|, définie dans \verb|game/game.hpp|.
Une fois la nouvelle classe codée, il suffit de changer une ligne dans le fichier \verb|main/main.cpp| pour lancer le jeu. Deux façons sont possibles pour lancer le jeu:
\begin{itemize}
\item\verb|game::run_test_two_players_game(game::MaClasse());| pour lancer un test à deux joueur: le MCTS ne va pas se lancer.
\item\verb|mcts::run_test_mcts_two_players(game::MaClasse());| pour lancer une partie conte le MCTS
\item\verb|mcts::run_test_mcts_two_players(game::MaClasse());| pour lancer une partie contre le MCTS.
\end{itemize}
\paragraph*{} Dans l'interface un joueur est représenté par un nombre sur 8bits (le premier joueur est le joueur 0, le deuxième le joueur 1) et chaque fin de partie
a une valeur qui est utilisée dans la construction de l'arbre de décision (classiquement 1 si le MCTS gagne, -1 s'il perd)
\paragraph*{} Dans l'interface, un joueur est représenté par un nombre sur 8bits (le premier joueur est le joueur 0, le deuxième le joueur 1). Chaque fin de partie
a une valeur qui est utilisée dans la construction de l'arbre de décision (classiquement 1 si le MCTS gagne, -1 s'il perd).
\paragraph*{} Pour implémenter l'interface, il faut implémenter toutes ses fonctions. Elles ne sont pas toutes indispensables ou dépendantes du jeu, donc une partie
d'entre elles pourront être copiées du fichier \verb|penguin.cpp|. Pour les autres on va en donner une liste avec des explications ci-dessous:
\paragraph*{} Pour implémenter l'interface, il faut implémenter toutes ses fonctions. Elles ne sont pas toutes indispensables ou dépendantes du nouveau jeu, c'est pourquoi
une partie d'entre elles pourront être directement copiées du fichier \verb|penguin.cpp|.
Les explications des fonctions indispensables sont listées ci-dessous:
\paragraph*{}
\begin{itemize}
\item\verb|bool end_of_game()| Indique si le jeu est terminé. Peu importe le résultat.
\item\verb|bool end_of_game()| Indique si le jeu est terminé. Indépendamment de son résultat.
\item\verb|int value (uint8 player)| La valeur pour le joueur \verb|player| dans l'état actuel du jeu.
\item\verb|bool won/lost/draw(uint8 player)| Si le joueur \verb|player| a gagné / perdu / fait égalité.
\item\verb|uint8 current_player()| Le jouer qui doit jouer actuellement.
\item\verb|bool won/lost/draw(uint8 player)| Si le joueur \verb|player| a gagné/perdu/fait égalité.
\item\verb|uint8 current_player()| Le joueur dont c'est le tour.
\item\verb|uint16 number_of_moves()| Le nombre total de coups que le joueur actuel peut jouer.
\item\verb|play(uint16 move)| Joue le coup numéro \verb|move| pour le joueur actuel.
\item\verb|string player_to_string(uint8 player)| Représentation d'un joueur de façon compréhensible pour un humain.
\item\verb|string move_to_string(uint16 m)| Représentation d'un coup jouable de façon compréhensible pour un humain.
\item\verb|string to_string()| Représentation de l'état actuel du jeu de façon compréhensible pour un humain.
\end{itemize}
La fonction \verb|move_to_string| est importante, car pour comprendre le coup qu'un joueur humain veut jouer la fonction inverse est utilisée (les différents coups possibles sont mapés).
La fonction \verb|move_to_string| est importante car c'est la représentation que l'humain devra utiliser pour spécifier le coup qu'il veut jouer.
\paragraph*{} Il ne faut pas oublier d'ajouter les nouveaux fichiers dans le makefile!
...
...
@@ -75,29 +76,28 @@ bitboards, pingouins sur 32 bits, calculs de +8 -8 selon la direction ...
\newpage
\section{L'interface graphique}
Tous les fichiers dont on va parler ici se trouvent dans le dossier \verb|GUI/src|. L'interface graphique est développée en Java 1.8 (elle utilise des lambda-expressions) et Javafx
Tous les fichiers évoqués dans cette section se situent dans le dossier \verb|GUI/src|. L'interface graphique est développée en Java 1.8 (elle utilise notamment des lambda-expressions) et JavaFX.
L'interface graphique est codée suivant un modèle MVC (Modèle - Vue - Contrôleur)
L'interface graphique est codée suivant un modèle MVC (Modèle - Vue - Contrôleur).
\paragraph{Le modèle}Le modèle sert à stocker toutes les données du jeu. Les classes sont utilisées comme conteneurs pour stocker les valeurs nécessaires au jeu.
\paragraph{Le modèle:}il sert à stocker toutes les données du jeu. Les classes sont utilisées comme conteneurs pour stocker les valeurs nécessaires au jeu.
La classe principale est la classe \verb|GameState| qui contient la plupart des informations relatives au jeu. Les valeurs sont stockés en forme de bitboards et on utilise des opérations
binaires pour les extraire quand nécessaire.
La classe principale est la classe \verb|GameState| qui contient la plupart des informations relatives au jeu. Les valeurs sont stockés en forme de bitboards et utilise des opérations
binaires sont utilisées pour les extraire quand nécessaire.
Une méthode permet de mettre à jour un object \verb|GameState| à partir du \textsc{json} renvoyé par le \textsc{mcts}.
Une méthode permet de mettre à jour un object \verb|GameState| à partir du JSON renvoyé par le MCTS.
\paragraph{La vue} Le visuel de l'application est décrit dans le fichier \verb|view.fxml|, les différentes cases sont définies avec un positionnement absolu et
ont des id qui vont de \verb|tile0| à \verb|tile59|. Les autres éléments sont aussi positionnés de façon absolue.
\paragraph{La vue:} Le visuel de l'application est décrit dans le fichier \verb|view.fxml|, les différentes cases sont définies avec un positionnement absolu et
ont un id qui vont de \verb|tile0| à \verb|tile59|. Les autres éléments sont aussi positionnés de façon absolue.
Ce n'est pas une façon de faire très propre et on s'en excuse, mais l'interface graphique étant pas l'objectif de notre projet on y a alloué moins de temps.
Cette façon de faire n'est pas celle préconisée (elle n'est pas "propre", nous nous en excusons). L'interface graphique n'étant pas l'objectif initial du projet, nous y avons alloué moins de temps.
\paragraph{Le contrôleur} Le contrôleur s'occupe de faire le lien entre le modèle, la vue et le programme en C++. Pour ce faire à l'initialisation on exécute l'IA
comme sous-processus et on lance un \verb|UpdateThread| qui va s'occuper de modifier le modèle à chaque fois que le sous-processus va écrire quelque chose dans sa sortie standard, et ensuite notifier la vue
\paragraph{Le contrôleur:} il s'occupe de faire le lien entre le modèle, la vue et le programme en C++. Pour ce faire, à l'initialisation, l'IA sera exécutée comme sous-processus. Un \verb|UpdateThread| s'occupera de modifier le modèle à chaque fois que le sous-processus va écrire quelque chose dans sa sortie standard, et ensuite notifier la vue
de se mettre à jour aussi.
La classe \verb|Controller| est la classe ``principale'' du programme: elle s'occupe de créer le plateau, lancer la partie, écouter les clicks du joueur à travers des\verb|EventHandler|, et gérer la fin de partie (sous demande de l'\verb|UpdateThread|).
La classe \verb|Controller| est la classe ``principale'' du programme: elle s'occupe de créer le plateau, lancer la partie, écouter les clics du joueur au travers du\verb|EventHandler|, et de gérer la fin de partie (à la demande de l'\verb|UpdateThread|).
Quand l'interface graphique est fermée (à n'importe quel moment) le sous-processus est tué. Ceci se fait grâce à la fonction Java
Lorsque l'interface graphique est fermée (peu importe le moment) le sous-processus est tué. Ceci se fait grâce à la fonction Java: