From 89c8f689dd4fc0b4afaf06a09f72b915387ac14f Mon Sep 17 00:00:00 2001 From: "g.levassor--gentil" Date: Fri, 16 May 2025 09:30:28 +0200 Subject: [PATCH] autoplayer upgraded 2 moves ahead --- src/backend/AutoPlayer.java | 86 +++++++++++++++++++++++++------------ 1 file changed, 59 insertions(+), 27 deletions(-) diff --git a/src/backend/AutoPlayer.java b/src/backend/AutoPlayer.java index 1d15d8e..ea326e6 100644 --- a/src/backend/AutoPlayer.java +++ b/src/backend/AutoPlayer.java @@ -4,13 +4,69 @@ import java.util.ArrayList; public class AutoPlayer { + private static final int MAX_DEPTH = 2; // You can increase this for stronger AI + public Move computeBestMove(Board board) { + return minimax(board, MAX_DEPTH, board.isTurnWhite()).bestMove; + } + + private static class ScoredMove { + Move bestMove; + int score; + + ScoredMove(Move move, int score) { + this.bestMove = move; + this.score = score; + } + } + + private ScoredMove minimax(Board board, int depth, boolean isMaximizing) { + if (depth == 0) { + return new ScoredMove(null, evaluateBoard(board)); + } + + ArrayList possibleMoves = generateAllMoves(board, isMaximizing); + if (possibleMoves.isEmpty()) { + return new ScoredMove(null, evaluateBoard(board)); + } + + Move bestMove = null; + int bestScore = isMaximizing ? Integer.MIN_VALUE : Integer.MAX_VALUE; + + for (Move move : possibleMoves) { + Board boardCopy = new Board(board); // Deep copy + boardCopy.playMove(move); + + int score = minimax(boardCopy, depth - 1, !isMaximizing).score; + + if (isMaximizing && score > bestScore) { + bestScore = score; + bestMove = move; + } else if (!isMaximizing && score < bestScore) { + bestScore = score; + bestMove = move; + } + } + + return new ScoredMove(bestMove, bestScore); + } + + private int evaluateBoard(Board board) { + int score = 0; + for (Piece p : board.getPieces()) { + int value = pieceValue(p.getType()); + score += p.isWhite() ? value : -value; + } + return score; + } + + private ArrayList generateAllMoves(Board board, boolean isWhite) { ArrayList allMoves = new ArrayList<>(); - boolean isWhite = board.isTurnWhite(); for (Piece piece : board.getPieces()) { if (piece.isWhite() != isWhite) continue; - ArrayList legalMoves = getLegalMoves(board, piece); + + ArrayList legalMoves = board.computeLegalMoves(piece); for (int[] move : legalMoves) { Piece target = getPieceAt(board, move[0], move[1]); Move candidate = new Move( @@ -23,26 +79,7 @@ public class AutoPlayer { } } - // Evaluate moves - Move bestMove = null; - int bestScore = Integer.MIN_VALUE; - - for (Move move : allMoves) { - int score = evaluateMove(move); - if (score > bestScore) { - bestScore = score; - bestMove = move; - } - } - - return bestMove; - } - - private int evaluateMove(Move move) { - if (move.getCapturedPiece() != null) { - return pieceValue(move.getCapturedPiece().getType()); - } - return 0; + return allMoves; } private int pieceValue(PieceType type) { @@ -57,11 +94,6 @@ public class AutoPlayer { } } - private ArrayList getLegalMoves(Board board, Piece piece) { - // Reuse board's internal method - // But we must simulate access: simulate selection, compute, and reset - return board.computeLegalMoves(piece); - } private Piece getPieceAt(Board board, int x, int y) { for (Piece p : board.getPieces()) {