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

Replace MCTS.java

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