package iialib.games.algs.algorithms; import iialib.games.algs.GameAlgorithm; import iialib.games.algs.IHeuristic; import iialib.games.model.IBoard; import iialib.games.model.IMove; import iialib.games.model.IRole; public class MiniMax> implements GameAlgorithm { // Constants /** Defaut value for depth limit */ private final static int DEPTH_MAX_DEFAUT = 4; // Attributes /** Role of the max player */ private final Role playerMaxRole; /** Role of the min player */ private final Role playerMinRole; /** Algorithm max depth */ private int depthMax = DEPTH_MAX_DEFAUT; /** Heuristic used by the max player */ private IHeuristic h; // /** number of internal visited (developed) nodes (for stats) */ private int nbNodes; /** number of leaves nodes nodes (for stats) */ private int nbLeaves; // --------- Constructors --------- public MiniMax(Role playerMaxRole, Role playerMinRole, IHeuristic h) { this.playerMaxRole = playerMaxRole; this.playerMinRole = playerMinRole; this.h = h; } // public MiniMax(Role playerMaxRole, Role playerMinRole, IHeuristic h, int depthMax) { this(playerMaxRole, playerMinRole, h); this.depthMax = depthMax; } /* * IAlgo METHODS ============= */ @Override public Move bestMove(Board board, Role playerRole) { System.out.println("[MiniMax]"); nbNodes = 0; nbLeaves = 0; Move bestMove = null; int bestValue = IHeuristic.MIN_VALUE; for (Move move : board.possibleMoves(playerMaxRole)) { Board successor = board.play(move, playerMaxRole); int value = minValue(successor, 1); if (value > bestValue) { bestValue = value; bestMove = move; } } System.out.println("Nodes=" + nbNodes + " Leaves=" + nbLeaves); return bestMove; } /* * PUBLIC METHODS ============== */ public String toString() { return "MiniMax(ProfMax=" + depthMax + ")"; } /* * PRIVATE METHODS =============== */ private int maxValue(Board board, int depth) { nbNodes++; if (board.isGameOver() || depth >= depthMax) { nbLeaves++; return h.eval(board, playerMaxRole); } int value = IHeuristic.MIN_VALUE; for (Move move : board.possibleMoves(playerMaxRole)) { Board successor = board.play(move, playerMaxRole); value = Math.max(value, minValue(successor, depth + 1)); } return value; } private int minValue(Board board, int depth) { nbNodes++; if (board.isGameOver() || depth >= depthMax) { nbLeaves++; return h.eval(board, playerMaxRole); } int value = IHeuristic.MAX_VALUE; for (Move move : board.possibleMoves(playerMinRole)) { Board successor = board.play(move, playerMinRole); value = Math.min(value, maxValue(successor, depth + 1)); } return value; } }