Commit 32d715e1 authored by MACE Lloyd's avatar MACE Lloyd

Replace MCTS.java

parent 8772dd01
...@@ -18,89 +18,76 @@ import tictactoecodingame.Plateau; ...@@ -18,89 +18,76 @@ import tictactoecodingame.Plateau;
public class MCTS { public class MCTS {
Plateau plateau; Plateau plateau;
Noeud racine;
double coefficientUCT; double coefficientUCT;
Joueur joueur; Joueur joueur;
Joueur adversaire; Joueur adversaire;
Random r; Random r;
int nbIteration; //Nombre d'itérations des 4 phases du MCTS
Noeud racine; //Racine de l'arbre
Noeud noeud; //Noeud pour parcourir l'arbre
//CONSTRUCTEUR //CONSTRUCTEUR
public MCTS(Plateau plateau, Joueur joueur, Joueur adversaire) {
public MCTS(Plateau plateau, Joueur joueur, Joueur adversaire, int nbIteration) {
this.plateau = plateau; this.plateau = plateau;
this.joueur = joueur; this.joueur = joueur;
this.adversaire = adversaire; this.adversaire = adversaire;
this.nbIteration = nbIteration;
plateau.sauvegardePosition(0); plateau.sauvegardePosition(0);
//coefficientUCT = 0.8;
coefficientUCT = Math.sqrt(2); coefficientUCT = Math.sqrt(2);
r = new Random(System.currentTimeMillis()); r = new Random(System.currentTimeMillis());
Etat etat = new Etat(); Etat etat = new Etat();
etat.setJoueur(joueur); etat.setJoueur(joueur);
racine = new Noeud(); racine = new Noeud();
racine.setEtat(etat); racine.setEtat(etat);
this.noeud = racine;
} }
//Obtenir le meilleurCoup grâce au MCTS //Obtenir le meilleurCoup grâce au MCTS
public Coup meilleurCoup() { public Coup meilleurCoup() {
//double endTime = System.currentTimeMillis() + 1000; // temps en milliseconde for (int i=0; i < nbIteration; i++) {
Noeud noeudPrometteur; selection();
Noeud noeudSimulation;
Joueur gagnantSimulation;
ArrayList<Coup> coupsPossibles;
//while (System.currentTimeMillis() < endTime) {
for (int i=0; i < 2000; i++) { //nombre d'itérations variable
noeudPrometteur = selection();
if (plateau.partieTerminee()) { if (plateau.partieTerminee()) {
propagationArriere(noeudPrometteur, plateau.vainqueur()); propagationArriere();
} }
else { else {
coupsPossibles = plateau.getListeCoups(noeudPrometteur.getEtat().getJoueur()); expansion();
noeudSimulation = expansion(noeudPrometteur, coupsPossibles); simulation();
gagnantSimulation = simulation(noeudSimulation); propagationArriere();
propagationArriere(noeudSimulation, gagnantSimulation);
}
/* //TESTS
if (!racine.getListeEnfant().isEmpty()) {
for (Noeud enfant : racine.getListeEnfant()) {
System.out.print(enfant.getEtat().getScoreVictoire() + " / " + enfant.getEtat().getNbVisite() + " " + enfant.getEtat().getDernierCoup().toString() + " | ");
}
} }
System.out.println();
System.out.println(racine.getEtat().getScoreVictoire() + "/" + racine.getEtat().getNbVisite());
*/
} }
plateau.restaurePosition(0); return MeilleurCoup.getMeilleurCoupUCT(noeud);
return Util.getMeilleurCoup(racine);
} }
//4 PHASE DU MCTS //4 PHASE DU MCTS
//Selectionne le noeud "prometteur" grâce à UCT. /**
public Noeud selection() { * Selectionne le noeud "prometteur" grâce à UCT (Upper Confidence Bound 1 applied to Trees).
Noeud noeudPrometteur = racine; * Tant que le noeud selectionné possède des noeuds enfants, on choisit l'enfant le plus prometteur.
while (!noeudPrometteur.getListeEnfant().isEmpty()) { */
noeudPrometteur = UCT.trouverNoeudPrometteur(noeudPrometteur, coefficientUCT);
plateau.joueCoup(noeudPrometteur.getEtat().getDernierCoup()); public void selection() {
while (!noeud.getListeEnfant().isEmpty()) {
noeud = UCT.trouverNoeudPrometteurUCT(noeud, coefficientUCT);
plateau.joueCoup(noeud.getEtat().getDernierCoup());
} }
return noeudPrometteur;
} }
//Une fois le meilleur noeud trouvé, on créé tous les noeuds enfant possible, et on en choisit un au hasard. /**
public Noeud expansion(Noeud noeud, ArrayList<Coup> coupsPossibles) { * Une fois le neoud prometteur trouvé, on créé tous les noeuds enfant possible, et on en choisit un au hasard.
Joueur joueurTemp = Util.swapJoueur(noeud.getEtat().getJoueur(), joueur, adversaire); */
public void expansion() {
ArrayList<Coup> coupsPossibles = plateau.getListeCoups(noeud.getEtat().getJoueur());
ArrayList<Noeud> noeudsPossibles = noeud.getListeEnfant();
int newProfondeur = noeud.getEtat().getProfondeur() + 1; int newProfondeur = noeud.getEtat().getProfondeur() + 1;
int randomIndex; Joueur joueurTemp = Util.swapJoueur(noeud.getEtat().getJoueur(), joueur, adversaire);
Etat newEtat; Etat newEtat;
Noeud randomNoeud;
Noeud newNoeud; Noeud newNoeud;
for (Coup coup : coupsPossibles) { for (Coup coup : coupsPossibles) {
newEtat = new Etat(); newEtat = new Etat();
newEtat.setJoueur(joueurTemp); newEtat.setJoueur(joueurTemp);
...@@ -108,47 +95,50 @@ public class MCTS { ...@@ -108,47 +95,50 @@ public class MCTS {
newEtat.setProfondeur(newProfondeur); newEtat.setProfondeur(newProfondeur);
newNoeud = new Noeud(newEtat, noeud); newNoeud = new Noeud(newEtat, noeud);
noeud.getListeEnfant().add(newNoeud); noeudsPossibles.add(newNoeud);
} }
noeud = noeudsPossibles.get(r.nextInt(noeudsPossibles.size()));
ArrayList<Noeud> noeudsPossibles = noeud.getListeEnfant(); plateau.joueCoup(noeud.getEtat().getDernierCoup());
randomIndex = r.nextInt(noeudsPossibles.size());
randomNoeud = noeudsPossibles.get(randomIndex);
plateau.joueCoup(randomNoeud.getEtat().getDernierCoup());
return randomNoeud;
} }
//A partir du nouveau noeud choisi durant l'expansion, on simule une partie de coup aléatoire jusqu'à terminer la partie. /**
public Joueur simulation(Noeud noeud) { * A partir du nouveau noeud choisi durant l'expansion, on simule une partie de coup aléatoire jusqu'à terminer la partie.
*/
public void simulation() {
Joueur joueurTemp = noeud.getEtat().getJoueur(); Joueur joueurTemp = noeud.getEtat().getJoueur();
int randomIndex;
Coup randomCoup;
while (!plateau.partieTerminee()) { while (!plateau.partieTerminee()) {
int randomIndex = r.nextInt(plateau.getListeCoups(joueurTemp).size()); randomIndex = r.nextInt(plateau.getListeCoups(joueurTemp).size());
Coup randomCoup = plateau.getListeCoups(joueurTemp).get(randomIndex); randomCoup = plateau.getListeCoups(joueurTemp).get(randomIndex);
plateau.joueCoup(randomCoup); plateau.joueCoup(randomCoup);
joueurTemp = Util.swapJoueur(joueurTemp, joueur, adversaire); joueurTemp = Util.swapJoueur(joueurTemp, joueur, adversaire);
} }
joueurTemp = plateau.vainqueur();
return joueurTemp;
} }
//Une fois la simulation terminée, on met à jour l'arbre. /**
public void propagationArriere(Noeud noeud, Joueur gagnant) { * Une fois la simulation terminée, on met à jour l'arbre comme suit :
plateau.restaurePosition(0); * On remonte dans l'arbre de parent en parent jusqu'à atteindre la racine,
Noeud parent = noeud; * en mettant à jour le nombre de visite de chaque noeud,
* et le score des noeud dont le joueur est soit le perdant, soit le joueur null.
while (parent != null) { */
parent.getEtat().updateNbVisite();
if (gagnant == null) { public void propagationArriere() {
parent.getEtat().updateNbVictoire(0.5); while (noeud != null) {
noeud.getEtat().updateNbVisite();
if (plateau.vainqueur() == null) {
noeud.getEtat().updateNbVictoire(0.5);
} }
if (gagnant != null && parent.getEtat().getJoueur() != gagnant) { if (plateau.vainqueur() != null && noeud.getEtat().getJoueur() != plateau.vainqueur()) {
parent.getEtat().updateNbVictoire(1); noeud.getEtat().updateNbVictoire(1);
} }
parent = parent.getParent(); noeud = noeud.getParent();
} }
noeud = racine;
plateau.restaurePosition(0);
} }
} }
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