Commit 5a013c2d authored by Timothy LAIRD's avatar Timothy LAIRD

Merge commit

parent 90e81581
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<url>src/tictactoecodingame/AlgoRechercheMCTS.java</url> <url>src/tictactoecodingame/AlgoRechercheMCTS.java</url>
<bookmark id="1"> <bookmark id="1">
<name/> <name/>
<line>96</line> <line>156</line>
<key/> <key/>
</bookmark> </bookmark>
</file> </file>
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<group> <group>
<file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/ArbreMCTS.java</file> <file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/ArbreMCTS.java</file>
<file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Node.java</file> <file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Node.java</file>
<file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Fraction.java</file> <file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Arbitre.java</file>
<file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/AlgoRechercheMCTS.java</file> <file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/AlgoRechercheMCTS.java</file>
<file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Player.java</file> <file>file:/C:/Users/timot/OneDrive/Desktop/2019-2020/Projet-Informatique/TicTacToe/src/tictactoecodingame/Player.java</file>
</group> </group>
......
...@@ -61,16 +61,18 @@ public class Arbitre { ...@@ -61,16 +61,18 @@ public class Arbitre {
} }
Joueur vainqueur = plateau.vainqueur(); Joueur vainqueur = plateau.vainqueur();
/*
if ( vainqueur != null ) if ( vainqueur != null )
System.out.println( vainqueur + " gagne la partie "); System.out.println( vainqueur + " gagne la partie ");
else else
System.out.println( "Partie nulle "); System.out.println( "Partie nulle ");
*/
return vainqueur; return vainqueur;
} }
public void startTournament( int _nbPartie , boolean _trace) { public Joueur startTournament( int _nbPartie , boolean _trace) {
double[] nbVictoire = new double[2]; double[] nbVictoire = new double[2];
Joueur vainqueur; Joueur vainqueur;
...@@ -81,12 +83,12 @@ public class Arbitre { ...@@ -81,12 +83,12 @@ public class Arbitre {
for (int i = 0 ; i < _nbPartie ; i++ ) { for (int i = 0 ; i < _nbPartie ; i++ ) {
vainqueur = startNewGame(_trace); vainqueur = startNewGame(_trace);
if ( vainqueur == joueur1 ) nbVictoire[0]++; if ( vainqueur == joueur1 ) nbVictoire[0]++;
if ( vainqueur == joueur2 ) nbVictoire[1]++; if ( vainqueur == joueur2 ) nbVictoire[1]++;
if ( vainqueur == null ) { if ( vainqueur == null ) {
nbVictoire[0]+=0.5; nbVictoire[0]+=0.0;
nbVictoire[1]+=0.5; nbVictoire[1]+=0.0;
} }
if ( numJoueur == 0 ) { if ( numJoueur == 0 ) {
...@@ -97,21 +99,27 @@ public class Arbitre { ...@@ -97,21 +99,27 @@ public class Arbitre {
currentJoueur = joueur1; currentJoueur = joueur1;
numJoueur=0; numJoueur=0;
} }
System.out.println(joueur1 + " score : " + nbVictoire[0]); //System.out.println(joueur1 + " score : " + nbVictoire[0]);
System.out.println(joueur2 + " score : " + nbVictoire[1]); //System.out.println(joueur2 + " score : " + nbVictoire[1]);
} }
System.out.println(joueur1 + " score : " + nbVictoire[0]); System.out.println(joueur1 + " score : " + nbVictoire[0]);
System.out.println(joueur2 + " score : " + nbVictoire[1]); System.out.println(joueur2 + " score : " + nbVictoire[1]);
if (nbVictoire[0] > nbVictoire[1]) if (nbVictoire[0] > nbVictoire[1]){
System.out.println(joueur1 + " GAGNE "); //System.out.println(joueur1 + " GAGNE ");
else vainqueur = joueur1;
if (nbVictoire[1] > nbVictoire[0]) }else{
System.out.println(joueur2 + " GAGNE "); if (nbVictoire[1] > nbVictoire[0]){
else //System.out.println(joueur2 + " GAGNE ");
System.out.println("Match nul"); vainqueur = joueur2;
}else{
//System.out.println("Match nul");
vainqueur = null;
}
}
return vainqueur;
} }
public Joueur getCurrentJoueur() { public Joueur getCurrentJoueur() {
......
...@@ -7,11 +7,16 @@ package tictactoecodingame; ...@@ -7,11 +7,16 @@ package tictactoecodingame;
/** /**
* *
* @author timot * <div>Cette classe englobe la structure de noeud en un arbre, et permets d'agir sur sa racine.</div>
*/ */
public class ArbreMCTS { public class ArbreMCTS {
private Node root; private Node root;
/**
* <div>Initialisation d'un arbre : La racine représente un plateau vide.</div>
* @param pl Le joueur qui va jouer.
* @param o Le joueur qui vient de jouer.
*/
public ArbreMCTS(Joueur pl, Joueur o){ public ArbreMCTS(Joueur pl, Joueur o){
root = new Node(null, pl, o); root = new Node(null, pl, o);
} }
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package tictactoecodingame;
import java.util.ArrayList;
/**
*
* @author louis
*/
public class Fraction {
public static double frctValue(int parentVisit, int visits, int wins){
if(visits == 0){
return Integer.MAX_VALUE;
}
return (wins/visits) + 1.41 * Math.sqrt(Math.log(parentVisit) / visits);
}
public static Node bestChild(Node root){
int parentVisit = root.visits();
int maxIndex = 0;
double maxScore = 0;
ArrayList<Node> children = root.children();
double currentScore; Node currentNode;
for(int i = 0; i < children.size(); i++){
currentNode = children.get(i);
currentScore = frctValue(parentVisit, currentNode.visits(), currentNode.wins());
if(currentScore > maxScore){
maxScore = currentScore;
maxIndex = i;
}
}
return children.get(maxIndex);
}
}
...@@ -9,16 +9,35 @@ import java.util.ArrayList; ...@@ -9,16 +9,35 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
/** /**
* *
* @author timot * <div>Cette classe instancie les noeuds d'un arbre. Chaque noeud contient un certain nombre d'informations :</div>
* <ul>
* <li>Un coup : Ce coup représente le coup qui <strong>vient</strong> d'être joué.</li>
* <li>Deux joueurs : Ces joueurs représentent respectivement le joueur qui va jouer, et son adversaire, soit le joueur qui vient
* de jouer.</li>
* <li>Trois entiers : Ces entiers comptent le nombre de victoires, égalités et nombre total de parties jouées passant par ce noeud.
* Les victoires sont comptées pour le joueur qui vient de jouer, c'est à dire opponent, étant donné que ces valeurs sont uniquement
* lues depuis le contexte de leur parent dans l'arbre, où opponent devient player.</li>
* <li>Une liste de Node : Cette liste représente simplement les enfants du noeud.</li>
* <li>Un booléen : Ce booléen indique si le noeud est résolu. Un noeud résolu est un noeud représentant une partie terminée, ou un
* noeud dont tous les fils sont résolus.</li>
* </ul>
*/ */
public class Node { public class Node {
private Coup coup; private final Coup coup;
private final Joueur player; private final Joueur player;
private final Joueur opponent; private final Joueur opponent;
private int visits = 0; private int visits = 0;
private int wins = 0; private int wins = 0;
private int draws = 0;
private final ArrayList<Node> children; private final ArrayList<Node> children;
private boolean solved = false;
/**
* <div>Initialisation standard d'un Node</div>
* @param c Le coup qui vient d'être joué.
* @param pl Le joueur qui va jouer le prochain coup.
* @param o Le joueur qui vient de jouer le coup c.
*/
public Node(Coup c, Joueur pl, Joueur o){ public Node(Coup c, Joueur pl, Joueur o){
coup = c; coup = c;
player = pl; player = pl;
...@@ -26,6 +45,7 @@ public class Node { ...@@ -26,6 +45,7 @@ public class Node {
children = new ArrayList<>(); children = new ArrayList<>();
} }
//Les accesseurs et modifieurs nécessaires
public int visits(){ public int visits(){
return visits; return visits;
} }
...@@ -34,6 +54,10 @@ public class Node { ...@@ -34,6 +54,10 @@ public class Node {
return wins; return wins;
} }
public int draws(){
return draws;
}
public Joueur player(){ public Joueur player(){
return player; return player;
} }
...@@ -50,26 +74,42 @@ public class Node { ...@@ -50,26 +74,42 @@ public class Node {
return coup; return coup;
} }
public void coup(Coup c){ public boolean solved(){
coup = c; return solved;
} }
public void solved(boolean s){
solved = s;
}
//Les fonctions permettant d'incrémenter le nombre de visites, victoires et égalités.
public void addVisit(){ public void addVisit(){
visits++; visits++;
} }
public void addWin(){ public void addWin(){
wins++; wins ++;
} }
public void addDraw(){
draws++;
}
/** <div>Une fonction permettant de calculer le taux de victoire d'un noeud.Ce taux peut prendre en compte les égalités, en fonction
du coefficient rentré.</div>
@return Le taux de victoire.
*/
public double winrate(){ public double winrate(){
if(visits == 0){ if(visits == 0){
return 0; return 0;
}else{ }else{
return wins/visits; return (wins + 0.3*draws)/visits;
} }
} }
/** <div>Une fonction permettant de trouver le Node fils avec le meilleur taux de victoire.</div>
* @return Le Node avec le meilleur taux de victoire de tous les fils de son père.
*/
public Node nextPlay(){ public Node nextPlay(){
Node bestNode = null; Node bestNode = null;
double winrate = Double.NEGATIVE_INFINITY; double winrate = Double.NEGATIVE_INFINITY;
...@@ -85,4 +125,10 @@ public class Node { ...@@ -85,4 +125,10 @@ public class Node {
} }
return bestNode; return bestNode;
} }
//Une méthode permettant de visualiser les informations d'un noeud. Surtout utile pendant le débogage.
@Override
public String toString(){
return coup.toString() + " " + visits + " " + winrate() * 100;
}
} }
...@@ -12,27 +12,54 @@ public class Player { ...@@ -12,27 +12,54 @@ public class Player {
public static void main(String args[]) { public static void main(String args[]) {
JoueurHumain humain = new JoueurHumain("Humain"); //JoueurHumain humain = new JoueurHumain("Humain");
JoueurOrdi joueurOrdi = new JoueurOrdi("Ordi"); //JoueurOrdi joueurOrdiRnd = new JoueurOrdi("OrdiRnd");
JoueurOrdi joueurOrdiMCTS1000 = new JoueurOrdi("OrdiMCTS1000");
JoueurOrdi joueurOrdiMCTS5000 = new JoueurOrdi("OrdiMCTS5000");
//JoueurOrdi joueurOrdiMCTS10000 = new JoueurOrdi("OrdiMCTS10000");
double coeff = Math.sqrt(2);
// Remplacer ici l'algorithme aléatoire par votre algorithme.
// Créer une nouvelle classe qui hérite de la class AlgoRecherche
AlgoRechercheMCTS alea = new AlgoRechercheMCTS(joueurOrdi, humain, 1000,0.1);
joueurOrdi.setAlgoRecherche(alea);
GrilleTicTacToe3x3 grille = new GrilleTicTacToe3x3(); GrilleTicTacToe3x3 grille = new GrilleTicTacToe3x3();
/*
AlgoRechercheAleatoire aleaRnd = new AlgoRechercheAleatoire();
Arbitre a = new Arbitre(grille, humain , joueurOrdi ); joueurOrdiRnd.setAlgoRecherche(aleaRnd);
*/
AlgoRechercheMCTS mcts1000 = new AlgoRechercheMCTS(joueurOrdiMCTS1000, joueurOrdiMCTS5000, 1000, coeff, grille.getNbLignes(), grille.getNbColonnes(), true);
joueurOrdiMCTS1000.setAlgoRecherche(mcts1000);
AlgoRechercheMCTS mcts5000 = new AlgoRechercheMCTS(joueurOrdiMCTS5000, joueurOrdiMCTS1000, 5000, coeff, grille.getNbLignes(), grille.getNbColonnes(), true);
joueurOrdiMCTS5000.setAlgoRecherche(mcts5000);
/*
AlgoRechercheMCTS mcts10000 = new AlgoRechercheMCTS(joueurOrdiMCTS10000, joueurOrdiMCTS1000, 10000,coeff, grille.getNbLignes(), grille.getNbColonnes(), false);
joueurOrdiMCTS10000.setAlgoRecherche(mcts10000);
*/
// Arbitre a = new Arbitre(grille, joueurOrdi , humain ); Arbitre a = new Arbitre(grille, joueurOrdiMCTS1000, joueurOrdiMCTS5000);
//a.startNewGame(true); // Demarre une partie en affichant la grille du jeu
a.startNewGame(true); // Demarre une partie en affichant la grille du jeu
// Pour lancer un tournooi de 100 parties en affichant la grille du jeu
//a.startTournament(1000 , false);
// Pour lancer un tournoi de 100 parties en affichant la grille du jeu
int[] results = {0,0,0};Joueur winner;
for(int i = 0; i < 100; i++){
System.out.println("Round " + i);
winner = a.startTournament(100 , false);
if(winner != null){
if(winner.equals(joueurOrdiMCTS1000)){
results[0]++;
}else{
results[1]++;
}
}else{
results[2]++;
}
}
System.out.println();
System.out.println("1000 vs 5000");
System.out.println("Ordi MCTS 1000 :" + results[0]);
System.out.println("Ordi MCTS 5000 :" + results[1]);
System.out.println("Draws :" + results[2]);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment