package fr.iut_fbleau.Nim; import fr.iut_fbleau.GameAPI.AbstractGamePlayer; import fr.iut_fbleau.GameAPI.AbstractPly; import fr.iut_fbleau.GameAPI.IBoard; import fr.iut_fbleau.GameAPI.Player; import fr.iut_fbleau.GameAPI.Result; import java.util.Iterator; /** * Représente un joueur bot pour le jeu de Nim. * Le bot utilise l'algorithme MiniMax avec élagage Alpha-Beta pour choisir le meilleur coup. */ public class NimBotPlayer extends AbstractGamePlayer { private Player joueur; /** * Constructeur d'un bot joueur de Nim * * @param joueur le type de joueur (PLAYER1 ou PLAYER2) */ public NimBotPlayer(Player joueur) { this.joueur = joueur; } @Override public AbstractPly giveYourMove(IBoard p) { if (!(p instanceof NimBoard)) { throw new IllegalArgumentException("Le plateau doit être un NimBoard"); } NimBoard plateau = (NimBoard) p; System.out.println("\n" + plateau); System.out.println("Le bot réfléchit..."); AbstractPly meilleurCoup = findBestMove(plateau); System.out.println("Le bot joue : " + meilleurCoup); return meilleurCoup; } /** * Trouve le meilleur coup à jouer en utilisant l'algorithme MiniMax avec Alpha-Beta */ private AbstractPly findBestMove(NimBoard plateau) { AbstractPly meilleurCoup = null; int meilleureValeur; if (this.joueur == Player.PLAYER1) { meilleureValeur = Integer.MIN_VALUE; Iterator coups = plateau.iterator(); while (coups.hasNext()) { AbstractPly coup = coups.next(); plateau.doPly(coup); int score = minimax(plateau, Integer.MIN_VALUE, Integer.MAX_VALUE, false); plateau.undoPly(); if (score > meilleureValeur) { meilleureValeur = score; meilleurCoup = coup; } } } else { meilleureValeur = Integer.MAX_VALUE; Iterator coups = plateau.iterator(); while (coups.hasNext()) { AbstractPly coup = coups.next(); plateau.doPly(coup); int score = minimax(plateau, Integer.MIN_VALUE, Integer.MAX_VALUE, true); plateau.undoPly(); if (score < meilleureValeur) { meilleureValeur = score; meilleurCoup = coup; } } } return meilleurCoup; } /** * Algorithme MiniMax avec élagage Alpha-Beta * * @param plateau le plateau de jeu * @param alpha la valeur alpha pour l'élagage * @param beta la valeur beta pour l'élagage * @param isMaximizing true si on maximise, false si on minimise * @return l'évaluation de la position */ private int minimax(NimBoard plateau, int alpha, int beta, boolean isMaximizing) { // Condition terminale : jeu fini if (plateau.isGameOver()) { Result result = plateau.getResult(); if (result == Result.WIN) { return 1; // PLAYER1 gagne } else if (result == Result.LOSS) { return -1; // PLAYER1 perd (PLAYER2 gagne) } else { return 0; // Match nul } } if (isMaximizing) { // Maximiser pour PLAYER1 int max = Integer.MIN_VALUE; Iterator coups = plateau.iterator(); while (coups.hasNext()) { AbstractPly coup = coups.next(); plateau.doPly(coup); int eval = minimax(plateau, alpha, beta, false); plateau.undoPly(); max = Math.max(max, eval); alpha = Math.max(alpha, eval); // Élagage Beta if (beta <= alpha) { break; } } return max; } else { // Minimiser pour PLAYER2 int min = Integer.MAX_VALUE; Iterator coups = plateau.iterator(); while (coups.hasNext()) { AbstractPly coup = coups.next(); plateau.doPly(coup); int eval = minimax(plateau, alpha, beta, true); plateau.undoPly(); min = Math.min(min, eval); beta = Math.min(beta, eval); // Élagage Alpha if (beta <= alpha) { break; } } return min; } } /** * @return le type de joueur */ public Player getPlayer() { return this.joueur; } }