Commit ef7431c2 authored by MACE Lloyd's avatar MACE Lloyd

Class MCTS

parent 0903b6e0
/*
* 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 mcts;
import java.util.ArrayList;
import java.util.Random;
import tictactoecodingame.AlgoRechercheAleatoire;
import tictactoecodingame.Coup;
import tictactoecodingame.Joueur;
import tictactoecodingame.JoueurOrdi;
import tictactoecodingame.Plateau;
/**
*
* @author Lloyd
*/
public class MCTS {
Plateau plateau;
Noeud racine;
double coefficientUCT;
Joueur joueur;
JoueurOrdi joueurOrdiSimulation; //ordinateur algoRechercheAleatoire durant les simulations
//CONSTRUCTEUR
public MCTS(Plateau plateau, Joueur joueur) {
this.plateau = plateau;
this.joueur = joueur;
coefficientUCT = Math.sqrt(2);
racine = new Noeud();
racine.setEtat(new Etat(plateau, joueur));
AlgoRechercheAleatoire algoAleatoire = new AlgoRechercheAleatoire();
joueurOrdiSimulation = new JoueurOrdi("jOS", algoAleatoire);
}
//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;
int resultat;
noeudPrometteur = selection();
//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());
}
}
else {
resultat = simulation(noeudPrometteur);
propagationArriere(noeudPrometteur, resultat);
}
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.println();
System.out.println(racine.getEtat().getNbVictoire() + "/" + racine.getEtat().getNbVisite() + " " );
}
joueur.setIdJoueur(racine.getEtat().getNumJoueur());
return Util.getMeilleurCoup(racine, joueur);
}
//4 PHASE DU MCTS
//Selectionne le noeud "prometteur" grâce à UCT.
public Noeud selection() {
Noeud noeudPrometteur = racine;
while (!noeudPrometteur.getListeEnfant().isEmpty()) {
noeudPrometteur = UCT.trouverNoeudPrometteur(noeudPrometteur, coefficientUCT);
}
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();
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);
Etat etat = new Etat();
etat.setPlateau(nouveauPlateau);
etat.setCoupsPossibles(nouveauCoupsPossibles);
etat.setNumJoueur(numAdversaire);
Noeud nouveauNoeud = new Noeud(etat, noeud);
noeud.getListeEnfant().add(nouveauNoeud);
return nouveauNoeud;
}
/*
public Noeud expansion(Noeud noeud) {
ArrayList<Coup> coupsPossibles = noeud.getEtat().getCoupsPossibles();
if (!coupsPossibles.isEmpty()) {
Random r = new Random();
int randomIndex = r.nextInt(coupsPossibles.size());
Coup randomCoup = coupsPossibles.remove(randomIndex);
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.setPlateau(nouveauPlateau);
etat.setCoupsPossibles(nouveauCoupsPossibles);
etat.setNumJoueur(numAdversaire);
Noeud nouveauNoeud = new Noeud(etat, noeud);
noeud.getListeEnfant().add(nouveauNoeud);
return nouveauNoeud;
}
return noeud;
}
*/
//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;
while (!plateauTemporaire.partieTerminee()) {
Coup coup = joueurOrdiSimulation.joue(plateauTemporaire);
plateauTemporaire.joueCoup(coup);
Util.setAdversaire(joueurOrdiSimulation);
}
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;
}
}
return resultat;
}
//Une fois la simulation terminée, on met à jour l'arbre
public void propagationArriere(Noeud noeud, int resultat) {
int numJoueur = noeud.getEtat().getNumJoueur();
Noeud parent = noeud;
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();
}
}
}
parent = parent.getParent();
}
}
}
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