Partage
  • Partager sur Facebook
  • Partager sur Twitter

Algorithme min max pour un puissance 4

    20 avril 2023 à 13:43:37

    Bonjour, j'ai codé un puissance 4 joueur vs joueur et maintenant je dois implémenter une IA pour jouer contre, celle-ci doit implémenter dans un premier temps l'algorithme min max basique puis l'élagage alpha beta.

    Je suis à l'étape de l'algorithme min max, je me suis inspiré de ce que j'ai trouvé sur internet mais j'ai un problème, l'ordinateur va toujours jouer sur la dernière colonne disponible je ne comprends pas pourquoi.

    Merci pour votre aide

    Voici mes classes :

    Ma classe Grille :

    public class Grille {
        private final int nbLignes = 6;
        private int nbColonnes = 7;
        private Jeton[][] grille;
    
        public Grille(){
            this.grille = new Jeton[nbLignes][nbColonnes];
            initialiserGrille();
        }
    
        public int getNbLignes() {
            return nbLignes;
        }
    
        public int getNbColonnes() {
            return nbColonnes;
        }
    
        public Jeton getJeton(int ligne, int colonne) {
            return grille[ligne][colonne];
        }
        
        public boolean estColonneValide(int colonne) {
            // Vérifier que la colonne est dans les limites de la grille
            if (colonne < 0 || colonne >= nbColonnes) {
                return false;
            }
            
            if (grille[0][colonne].getSymbole() != '.') {
            	return false;
            }
            return true;
        }
        
        public void placerJeton(Jeton jeton, int colonne) {
                int ligne = nbLignes - 1;
                while (ligne >= 0 && grille[ligne][colonne].getSymbole() != '.') {
                    ligne--;
                }
                if(ligne >= 0) {
                	grille[ligne][colonne] = jeton;
            }
        }
        
        public boolean estPleine() {
            for (int i = 0; i < nbColonnes; i++) {
                if (grille[0][i].getSymbole() == '.') {
                    return false;
                }
            }
            return true;
        }
        
        public boolean estColonnePleine(int c) {
            if (grille[0][c].getSymbole() == '.') {
               return false;
            }
            return true;
        }
        
        public boolean estGagnante(Jeton jeton) {
            // Vérifie les lignes
            for (int i = 0; i < 6; i++) {
                for (int j = 0; j < 4; j++) {
                    if (grille[i][j] == jeton && grille[i][j+1] == jeton && grille[i][j+2] == jeton && grille[i][j+3] == jeton) {
                        return true;
                    }
                }
            }
            // Vérifie les colonnes
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 7; j++) {
                    if (grille[i][j] == jeton && grille[i+1][j] == jeton && grille[i+2][j] == jeton && grille[i+3][j] == jeton) {
                        return true;
                    }
                }
            }
            // Vérifie les diagonales descendantes
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 4; j++) {
                    if (grille[i][j] == jeton && grille[i+1][j+1] == jeton && grille[i+2][j+2] == jeton && grille[i+3][j+3] == jeton) {
                        return true;
                    }
                }
            }
            // Vérifie les diagonales montantes
            for (int i = 3; i < 6; i++) {
                for (int j = 0; j < 4; j++) {
                    if (grille[i][j] == jeton && grille[i-1][j+1] == jeton && grille[i-2][j+2] == jeton && grille[i-3][j+3] == jeton) {
                        return true;
                    }
                }
            }
            return false;
        }
        
        public void initialiserGrille() {
            for (int i = 0; i < nbLignes; i++) {
                for (int j = 0; j < nbColonnes; j++) {
                    grille[i][j] = new Jeton('.');
                }
            }
        }
        
        public Grille copie() {
        	Grille nouvelleGrille = new Grille();
            for (int i = 0; i < nbLignes; i++) {
                for (int j = 0; j < nbColonnes; j++) {
                    nouvelleGrille.grille[i][j] = grille[i][j];
                }
            }
            return nouvelleGrille;
        }
    
        public void afficher() {
            for (int ligne = 0; ligne < nbLignes; ligne++) {
                for (int colonne = 0; colonne < nbColonnes; colonne++) {
                    if (grille[ligne][colonne].getSymbole() == '.') {
                        System.out.print("| ");
                    }
                    else 
                    {
                        System.out.print("|" + grille[ligne][colonne].getSymbole());
                    }
                }
                System.out.println("|");
            }
            System.out.println("---------------");
        }
    }

    Ma classe Jeton :

    public class Jeton {
        public static final Jeton ORDINATEUR = new Jeton('J');
        public static final Jeton JOUEUR = new Jeton('R');
    	private char symbole;
    
        public Jeton(char symbole) {
            this.symbole = symbole;
        }
    
        public char getSymbole() {
            return symbole;
        }
    
        public void setSymbole(char symbole) {
            this.symbole = symbole;
        }
    }

    Ma classe Joueur :

    public class Joueur {
        private String nom;
        private Jeton jeton;
        
        public Joueur(String nom, Jeton jeton) {
            this.nom = nom;
            this.jeton = jeton;
        }
        
        public Joueur() {
        	
        }
    
        public String getNom() {
            return nom;
        }
    
        public Jeton getJeton() {
            return jeton;
        }
    }

    Ma classe Puissance 4 :

    package projet;
    
    import java.util.Scanner;
    
    public class Puissance4 {
    	   private Grille grille;
    	   private Joueur joueur1;
    	   private MinMax joueur2;
    	   private Joueur joueurCourant;
    	   private static Puissance4 partie;
    	   static {
    		   partie = new Puissance4();
    	   }
    	   public Puissance4() {
    		      grille = new Grille();
    		      joueur1 = new Joueur("Joueur 1", new Jeton('R'));
    		      joueur2 = new MinMax("Ordinateur", new Jeton('J'));//Joueur("Joueur 2", new Jeton('J'));
    		      joueurCourant = joueur1;
    		   }
    	   
    	   public static Puissance4 getPartie(){
    			return partie;
    		}
    	   
    	   public Joueur joueurSuivant(Joueur joueur) {
    		   return (joueur == this.joueur1) ? this.joueur2 : this.joueur1;
    	   }
    	   
    	   public void jouer() {
    	      Scanner input = new Scanner(System.in);
    	      grille.initialiserGrille();
    	      grille.afficher();
    
    	      boolean gameOver = false;
    	      while (!gameOver) {
    	    	  if(joueurCourant == joueur2) {
    	    		  int colonne = joueur2.choisirCoup(grille, joueurCourant);
    	    		  grille.placerJeton(joueurCourant.getJeton(), colonne);
    	    		  grille.afficher();
    	    	  }
    	    	  else {
    	    		  System.out.println(joueurCourant.getNom() + ", choisissez une colonne pour placer votre jeton : ");
    	 	         int colonne = input.nextInt();
    
    	 	         while (!grille.estColonneValide(colonne)) {
    	 	            System.out.println("Colonne invalide ou occupée. Veuillez choisir une autre colonne : ");
    	 	            colonne = input.nextInt();
    	 	         }
    
    	 	         grille.placerJeton(joueurCourant.getJeton(), colonne);
    	 	         grille.afficher();
    	    	  }
    	 	         if (grille.estGagnante(joueurCourant.getJeton())) {
    	 	            System.out.println(joueurCourant.getNom() + " a gagné !");
    	 	            gameOver = true;
    	 	         } else if (grille.estPleine()) {
    	 	            System.out.println("La grille est pleine. Match nul !");
    	 	            gameOver = true;
    	 	         } else {
    	 	            joueurCourant = joueurSuivant(joueurCourant);
    	 	         }
    	    	  }
    	      input.close();
    	      }
    	   }

    Ma classe min max: 

    public class MinMax extends Joueur {
    
    	private static final int PROFONDEUR_EXPLORATION_MIN_MAX = 3;
    	public MinMax(String nom, Jeton jeton) {
    		super(nom,jeton);
    	}
    	
    	private double min(Grille grille, Joueur joueur, int profondeur) {
    		double valeurDeJeu = Integer.MAX_VALUE;
    		if(profondeur != 0) {
    			for (int i = 0 ; i < 7 ; i++) {
    				if(!grille.estColonnePleine(i)) {
    					Grille grilleTmp = grille.copie();
    					Jeton jeton = new Jeton(Puissance4.getPartie().joueurSuivant(joueur).getJeton().getSymbole());
    					grilleTmp.placerJeton(jeton, i);
    					//System.out.println("valeur max "+this.max(grilleTmp,joueur,profondeur-1));
    					valeurDeJeu = Math.min(valeurDeJeu, this.max(grilleTmp,joueur,profondeur-1));
    					//System.out.println("min vdj "+valeurDeJeu);
    				}
    			}
    			return valeurDeJeu;
    		}
    		else {
    			return evaluation(grille);
    		}
    	}
    	
    	private double max(Grille grille, Joueur joueur, int profondeur) {
    		double valeurDeJeu = Integer.MIN_VALUE;
    		if(profondeur != 0) {
    			for (int i = 0 ; i < 7 ; i++) {
    				if(!grille.estColonnePleine(i)) {
    					Grille grilleTmp = grille.copie();
    					Jeton jeton = new Jeton(joueur.getJeton().getSymbole());
    					grilleTmp.placerJeton(jeton, i);
    					valeurDeJeu = Math.max(valeurDeJeu, this.min(grilleTmp,joueur,profondeur-1));
    					System.out.println(" max vdj "+valeurDeJeu);
    				}
    			}
    			return valeurDeJeu;
    		}
    		else {
    			return evaluation(grille);
    		}
    	}
    	
    	private double minmax(Grille grille, Joueur joueur,  int profondeur){
    		return this.min(grille, joueur, profondeur);
    	}
    	
    	public int choisirCoup(Grille grille, Joueur joueur) {
    		int colonneAJoueur = -1;
    		double valeurDeJeu = Double.NEGATIVE_INFINITY;;
    		for (int i = 0 ; i < 7 ; i++) {
    			if(!grille.estColonnePleine(i)) {
    				Grille grilleTmp = grille.copie();
    				Jeton jeton = new Jeton(joueur.getJeton().getSymbole());
    				grilleTmp.placerJeton(jeton, i);
    				double valeurDeJeuCourante = minmax(grilleTmp, joueur, PROFONDEUR_EXPLORATION_MIN_MAX);
    				//System.out.println("vdjc "+valeurDeJeuCourante);
    				//System.out.println("vdj "+valeurDeJeu);
    				if(valeurDeJeuCourante >= valeurDeJeu) {
    					valeurDeJeu = valeurDeJeuCourante;
    					colonneAJoueur = i;
    				}
    			}
    		}
    		System.out.println("voici la colonne a jouer "+colonneAJoueur);
    		return colonneAJoueur;
    	}
    	
    	private int evaluation(Grille grille) {
    	    int score = 0;
    
    	    // Vérifier les alignements horizontaux
    	    for (int ligne = 0; ligne < grille.getNbLignes(); ligne++) {
    	        for (int colonne = 0; colonne < grille.getNbColonnes() - 3; colonne++) {
    	            score += evaluerAlignement(grille.getJeton(ligne, colonne), grille.getJeton(ligne, colonne + 1),
    	                                        grille.getJeton(ligne, colonne + 2), grille.getJeton(ligne, colonne + 3));
    	        }
    	    }
    
    	    // Vérifier les alignements verticaux
    	    for (int ligne = 0; ligne < grille.getNbLignes() - 3; ligne++) {
    	        for (int colonne = 0; colonne < grille.getNbColonnes(); colonne++) {
    	            score += evaluerAlignement(grille.getJeton(ligne, colonne), grille.getJeton(ligne + 1, colonne),
    	                                        grille.getJeton(ligne + 2, colonne), grille.getJeton(ligne + 3, colonne));
    	        }
    	    }
    
    	    // Vérifier les alignements diagonaux vers le bas
    	    for (int ligne = 0; ligne < grille.getNbLignes() - 3; ligne++) {
    	        for (int colonne = 0; colonne < grille.getNbColonnes() - 3; colonne++) {
    	            score += evaluerAlignement(grille.getJeton(ligne, colonne), grille.getJeton(ligne + 1, colonne + 1),
    	                                        grille.getJeton(ligne + 2, colonne + 2), grille.getJeton(ligne + 3, colonne + 3));
    	        }
    	    }
    
    	    // Vérifier les alignements diagonaux vers le haut
    	    for (int ligne = 3; ligne < grille.getNbLignes(); ligne++) {
    	        for (int colonne = 0; colonne < grille.getNbColonnes() - 3; colonne++) {
    	            score += evaluerAlignement(grille.getJeton(ligne, colonne), grille.getJeton(ligne - 1, colonne + 1),
    	                                        grille.getJeton(ligne - 2, colonne + 2), grille.getJeton(ligne - 3, colonne + 3));
    	        }
    	    }
    
    	    return score;
    	}
       private int evaluerAlignement(Jeton jeton1, Jeton jeton2, Jeton jeton3, Jeton jeton4) {
    	    int score = 0;
    	    int nbJetonsJoueur = 0;
    	    int nbJetonsOrdinateur = 0;
    	    int nbJetonsVides = 0;
    
    	    // Vérifier le nombre de jetons du joueur, de l'ordinateur et vides dans l'alignement
    	    if (jeton1 == Jeton.JOUEUR) {
    	        nbJetonsJoueur++;
    	    } else if (jeton1 == Jeton.ORDINATEUR) {
    	        nbJetonsOrdinateur++;
    	    } else {
    	        nbJetonsVides++;
    	    }
    
    	    if (jeton2 == Jeton.JOUEUR) {
    	        nbJetonsJoueur++;
    	    } else if (jeton2 == Jeton.ORDINATEUR) {
    	        nbJetonsOrdinateur++;
    	    } else {
    	        nbJetonsVides++;
    	    }
    
    	    if (jeton3 == Jeton.JOUEUR) {
    	        nbJetonsJoueur++;
    	    } else if (jeton3 == Jeton.ORDINATEUR) {
    	        nbJetonsOrdinateur++;
    	    } else {
    	        nbJetonsVides++;
    	    }
    
    	    if (jeton4 == Jeton.JOUEUR) {
    	        nbJetonsJoueur++;
    	    } else if (jeton4 == Jeton.ORDINATEUR) {
    	        nbJetonsOrdinateur++;
    	    } else {
    	        nbJetonsVides++;
    	    }
    
    	    // Calculer le score en fonction du nombre de jetons du joueur et de l'ordinateur
    	    if (nbJetonsJoueur == 4) {
    	        score += 1000;
    	    } else if (nbJetonsJoueur == 3 && nbJetonsVides == 1) {
    	        score += 5;
    	    } else if (nbJetonsJoueur == 2 && nbJetonsVides == 2) {
    	        score += 2;
    	    }
    
    	    if (nbJetonsOrdinateur == 4) {
    	        score -= 1000;
    	    } else if (nbJetonsOrdinateur == 3 && nbJetonsVides == 1) {
    	        score -= 5;
    	    } else if (nbJetonsOrdinateur == 2 && nbJetonsVides == 2) {
    	        score -= 2;
    	    }
    
    	    return score;
    	}
    }
    
    
    




    • Partager sur Facebook
    • Partager sur Twitter

    Algorithme min max pour un puissance 4

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown