/* * 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 static java.lang.Math.max; import static java.lang.Math.min; import java.util.ArrayList; /** * * @author Alain */ public class AlgoRechercheMinMax_9x9 extends AlgoRecherche { /* Le but de cet algorithme est d'implémenter la méthode MinMax au jeu TicTacToe9x9. La fonction d'évaluation est ici plus compliqué elle retourne 10 sur le noeud si l'ordi gagne une case et -10 si l'ordi perd une case. Cet algorithme est implémenté avec l'amélioration alpha beta. */ Joueur humain; Joueur ordi; public AlgoRechercheMinMax_9x9(Joueur _ordi1, Joueur _joueur1){ ordi = _ordi1; humain = _joueur1; } double[] scores = {-1000,1000,0}; @Override public Coup meilleurCoup(Plateau _plateau, Joueur _joueur, boolean ponder){ /* MeilleurCoup prend en paramètre un plateau, un joueur (non utilisé ici mais qui serait l'ordi) et un boolean pour laisser l'ordi réfléchir. */ double inf = Double.POSITIVE_INFINITY; double bestScore = -1 * inf; CoupTicTacToe meilleur_coup = null ; GrilleTicTacToe9x9 _plateau1 = (GrilleTicTacToe9x9) _plateau; CoupTicTacToe coup_humain = _plateau1.dernierCoup; double alpha = -1 * inf; // méthode alpha beta double beta = inf; ArrayList<Coup> coups = _plateau.getListeCoups(ordi); for (int i = 0; i < coups.size(); i++){ _plateau.sauvegardePosition(0); _plateau.joueCoup(coups.get(i)); double score = minimax(_plateau,humain,1,false,alpha,beta); //False car l'ordi a déjà placé son premier coup Coup coup_provisoire = coups.get(i); _plateau.restaurePosition(0); if (score > bestScore){ bestScore = score; meilleur_coup = (CoupTicTacToe)coup_provisoire; } } _plateau1.dernierCoup = coup_humain; return meilleur_coup; // changer le tour du joueur } public double minimax(Plateau _plateau,Joueur _joueur,int profondeur,boolean isMaximizing, double alpha, double beta){ /* minimax prend en paramètre un plateau, le joueur qui va jouer, la profondeur, un boolean pour savoir si on doit maximiser ou minimiser et des doubles alpha et beta pour implémenter la méthode alpha beta. */ if (_plateau.partieTerminee()){ if(_plateau.partieNulle()){ return 0; } else{ Joueur gagnant = _plateau.vainqueur(); //Il faudrait connaitre le vainqueur if (gagnant != null){ int resultat = gagnant.getIdJoueur(); return scores[resultat];} else{ return 0; } } } if(profondeur>5){ return evaluation(_plateau); } if (isMaximizing) { //ordi qui joue double inf = Double.POSITIVE_INFINITY; double bestScore = -1 * inf; ArrayList<Coup> coups = _plateau.getListeCoups(ordi); for (int i = 0; i < coups.size(); i++){ _plateau.sauvegardePosition(profondeur); _plateau.joueCoup(coups.get(i)); double score = minimax(_plateau,humain,profondeur + 1,false,alpha,beta); _plateau.restaurePosition(profondeur); alpha = max(alpha,score); if (beta <= alpha){ break; } bestScore = max(score,bestScore); } return bestScore; } else { // Humain ou autre ordi qui joue double inf = Double.POSITIVE_INFINITY; double bestScore = inf; ArrayList<Coup> coups = _plateau.getListeCoups(humain); for (int i = 0; i < coups.size(); i++){ _plateau.sauvegardePosition(profondeur); _plateau.joueCoup(coups.get(i)); double score = minimax(_plateau,ordi,profondeur + 1,true,alpha,beta); _plateau.restaurePosition(profondeur); beta = min(beta,score); if (beta <= alpha){ break; } bestScore = min(score,bestScore); } return bestScore; } } public double evaluation(Plateau _plateau1){ // Fonction d'évaluation pour attribuer un score si une case a été remportée ou non. GrilleTicTacToe9x9 _plateau = (GrilleTicTacToe9x9) _plateau1; double delta = 0; for(int i = 0; i < 3; i++){ // abscisse de la case 3x3 for(int j = 0; j < 3; j++){ //ordonnée de la case 3x3 for(int k = 0; k < 3; k++){ // absisse de la case 9x9 for(int l = 0; l< 3; l++){ // ordonnée de la case 9x9 Case case1 = new Case(3*i + k, 3*j + l); Piece p = _plateau.getPiece(case1); if (p!= null && p.getJoueur() == humain){ if (_plateau.caseGagnante(_plateau.grille9x9, 3*i, 3*j, 3*i + k, 3*j + l)){ // Si l'humain gagne delta = delta - 10; return delta;} } if (p!= null && p.getJoueur() == ordi){ if (_plateau.caseGagnante(_plateau.grille9x9, 3*i, 3*j, 3*i + k, 3*j + l)){ // Si l'ordi gagne delta = delta + 10; return delta;} } } } } } return 0; } }