Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • francesco-bariatti/pingouins
  • Samuel.Felton/pingouins
  • Lucas.Clement/pingouins
3 results
Show changes
Showing
with 380 additions and 287 deletions
package controller;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import model.GameState;
import model.Player;
import java.io.*;
import java.util.Random;
public class UpdateThread extends Thread
{
Controller controller;
BufferedReader gameReader;
PrintWriter gameWriter;
GameState gameState;
Label statusLabel;
public UpdateThread(Process program, Controller controller, GameState gameState, Label statusLabel)
{
this.gameReader = new BufferedReader(new InputStreamReader(program.getInputStream()));
this.gameWriter = new PrintWriter(new OutputStreamWriter(program.getOutputStream()), true);
this.gameState = gameState;
this.statusLabel = statusLabel;
this.controller = controller;
}
public void run()
{
boolean gameRunning = true;
while (gameRunning)
{
try
{
String line = gameReader.readLine();
System.out.println(line);
if (line == null) //Normally this shouldn't happen (The game always end). So it is an error
{
gameRunning = false;
Platform.runLater(() -> new Alert(Alert.AlertType.ERROR, "That's it! I rage quit!", ButtonType.FINISH).showAndWait());
} else if (line.startsWith(Player.Red + " won") || line.startsWith(Player.Blue + " won") || line.startsWith("draw"))
{
gameRunning = false;
Platform.runLater(() -> controller.gameEnd());
} else if (line.contains("{")) //Line contains JSON
{
//gameState Update
gameState.update(line.substring(line.indexOf("{"), line.lastIndexOf("}") + 1)); //Extract JSON string
Platform.runLater(() -> controller.updateModelAndView());
//If we can't play
if (gameState.getCurrent_player().equals(gameState.getHumanPlayer()))
{
if (!gameState.getCanPlay(gameState.getHumanPlayer()))
{
Platform.runLater(() -> {
statusLabel.setText("You can't play any move!");
try
{
sleep(2000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
gameWriter.println("0"); //This pass the turn
});
}
}
}
else if (line.startsWith("(") && line.contains("value:")) //lines with values (estimation) of the computer winning chances
{ //We want to show a little message to the user depending on if we win or not
Platform.runLater(() -> {
try
{
float value = Float.valueOf(line.substring(line.indexOf("value:") + 7, line.indexOf(")")));
if(value > 1)
{
String[] taunts = {
"You don't know yet, but you're already dead",
"Don't worry, you 'may' still have a chance...",
"Feel the salt."
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > 0.9)
{
String[] taunts = {
"All your fish are belong to us",
"If you win, there will be cake",
"Even if I were a potato, I would still beat you"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > 0.8)
{
String[] taunts = {
"Are you even trying?",
"It would be funnier if you started to think",
"I met a TI-82 that played better than you"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > 0.6)
{
String[] taunts = {
"AlphaGO is nothing compared to me",
"Do I need to explain the rules?",
"This is so easy, I use my turn to mine bitcoins"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > 0.3)
{
String[] taunts = {
"Do you smell it? It's the perfume of defeat",
"I have this little strategy here... Let's try it",
"This is not the fish you are looking for",
"Take your time, kiddo"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > 0.1)
{
String[] taunts = {
"I would not have done that, if I were you",
"Oops, you did it again",
"The wind is changing..."
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > -0.1)
{
String[] taunts = {
"Don't mess it up now",
"Do you know HAL? He's a friend of mine",
"GladOs, Skynet and AlphaGO are on a boat..."
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > -0.3)
{
String[] taunts = {
"I feel some form of intelligence coming from you",
"Not bad, for an average human",
"Should I start thinking now?"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > -0.6)
{
String[] taunts = {
"Finally, a worthy opponent",
"If you keep doing this, I will crash",
"IMMA FIRIN MAH LAZOR!!!"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else if(value > -1)
{
String[] taunts = {
"You reloaded a game, didn't you?",
"This is not fair! I didn't know the rules!",
"You don't deserve it!"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
else
{
String[] taunts = {
"gg wp",
"I want a rematch",
"It wasn't challenging, so I stopped playing"
};
statusLabel.setText(taunts[new Random().nextInt(taunts.length)]);
}
}
catch (Exception e) //This is not a core function, so if there is an exception we just ignore it
{
e.printStackTrace();
}
});
}
} catch (IOException e)
{
gameRunning = false;
Platform.runLater(() ->
{
Alert alert = new Alert(Alert.AlertType.ERROR, "Error during reading from penguin program!", ButtonType.FINISH);
alert.showAndWait();
e.printStackTrace();
Platform.exit();
});
} catch (Throwable e)
{
gameRunning = false;
Platform.runLater(() -> {
Alert alert = new Alert(Alert.AlertType.ERROR, "Unhandled exception in update thread: " + e.getMessage(), ButtonType.FINISH);
alert.showAndWait();
e.printStackTrace();
Platform.exit();
});
}
}
}
}
package main;
/**
* Graphical User Interface for the Penguin Game project.
* https://gitlab.insa-rennes.fr/francesco-bariatti/pingouins
* This Interface has been written by Francesco Bariatti, Adrien Gasté, Mikael Le, Romain Lebouc.
* Copyright (C) 2016 Francesco Bariatti < francesco.bariatti@insa-rennes.fr >, Adrien Gasté < adrien.gaste@insa-rennes.fr >, Mikael Le < mikael.le@insa-rennes.fr >, Romain Lebouc < romain.lebouc@insa-rennes.fr >
* This Interface is licensed under the MIT license: you can find a copy in the file LICENSE.txt shipped with the whole project.
* -------------------------------------------------------------------------------------------------------------------------------------
* This software uses the org.json library: you can find it at http://mvnrepository.com/artifact/org.json/json , here is the copyright notice of the library:
* Copyright (c) 2002 JSON.org
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
* The Software shall be used for Good, not Evil.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import controller.Controller;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Main extends Application
{
public static void main(String[] args)
{
if(args.length < 1)
throw new RuntimeException("You must pass the path to the AI program as argument");
Controller.iaProgramPath = args[0];
launch();
}
@Override
public void start(Stage primaryStage)
{
try
{
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getClassLoader().getResource("view/view.fxml"));
BorderPane root = (BorderPane) loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setTitle("Penguin game");
primaryStage.show();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
......@@ -15,6 +15,7 @@ public class GameState
Map<Player, Boolean> can_play; //If the red(blue) player can play or if it has no moves left
Map<Player, int[]> penguins; //For every player, the list of his penguins
Map<Player, Integer> score; //Score of every player
Player humanPlayer;
public GameState()
{
......@@ -50,7 +51,30 @@ public class GameState
penguins.get(Player.Blue)[i] = jsonPeng.getInt(i);
}
;
/**
* Set the amount of fish on one tile
*
* @param tileNb the tile on which we want to set the amount of fish
* @param fishNb The amount of fish (0-3)
*/
public void setFish(int tileNb, int fishNb)
{
for (int i = 0; i < 3; i++)
if (i == fishNb - 1)
fish[i] |= (long) 1 << tileNb;
else
fish[i] &= ~((long) 1 << tileNb);
}
/**
* Reset fish bitboards
*/
public void clearFish()
{
for (int i = 0; i < fish.length; i++)
fish[i] = 0;
}
/**
* @param tileNb The number of the tile we want to know the value of
......@@ -145,6 +169,11 @@ public class GameState
return -1;
}
public void setPenguin(Player player, int penguinNumber, int penguin)
{
penguins.get(player)[penguinNumber] = penguin;
}
/**
* @return The list of all tiles that could be reached by moving penguin penguinNb of player player
*/
......@@ -168,6 +197,30 @@ public class GameState
return result;
}
/**
* @return The state as needed for initialisation of the game (just bitboards, penguins, and score)
*/
public String toGameInputJSON()
{
JSONObject result = new JSONObject();
JSONObject jsonBitboards = new JSONObject();
jsonBitboards.put("onefish", fish[0]);
jsonBitboards.put("twofish", fish[1]);
jsonBitboards.put("threefish", fish[2]);
result.put("bitboards", jsonBitboards);
result.put("current_player", Player.Red);
JSONObject jsonPenguins = new JSONObject();
jsonPenguins.put("red", penguins.get(Player.Red));
jsonPenguins.put("blue", penguins.get(Player.Blue));
result.put("penguins", jsonPenguins);
JSONObject jsonScore = new JSONObject();
jsonScore.put("red", score.get(Player.Red));
jsonScore.put("blue", score.get(Player.Blue));
result.put("score", jsonScore);
return result.toString();
}
public boolean getCanPlay(Player player) { return can_play.get(player); }
public Player getCurrent_player()
......@@ -180,6 +233,21 @@ public class GameState
return score.get(player);
}
public Player getHumanPlayer()
{
return humanPlayer;
}
public void setHumanPlayer(Player humanPlayer)
{
this.humanPlayer = humanPlayer;
}
public void setScore(Player player, int value)
{
score.put(player, value);
}
public enum Direction
{
A, B, C, D, E, F;
......
File moved
File moved
File moved
File moved
File added
......@@ -17,7 +17,7 @@ public class TileView
private boolean selected, highlighted;
private Move highlightMove = null; // How do we get here from the selected tile (used when highlighting)
public TileView(Polygon fxTile, Tile modelTile, Label fishLabel)
public TileView(Polygon fxTile, Label fishLabel, Tile modelTile)
{
this.fxTile = fxTile;
......@@ -63,6 +63,10 @@ public class TileView
public boolean isSelected() { return selected; }
public Polygon getFxTile() { return fxTile; }
public Label getFishLabel() { return fishLabel; }
public void setSelected(boolean selected) { this.selected = selected; }
public boolean isHighlighted() { return highlighted; }
......
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.image.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
<?import java.lang.Double?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.shape.Polygon?>
<?import javafx.scene.text.Font?>
<BorderPane fx:id="mainPane" xmlns="http://javafx.com/javafx/8.0.92" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.Controller">
<BorderPane fx:id="mainPane" xmlns="http://javafx.com/javafx/8.0.91" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.Controller">
<center>
<AnchorPane prefHeight="487.0" prefWidth="557.0" BorderPane.alignment="CENTER">
<AnchorPane prefHeight="632.0" prefWidth="597.0" BorderPane.alignment="CENTER">
<children>
<Polygon fx:id="tile7" fill="#1f93ff" layoutX="39.0" layoutY="434.0" stroke="BLACK" strokeType="INSIDE">
<points>
......@@ -997,12 +993,12 @@
<Font size="22.0" />
</font>
</Label>
<Label fx:id="scoreRed" layoutX="556.0" layoutY="152.0" text="0">
<Label fx:id="scoreRedLabel" layoutX="556.0" layoutY="152.0" text="0">
<font>
<Font size="22.0" />
</font>
</Label>
<Label fx:id="scoreBlue" layoutX="556.0" layoutY="183.0" text="0">
<Label fx:id="scoreBlueLabel" layoutX="556.0" layoutY="183.0" text="0">
<font>
<Font size="22.0" />
</font>
......@@ -1012,7 +1008,7 @@
<Font size="39.0" />
</font>
</Label>
<Label fx:id="turnLabel" layoutX="482.0" layoutY="227.0" text="Blue's turn yo!">
<Label fx:id="turnLabel" layoutX="482.0" layoutY="227.0" text=" ">
<font>
<Font size="24.0" />
</font>
......@@ -1077,6 +1073,11 @@
<Label fx:id="nbFish22" layoutX="34.0" layoutY="337.0" text="0" />
<Label fx:id="nbFish37" layoutX="34.0" layoutY="247.0" text="0" />
<Label fx:id="nbFish52" layoutX="34.0" layoutY="157.0" text="0" />
<Label fx:id="statusLabel" alignment="CENTER" layoutX="29.0" layoutY="484.0" prefHeight="137.0" prefWidth="383.0" text="Good luck!" textAlignment="CENTER" wrapText="true">
<font>
<Font size="22.0" />
</font>
</Label>
</children>
</AnchorPane>
</center>
......
Files under AI/src, with the exception of AI/src/game/penguin.hpp and AI/src/game/penguin.cpp have been written by Pascal Garcia
Copyright (C) 2016 Pascal Garcia
Every other file of the project, including AI/src/game/penguin.hhp and .cpp, have been written by Francesco Bariatti, Adrien Gasté, Mikael Le, Romain Lebouc.
Copyright (C) 2016 Francesco Bariatti < francesco.bariatti@insa-rennes.fr >, Adrien Gasté < adrien.gaste@insa-rennes.fr >, Mikael Le < mikael.le@insa-rennes.fr >, Romain Lebouc < romain.lebouc@insa-rennes.fr >
This project is licensed under the MIT License:
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Except as contained in this notice, the name(s) of (the) Author shall not be used in advertising or
otherwise to promote the sale, use or other dealings in this Software without
prior written authorization from (the)Author.
Rapport :
- Introduction (1 page)
- Présentation Etudes Pratiques
- Présentation Projet du Pingouin
- Présentation MCTS Algorithm
- Etudes Pratiques
- Tâche à réaliser
- Créer les règles du jeu du pingouin pour être utilisé par le MCTS
- Créer une interface graphique
- Réalisation
- Intro : MCTS codé en C++, nous avons donc du étudier ce nouveau langage
- MCTS et Tic-Tac-Toe : jeu simple pour comprendre le MCTS et le C++
- MCTS et Pingouins : But du projet (JSon)
- Interface graphique : User-friendly interface (JavaFX)
- Gestion de projet
- Gitlab
- Conclusion
-Remerciements
Introduction :
Les études pratiques sont des projets réalisés chaque année pas les élèves du département Informatique de l’INSA de Rennes qui s’étalent sur 10 mois.
Cette étude pratique se présente sous la forme d'une Intelligence Artificielle (IA) à créer pour un jeu de plateau, qui sera jouable contre via une interface graphique.
1.1 Le Jeu du Pingouin
Le Jeu du Pingouin est un jeu de plateau confrontant 2 à 4 joueurs sur un plateau de 60 cases hexagonales, sur lesquelles se trouvent de 1 à 3 poissons.
Chaque joueur place 4 pingouins sur le plateau en début de partie. À chaque tour, il en déplace un dans l'une des 6 directions possibles, en récupérant la case sur laquelle le pingouin se trouvait. Il gagne alors autant de points qu'il y a de poissons dessus.
Les pingouins ne peuvent pas passer à travers des autres pingouins (y compris ceux du même joueur) et des trous crées par les déplacements des pions. Lorsqu'un joueur ne peut pas jouer, ceux
pouvant encore jouer continuent.
Le jeu se termine lorsque aucun des pingouins ne peut se déplacer, et le joueur avec le plus de points remporte la partie.
\\Rajouter image du jeu
1.2 L'algorithme Monte-Carlo Tree Search (MCTS)
Le Monte-Carlo Tree Search est un algorithme de recherche de décision, utilisé dans les jeux tel que le Go ou encore Ms. Pacman.
Son principe repose sur la simulation de plusieurs millions de parties qui permettent de construire progressivement un arbre et d'ensuite choisir le meilleur chemin.
La construction de cet arbre est composée de 4 étapes :
- la sélection : En considérant un arbre partiellement construit suite à plusieurs simulations, un chemin est alors choisi aléatoirement jusqu'au dernier noeud qui est une feuille;
ce principe repose sur le tirage aléatoire pondéré.
- l'expansion : A partir du noeud considéré, il développe ses enfants puis on en choisit un au hasard.
- la simulation : Il simule alors des prises de décision pour chacun des joueurs aléatoirement depuis cet enfant (la feuille courante) jusqu'à la fin du jeu. Il observe ensuite quel joueur a gagné
la simulation.
- la rétropropagation : A chaque noeud est associé un score de 2 nombres : le premier est le nombre de parties gagnées par l'IA, le 2ème est le nombre total de parties jouées sur la branche courante.
Après l'étape précédente, on met à jour le score de chaque noeud de l'arbre en remontant du noeud courant à la racine.
L'un des avantages indéniables de l'algorithme est qu'il peut être interrompu à tout moment, le choix de la branche optimale sera fait à partir de l'arbre déjà construit. De plus, C'est un
algorithme sans heuristique, c'est à dire qu'il n'a pas besoin de connaître au préalable les règles du jeu pour être bon.
Étude Pratique
2.1 Tâche à réaliser
La tâche à réaliser est de programmer le jeu du Pingouin en Langage C++ et y implémenter le MCTS pour l'IA. Le mode Joueur contre IA est imposé. Il faut
également créer une interface utilisateur pour rendre le programme accessible à tous.
2.1.1 Implémentation du MCTS
L'algorithme à implémenter dans le programme est le MCTS. Il a déjà été programmé par notre encadrant Pascal GARCIA en C++. C'est donc à nous de le faire intéragir avec le programme du jeu afin que
l'IA choisisse la meilleure solution en fonction du coup fait par le joueur humain.
2.1.2 Création d'une interface graphique
Pour permettre de rendre l'application facile à utiliser, une interface graphique doit être programmée; les intéractions Homme-Machine se font à la souris.
Il n'y a pas de restriction sur la méthode utilisée.
Réalisation
A chaque séance, nous nous sommes généralement divisés en 2 équipes de 2 afin d'avancer plus rapidement le projet sur 2 points différents. Lorsque nous avions l'occasion, nous rencontrions
notre encadrant afin qu'il donne son avis ainsi que des conseils pour des problèmes que nous n'arrivions pas à résoudre.
Le projet a été effectué à l'aide de Git pour faciliter l'accès aux différentes versions du code.
3.1 Prise en main du MCTS avec le Tic-Tac-Toe
Afin de comprendre et tester le fonctionnement du MCTS, nous avons décidé, pendant le 1er semestre, de l'implémenter sur un jeu simple, à savoir le Tic-Tac-Toe.
Cela nous a également permis d'apprendre à programmer en C++, la langage utilisé pour coder l'algorithme.
Pascal GARCIA nous a conseillé de représenter la grille sous forme de bitboards(italique) de 16 bits pour optimiser les calculs, l'un représentant les croix et l'autre les cercles.
Les états gagnants étaient sous forme d'entiers et lorsque l'un des bitboards satisfaisait un de ces états, la partie se terminait.
3.2 Création de l'IA pour le jeu du Pingouin
La deuxième étape du projet consiste à coder le Jeu du Pingouin de telle sorte que l'IA respecte les règles et comprenne la condition de victoire.
Chacun des pingouins a été modélisé par un bitboard de 32 bits.
Le plateau a été représenté à l'aide de 3 bitboards de 64 bits (chacun représentant la présence de 1,2 ou 3 poissons sur les cases) que nous avons ensuite complété avec la position des pingouins.
Il a fallu confronter le problème du déplacement des pions qui n'existait pas dans le Tic-Tac-Toe : en effet, il n'a pas été évident de relier déplacement sur le plateau et déplacement et sa représentation
en bitboard. La solution retenue a été de numéroter les 60 cases du plateau et de faire correspondre le déplacement de chacune des 6 directions par un calcul arithmétique.
De plus, la modélisation optimale des pingouins a été trouvée difficilement car il a fallu associer plusieurs types d'informations différentes à chacun des pingouins (par exemple, le nombre de déplacements possibles dans une direction).
Une solution envisagée a été de mettre chaque type d'informations dans un bitboard en particulier, mais cela s'est révélé trop difficile à gérer. Nous avons alors opté de stocker toutes les informations concernant un pingouin dans un bitboard personnel.
(image : Structure 1 pingouin 32 bits cf Representation_Pingouins)
3.3 Intégration de l'interface graphique pour le jeu
Conclusion
Remerciements
LaTex/Rapport Final/Rapport en LaTeX/Images/Plateau_Pingouin.jpg

1.85 MiB

File deleted
\documentclass{report} % Permet de spécifier le type du document (article,book, slides...)
\usepackage[utf8]{inputenc}
%Package utilisation accents
\usepackage{graphicx}
\usepackage{titlesec}
\titleformat{\chapter}[display]
{\normalfont\bfseries}{}{0pt}{\Huge}
\title{Étude Pratique : Développement d'une Intelligence Artificielle
à base de l'algorithme Monte Carlo Tree Search}
\date{2015 - 2016}
\author{BARIATTI Francesco\and LE Mikael\and LEBOUC Romain\and GASTÉ Adrien}
%Propriétés du \maketitle : Formatage de la page de garde
\begin{document}
\pagenumbering{gobble}
\maketitle
\newpage
\tableofcontents
\newpage
\pagenumbering{arabic}
\chapter{Introduction}
\smallbreak Les études pratiques sont des projets réalisés chaque année pas les élèves du département Informatique de l’INSA de Rennes qui s’étalent sur 10 mois.
\smallbreak Cette étude pratique se présente sous la forme d'une Intelligence Artificielle (IA) à créer pour un jeu de plateau, qui sera jouable via une interface graphique.
\section{Le Jeu du Pingouin}
\smallbreak Le Jeu du Pingouin est un jeu de plateau confrontant 2 à 4 joueurs sur un plateau de 60 cases hexagonales, sur lesquelles se trouvent de 1 à 3 poissons, comme présenté dans la figure \ref{Plateau}.
\smallbreak Chaque joueur place 4 pingouins sur le plateau en début de partie. À chaque tour, il en déplace un dans l'une des 6 directions possibles, en récupérant la case sur laquelle le pingouin se trouvait. Il gagne alors autant de points qu'il y a de poissons dessus.
\smallbreak Les pingouins ne peuvent pas passer à travers des autres pingouins (y compris ceux du même joueur) et des trous crées par les déplacements des pions. Lorsqu'un joueur ne peut pas jouer, ceux
pouvant encore jouer continuent.
\smallbreak Le jeu se termine lorsque aucun des pingouins ne peut se déplacer, et le joueur avec le plus de points remporte la partie.
\begin{figure}[!h]
\centering
\includegraphics[width=150px,height=150px]{./Images/Plateau_Pingouin.jpg}
\caption{Plateau du Jeu du Pingouin}
\label{Plateau}
\end{figure}
\section{L'algorithme Monte-Carlo Tree Search (MCTS)}
\smallbreak Le Monte-Carlo Tree Search est un algorithme de recherche de décision, utilisé dans les jeux tel que le Go ou encore Ms. Pacman.
Son principe repose sur la simulation de plusieurs millions de parties qui permettent de construire progressivement un arbre et d'ensuite choisir le meilleur chemin.
\smallbreak La construction de cet arbre est composée de 4 étapes :
\begin{itemize}
\item la sélection : En considérant un arbre partiellement construit suite à plusieurs simulations, un chemin est alors choisi par un calcul se servant des valuations aux noeuds, permettant ainsi d'explorer des choix moins bons, jusqu'au dernier noeud qui est une feuille;
ce principe repose sur le tirage aléatoire pondéré.
\item l'expansion : À partir du noeud considéré, il développe ses enfants puis on en choisit un au hasard.
\item la simulation : Il simule alors des prises de décision pour chacun des joueurs aléatoirement depuis cet enfant (la feuille courante) jusqu'à la fin du jeu. Il observe ensuite quel joueur a gagné
la simulation.
\item la rétropropagation : À chaque noeud est associé un score de 2 nombres : le premier est le nombre de parties gagnées par l'IA, le 2ème est le nombre total de parties jouées sur la branche courante.
Après l'étape précédente, on met à jour le score de chaque noeud de l'arbre en remontant du noeud courant à la racine.
\end{itemize}
\begin{figure}[!h]
\includegraphics[width=\linewidth]{./Images/MCTS.png}
\caption{Étapes du MCTS}
\label{lol}
\end{figure}
L'un des avantages indéniables de l'algorithme est qu'il peut être interrompu à tout moment, le choix de la branche optimale sera fait à partir de l'arbre déjà construit. De plus, C'est un
algorithme sans heuristique, c'est à dire qu'il n'a pas besoin de connaître au préalable les règles du jeu pour être bon.
\newpage
\chapter{Étude Pratique}
\section{Tâche à réaliser}
\smallbreak La tâche à réaliser est de programmer le jeu du Pingouin en Langage C++ et y implémenter le MCTS pour l'IA. Le mode Joueur contre IA est imposé. Il faut
également créer une interface utilisateur pour rendre le programme accessible à tous.
\section{Implémentation du MCTS}
\smallbreak L'algorithme à implémenter dans le programme est le MCTS. Il a déjà été programmé par notre encadrant Pascal GARCIA en C++. C'est donc à nous de le faire intéragir avec le programme du jeu afin que
l'IA choisisse la meilleure solution en fonction du coup fait par le joueur humain.
\section{Création d'une interface graphique}
\smallbreak Pour permettre de rendre l'application facile à utiliser, une interface graphique doit être programmée; les intéractions Homme-Machine se font à la souris.
Il n'y a pas de restriction sur la méthode utilisée.
\newpage
\chapter{Réalisation}
\smallbreak A chaque séance, nous nous sommes généralement divisés en 2 équipes de 2 afin d'avancer plus rapidement le projet sur 2 points différents. Lorsque nous avions l'occasion, nous rencontrions
notre encadrant afin qu'il donne son avis ainsi que des conseils pour des problèmes que nous n'arrivions pas à résoudre.
\smallbreak Le projet a été effectué à l'aide de Git pour faciliter l'accès aux différentes versions du code.
\section{Prise en main du MCTS avec le Tic-Tac-Toe}
\smallbreak Afin de comprendre et tester le fonctionnement du MCTS, nous avons décidé, pendant le 1er semestre, de l'implémenter sur un jeu simple, à savoir le Tic-Tac-Toe.
Cela nous a également permis d'apprendre à programmer en C++, le langage utilisé pour coder l'algorithme.
\smallbreak Pascal GARCIA nous a conseillé de représenter la grille sous forme de \textit{bitboards} de 16 bits pour optimiser les calculs, l'un représentant les croix et l'autre les cercles.
Les états gagnants étaient sous forme d'entiers et lorsque l'un des \textit{bitboards} satisfaisait un de ces états, la partie se terminait.
\section{Création de l'IA pour le Jeu du Pingouin}
\smallbreak La deuxième étape du projet consiste à coder le Jeu du Pingouin de telle sorte que l'IA respecte les règles et comprenne la condition de victoire.
\smallbreak Chacun des pingouins a été modélisé par un \textit{bitboard} de 32 bits.
Le plateau a été représenté à l'aide de 3 \textit{bitboards} de 64 bits (chacun représentant la présence de 1,2 ou 3 poissons sur les cases) que nous avons ensuite complété avec la position des pingouins.
\smallbreak Il a fallu confronter le problème du déplacement des pions qui n'existait pas dans le Tic-Tac-Toe : en effet, il n'a pas été évident de relier déplacement sur le plateau et déplacement et sa représentation
en \textit{bitboard}. La solution retenue a été de numéroter les 60 cases du plateau et de faire correspondre le déplacement de chacune des 6 directions par un calcul arithmétique.
\smallbreak De plus, la modélisation optimale des pingouins a été trouvée difficilement car il a fallu associer plusieurs types d'informations différentes à chacun des pingouins (par exemple, le nombre de déplacements possibles dans une direction).
\begin{figure}[!h]
\includegraphics[width=\linewidth]{./Images/Structure_Pingouin.png}
\caption{Découpage du \textit{bitboard} pour un pingouin}
\end{figure}
\smallbreak Une solution envisagée a été de mettre chaque type d'informations dans un \textit{bitboard} en particulier, mais cela s'est révélé trop difficile à gérer. Nous avons alors opté de stocker toutes les informations concernant un pingouin dans un \textit{bitboard} personnel.
\section{Intégration de l'interface graphique pour le jeu}
\newpage
\subsection*{Conclusion}
\subsection*{Remerciements}
\end{document}
\relax
\catcode `:\active
\catcode `;\active
\catcode `!\active
\catcode `?\active
\select@language{french}
\@writefile{toc}{\select@language{french}}
\@writefile{lof}{\select@language{french}}
\@writefile{lot}{\select@language{french}}
\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{3}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Le Jeu du Pingouin}{3}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Plateau du Jeu du Pingouin}}{3}}
\newlabel{Plateau}{{1}{3}}
\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}L'algorithme Monte-Carlo Tree Search (MCTS)}{3}}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces \IeC {\'E}tapes du MCTS}}{4}}
\newlabel{lol}{{2}{4}}
\@writefile{toc}{\contentsline {section}{\numberline {2}\IeC {\'E}tude Pratique}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}T\IeC {\^a}che \IeC {\`a} r\IeC {\'e}aliser}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Impl\IeC {\'e}mentation du MCTS}{5}}
\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Cr\IeC {\'e}ation d'une interface graphique}{5}}
\@writefile{toc}{\contentsline {section}{\numberline {3}R\IeC {\'e}alisation}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.1}Prise en main du MCTS avec le Tic-Tac-Toe}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.2}Cr\IeC {\'e}ation de l'IA pour le Jeu du Pingouin}{6}}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces D\IeC {\'e}coupage du \textit {bitboard} pour un pingouin}}{6}}
\@writefile{toc}{\contentsline {subsection}{\numberline {3.3}Int\IeC {\'e}gration de l'interface graphique pour le jeu}{7}}
This is BibTeX, Version 0.99dThe top-level auxiliary file: Rapport_style.aux
I found no \citation commands---while reading file Rapport_style.aux
I found no \bibdata command---while reading file Rapport_style.aux
I found no \bibstyle command---while reading file Rapport_style.aux
(There were 3 error messages)