From a0033627ccf8770c1a7d067a3b881425dfe5331e Mon Sep 17 00:00:00 2001 From: Jerome Bedier Date: Thu, 22 May 2025 22:47:44 +0200 Subject: [PATCH] to avoid dumb autoplayer best move + random --- src/backend/AutoPlayer.java | 82 ++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 15 deletions(-) diff --git a/src/backend/AutoPlayer.java b/src/backend/AutoPlayer.java index 6b6fd6b..98da544 100644 --- a/src/backend/AutoPlayer.java +++ b/src/backend/AutoPlayer.java @@ -1,32 +1,84 @@ package backend; import java.util.ArrayList; +import java.util.List; import java.util.Random; public class AutoPlayer { + private Integer lastMovedPieceHash = null; // Use piece's position and color for tracking - /** - * Returns a random legal move for the active player. - */ public Move computeBestMove(Board board) { - ArrayList pieces = board.getPieces(); - ArrayList allMoves = new ArrayList<>(); - boolean isWhite = board.isTurnWhite(); + // Stop if only one king is left + int kingCount = 0; + for (Piece piece : board.getPieces()) { + if (piece.getType() == PieceType.King) kingCount++; + } + if (kingCount <= 1) { + return null; + } + + ArrayList pieces = board.getPieces(); + boolean isWhite = board.isTurnWhite(); + int bestPriority = Integer.MIN_VALUE; + List bestMoves = new ArrayList<>(); + List movePieceHashes = new ArrayList<>(); - // Collect all legal moves for all of the active player's pieces for (Piece piece : pieces) { if (piece.isWhite() == isWhite) { + // Skip if this piece was just moved last time + int pieceHash = (piece.getX()*31 + piece.getY()) * (piece.isWhite() ? 1 : -1); + if (lastMovedPieceHash != null && pieceHash == lastMovedPieceHash) { + continue; + } + ArrayList moves = board.getLegalMoves(piece); - allMoves.addAll(moves); + for (Move move : moves) { + Board copy = new Board(board); + copy.playMove(move); + Piece enemyKing = copy.findKing(!isWhite); + if (enemyKing == null) { + // Move that captures the king (not standard chess, but per your requirements) + // Remember which piece makes this move + bestMoves.clear(); + bestMoves.add(move); + movePieceHashes.clear(); + movePieceHashes.add(pieceHash); + bestPriority = Integer.MAX_VALUE; + break; + } + // Manhattan distance from this piece (after move) to enemy king + int dist = Math.abs(move.getToX() - enemyKing.getX()) + Math.abs(move.getToY() - enemyKing.getY()); + int priority = -dist; + + // Bonus if move puts king in check + if (copy.isKingInCheck(!isWhite)) { + priority += 1000; + } + + if (priority > bestPriority) { + bestPriority = priority; + bestMoves.clear(); + bestMoves.add(move); + movePieceHashes.clear(); + movePieceHashes.add(pieceHash); + } else if (priority == bestPriority) { + bestMoves.add(move); + movePieceHashes.add(pieceHash); + } + } } } - - if (allMoves.isEmpty()) { - return null; // No moves = checkmate or stalemate - } - - // Pick a random move + if (bestMoves.isEmpty()) return null; + // Randomly pick among best moves Random rand = new Random(); - return allMoves.get(rand.nextInt(allMoves.size())); + int idx = rand.nextInt(bestMoves.size()); + // Set last moved piece hash for next time + lastMovedPieceHash = movePieceHashes.get(idx); + return bestMoves.get(idx); + } + + // Optional: Call this after a human move to reset tracking + public void resetLastMovedPiece() { + lastMovedPieceHash = null; } } \ No newline at end of file