Commit 82ae4ede authored by MACE Lloyd's avatar MACE Lloyd

Replace MCTS.java

parent 9f2911b2
...@@ -7,10 +7,8 @@ package mcts; ...@@ -7,10 +7,8 @@ package mcts;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import tictactoecodingame.AlgoRechercheAleatoire;
import tictactoecodingame.Coup; import tictactoecodingame.Coup;
import tictactoecodingame.Joueur; import tictactoecodingame.Joueur;
import tictactoecodingame.JoueurOrdi;
import tictactoecodingame.Plateau; import tictactoecodingame.Plateau;
/** /**
...@@ -23,102 +21,101 @@ public class MCTS { ...@@ -23,102 +21,101 @@ public class MCTS {
Noeud racine; Noeud racine;
double coefficientUCT; double coefficientUCT;
Joueur joueur; Joueur joueur;
JoueurOrdi joueurOrdiSimulation; //ordinateur algoRechercheAleatoire durant les simulations Joueur adversaire;
//CONSTRUCTEUR //CONSTRUCTEUR
public MCTS(Plateau plateau, Joueur joueur) { public MCTS(Plateau plateau, Joueur joueur, Joueur adversaire) {
this.plateau = plateau; this.plateau = plateau;
this.joueur = joueur; this.joueur = joueur;
this.adversaire = adversaire;
System.out.println(joueur + " / " + adversaire);
plateau.sauvegardePosition(0);
coefficientUCT = Math.sqrt(2); coefficientUCT = Math.sqrt(2);
Etat etat = new Etat();
etat.setJoueur(joueur);
racine = new Noeud(); racine = new Noeud();
racine.setEtat(new Etat(plateau, joueur)); racine.setEtat(etat);
AlgoRechercheAleatoire algoAleatoire = new AlgoRechercheAleatoire();
joueurOrdiSimulation = new JoueurOrdi("jOS", algoAleatoire);
} }
//Obtenir le meilleurCoup grâce au MCTS //Obtenir le meilleurCoup grâce au MCTS
public Coup meilleurCoup() { public Coup meilleurCoup() {
double endTime = System.currentTimeMillis() + 100; //L'algorithme tourne pendant 10s double endTime = System.currentTimeMillis() + 20; //L'algorithme tourne pendant 10s
//System.out.println(racine.getEtat().getCoupsPossibles());
while (System.currentTimeMillis() < endTime) {
Noeud noeudPrometteur; Noeud noeudPrometteur;
Noeud nouveauNoeud; Noeud nouveauNoeud;
int resultat; Joueur gagnantSimulation;
ArrayList<Coup> coupsPossibles;
noeudPrometteur = selection(); while (System.currentTimeMillis() < endTime) {
//System.out.println(noeudPrometteur.getEtat().getCoupsPossibles()); noeudPrometteur = selection();
//System.out.println(racine.getListeEnfant().size()); coupsPossibles = plateau.getListeCoups(joueur);
if (!noeudPrometteur.getEtat().getCoupsPossibles().isEmpty()) { if (coupsPossibles.isEmpty()) {
while(!noeudPrometteur.getEtat().getCoupsPossibles().isEmpty()) { propagationArriere(noeudPrometteur, plateau.vainqueur());
nouveauNoeud = expansion(noeudPrometteur);
resultat = simulation(nouveauNoeud);
System.out.print(resultat + " ");
propagationArriere(nouveauNoeud, resultat);
//System.out.println(noeudPrometteur.getEtat().getCoupsPossibles());
}
} }
else { else {
resultat = simulation(noeudPrometteur); plateau.sauvegardePosition(noeudPrometteur.getEtat().getProfondeur());
propagationArriere(noeudPrometteur, resultat); while (!coupsPossibles.isEmpty()) {
nouveauNoeud = expansion(noeudPrometteur, coupsPossibles);
gagnantSimulation = simulation(nouveauNoeud);
//System.out.print(gagnantSimulation + " ");
propagationArriere(nouveauNoeud, gagnantSimulation);
plateau.restaurePosition(noeudPrometteur.getEtat().getProfondeur());
} }
System.out.println(); }
//System.out.println();
//System.out.println("_"); //System.out.println("_");
/*
if (!racine.getListeEnfant().isEmpty()) { if (!racine.getListeEnfant().isEmpty()) {
for (Noeud enfant : racine.getListeEnfant()) { for (Noeud enfant : racine.getListeEnfant()) {
System.out.print(enfant.getEtat().getNbVictoire() + "/" + enfant.getEtat().getNbVisite() + " "); System.out.print(enfant.getEtat().getNbVictoire() + "/" + enfant.getEtat().getNbVisite() + " | ");
} }
} }
System.out.println(); System.out.println();
System.out.println(racine.getEtat().getNbVictoire() + "/" + racine.getEtat().getNbVisite() + " " ); System.out.println(racine.getEtat().getNbVictoire() + "/" + racine.getEtat().getNbVisite());
*/
}
}
joueur.setIdJoueur(racine.getEtat().getNumJoueur()); plateau.restaurePosition(0);
return Util.getMeilleurCoup(racine, joueur); return Util.getMeilleurCoup(racine);
} }
//4 PHASE DU MCTS //4 PHASE DU MCTS
//Selectionne le noeud "prometteur" grâce à UCT. //Selectionne le noeud "prometteur" grâce à UCT.
public Noeud selection() { public Noeud selection() {
plateau.restaurePosition(0);
Noeud noeudPrometteur = racine; Noeud noeudPrometteur = racine;
while (!noeudPrometteur.getListeEnfant().isEmpty()) { while (!noeudPrometteur.getListeEnfant().isEmpty()) {
noeudPrometteur = UCT.trouverNoeudPrometteur(noeudPrometteur, coefficientUCT); noeudPrometteur = UCT.trouverNoeudPrometteur(noeudPrometteur, coefficientUCT);
plateau.joueCoup(noeudPrometteur.getEtat().getDernierCoup());
//plateau.sauvegardePosition(noeudPrometteur.getEtat().getProfondeur());
} }
return noeudPrometteur; return noeudPrometteur;
} }
//Une fois le meilleur noeud trouvé, on choisit un noeud au hasard parmi tous les noeuds possible. //Une fois le meilleur noeud trouvé, on choisit un noeud au hasard parmi tous les noeuds possible.
public Noeud expansion(Noeud noeud, ArrayList<Coup> coupsPossibles) {
public Noeud expansion(Noeud noeud) { Joueur joueurTemp = Util.swapJoueur(noeud.getEtat().getJoueur(), joueur, adversaire);
ArrayList<Coup> coupsPossibles = noeud.getEtat().getCoupsPossibles(); int profondeur = noeud.getEtat().getProfondeur();
Random r = new Random(); Random r = new Random();
int randomIndex = r.nextInt(coupsPossibles.size()); int randomIndex = r.nextInt(coupsPossibles.size());
Coup randomCoup = coupsPossibles.remove(randomIndex); Coup randomCoup = coupsPossibles.remove(randomIndex);
//System.out.println(randomCoup); plateau.joueCoup(randomCoup);
Plateau nouveauPlateau = Util.copyPlateau(noeud.getEtat().getPlateau());
nouveauPlateau.joueCoup(randomCoup);
int numAdversaire = Util.getNumAdversaire(noeud.getEtat().getNumJoueur());
joueur.setIdJoueur(numAdversaire);
ArrayList<Coup> nouveauCoupsPossibles = Util.copyCoupsPossibles(noeud, joueur);
nouveauCoupsPossibles.remove(randomCoup);
Etat etat = new Etat(); Etat etat = new Etat();
etat.setPlateau(nouveauPlateau); etat.setJoueur(joueurTemp);
etat.setCoupsPossibles(nouveauCoupsPossibles); etat.setDernierCoup(randomCoup);
etat.setNumJoueur(numAdversaire); etat.setProfondeur(profondeur + 1);
Noeud nouveauNoeud = new Noeud(etat, noeud); Noeud nouveauNoeud = new Noeud(etat, noeud);
noeud.getListeEnfant().add(nouveauNoeud); noeud.getListeEnfant().add(nouveauNoeud);
...@@ -126,83 +123,177 @@ public class MCTS { ...@@ -126,83 +123,177 @@ public class MCTS {
return nouveauNoeud; return nouveauNoeud;
} }
//A partir du nouveau noeud exploré, on simule une partie de coup aléatoire jusqu'à terminer la partie
public Joueur simulation(Noeud noeud) {
Joueur joueurTemp = noeud.getEtat().getJoueur();
while (!plateau.partieTerminee()) {
Random r = new Random();
int randomIndex = r.nextInt(plateau.getListeCoups(joueurTemp).size());
Coup randomCoup = plateau.getListeCoups(joueurTemp).get(randomIndex);
plateau.joueCoup(randomCoup);
joueurTemp = Util.swapJoueur(joueurTemp, joueur, adversaire);
}
joueurTemp = plateau.vainqueur();
return joueurTemp;
}
public void propagationArriere(Noeud noeud, Joueur gagnant) {
Noeud parent = noeud;
while (parent != null) {
parent.getEtat().updateNbVisite();
if (gagnant != null && parent.getEtat().getJoueur() != gagnant) {
parent.getEtat().updateNbVictoire();
}
parent = parent.getParent();
}
}
}
/*
//Obtenir le meilleurCoup grâce au MCTS
public Coup meilleurCoup() {
double endTime = System.currentTimeMillis() + 100; //L'algorithme tourne pendant 10s
//System.out.println(racine.getEtat().getCoupsPossibles());
while (System.currentTimeMillis() < endTime) {
Noeud noeudPrometteur;
Noeud nouveauNoeud;
Joueur gagnantSimulation;
noeudPrometteur = selection();
//System.out.println(noeudPrometteur.getEtat().getCoupsPossibles());
//System.out.println(racine.getListeEnfant().size());
ArrayList<Coup> coupsPossibles = plateau.getListeCoups(joueur);
if (coupsPossibles != null) {
while (!coupsPossibles.isEmpty()) {
nouveauNoeud = expansion(noeudPrometteur, coupsPossibles);
gagnantSimulation = simulation(nouveauNoeud);
//System.out.print(resultat + " ");
propagationArriere(nouveauNoeud, gagnantSimulation);
//System.out.println(noeudPrometteur.getEtat().getCoupsPossibles());
}
}
else {
gagnantSimulation = plateau.vainqueur();
propagationArriere(noeudPrometteur, gagnantSimulation);
}
/*
if (!plateau.getListeCoups(currentJoueur).isEmpty()) {
Util.swapJoueur(currentJoueur, joueur, adversaire);
while(noeudPrometteur.getListeEnfant().size() < plateau.getListeCoups(currentJoueur).size()) {
nouveauNoeud = expansion(noeudPrometteur);
gagnantSimulation = simulation(nouveauNoeud);
//System.out.print(resultat + " ");
propagationArriere(nouveauNoeud, gagnantSimulation);
//System.out.println(noeudPrometteur.getEtat().getCoupsPossibles());
}
}
else {
gagnantSimulation = simulation(noeudPrometteur);
propagationArriere(noeudPrometteur, gagnantSimulation);
}
*/
//System.out.println();
//System.out.println("_");
/* /*
public Noeud expansion(Noeud noeud) {
ArrayList<Coup> coupsPossibles = noeud.getEtat().getCoupsPossibles();
if (!coupsPossibles.isEmpty()) { if (!racine.getListeEnfant().isEmpty()) {
for (Noeud enfant : racine.getListeEnfant()) {
System.out.print(enfant.getEtat().getNbVictoire() + "/" + enfant.getEtat().getNbVisite() + " ");
}
}
System.out.println();
System.out.println(racine.getEtat().getNbVictoire() + "/" + racine.getEtat().getNbVisite() + " " );
*/ /*
}
return Util.getMeilleurCoup(racine);
}
*/
/*
//4 PHASE DU MCTS
//Selectionne le noeud "prometteur" grâce à UCT.
public Noeud selection() {
plateau.restaurePosition(0);
currentJoueur = joueur;
Noeud noeudPrometteur = racine;
while (!noeudPrometteur.getListeEnfant().isEmpty()) {
noeudPrometteur = UCT.trouverNoeudPrometteur(noeudPrometteur, coefficientUCT);
Util.swapJoueur(currentJoueur, joueur, adversaire);
plateau.joueCoup(noeudPrometteur.getEtat().getDernierCoup());
plateau.sauvegardePosition(noeudPrometteur.getEtat().getProfondeur());
}
return noeudPrometteur;
}
//Une fois le meilleur noeud trouvé, on choisit un noeud au hasard parmi tous les noeuds possible.
public Noeud expansion(Noeud noeud, ArrayList<Coup> coupsPossibles) {
int profondeur = noeud.getEtat().getProfondeur();
Random r = new Random(); Random r = new Random();
int randomIndex = r.nextInt(coupsPossibles.size()); int randomIndex = r.nextInt(coupsPossibles.size());
Coup randomCoup = coupsPossibles.remove(randomIndex); Coup randomCoup = coupsPossibles.remove(randomIndex);
Plateau nouveauPlateau = Util.copyPlateau(noeud.getEtat().getPlateau()); plateau.joueCoup(randomCoup);
nouveauPlateau.joueCoup(randomCoup); plateau.sauvegardePosition(profondeur + 1);
Util.swapJoueur(currentJoueur, joueur, adversaire);
int numAdversaire = Util.getNumAdversaire(noeud.getEtat().getNumJoueur());
joueur.setIdJoueur(numAdversaire);
ArrayList<Coup> nouveauCoupsPossibles = Util.copyCoupsPossibles(noeud, joueur);
nouveauCoupsPossibles.remove(randomCoup);
Etat etat = new Etat(); Etat etat = new Etat();
etat.setPlateau(nouveauPlateau); //etat.setNumJoueur(currentJoueur.getIdJoueur());
etat.setCoupsPossibles(nouveauCoupsPossibles); etat.setDernierCoup(randomCoup);
etat.setNumJoueur(numAdversaire); etat.setProfondeur(profondeur + 1);
Noeud nouveauNoeud = new Noeud(etat, noeud); Noeud nouveauNoeud = new Noeud(etat, noeud);
noeud.getListeEnfant().add(nouveauNoeud); noeud.getListeEnfant().add(nouveauNoeud);
return nouveauNoeud; return nouveauNoeud;
} }
return noeud;
}
*/
//A partir du nouveau noeud exploré, on simule une partie de coup aléatoire jusqu'à terminer la partie //A partir du nouveau noeud exploré, on simule une partie de coup aléatoire jusqu'à terminer la partie
public int simulation(Noeud noeud) { public Joueur simulation(Noeud noeud) {
Plateau plateauTemporaire = Util.copyPlateau(noeud.getEtat().getPlateau()); //int resultat = 0;
int numTemporaire = noeud.getEtat().getNumJoueur();
joueurOrdiSimulation.setIdJoueur(numTemporaire);
int resultat = 0;
while (!plateauTemporaire.partieTerminee()) { Joueur joueurTemp = currentJoueur;
Coup coup = joueurOrdiSimulation.joue(plateauTemporaire);
plateauTemporaire.joueCoup(coup);
Util.setAdversaire(joueurOrdiSimulation);
}
if (plateauTemporaire.partieGagnee()) { while (!plateau.partieTerminee()) {
if (plateauTemporaire.vainqueur().getIdJoueur() == noeud.getEtat().getNumJoueur()) { //!ATTENTION les numJoueur sont inversés à cause de la boucle while! Random r = new Random();
resultat = -1; int randomIndex = r.nextInt(plateau.getListeCoups(joueurTemp).size());
} Coup randomCoup = plateau.getListeCoups(joueurTemp).get(randomIndex);
else { plateau.joueCoup(randomCoup);
resultat = 1; Util.swapJoueur(joueurTemp, joueur, adversaire);
}
} }
return resultat; return plateau.vainqueur();
} }
//Une fois la simulation terminée, on met à jour l'arbre public void propagationArriere(Noeud noeud, Joueur gagnant) {
public void propagationArriere(Noeud noeud, int resultat) {
int numJoueur = noeud.getEtat().getNumJoueur();
Noeud parent = noeud; Noeud parent = noeud;
Joueur joueurTemp = currentJoueur;
while (parent != null) { while (parent != null) {
//updateNbVisite(parent);
parent.getEtat().updateNbVisite(); parent.getEtat().updateNbVisite();
if (parent.getEtat().getNumJoueur() == numJoueur) { if (gagnant != null && currentJoueur != gagnant) {
if (resultat == -1) {
//updateNbVictoire(parent);
parent.getEtat().updateNbVictoire();
}
else {
if (resultat == 1) {
//updateNbVictoire(parent);
parent.getEtat().updateNbVictoire(); parent.getEtat().updateNbVictoire();
} }
}
}
parent = parent.getParent(); parent = parent.getParent();
Util.swapJoueur(currentJoueur, joueur, adversaire);
} }
} }
} }
*/
\ No newline at end of file
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