to avoid dumb autoplayer best move + random

This commit is contained in:
Jérôme BEDIER 2025-05-22 22:47:44 +02:00
parent ef14d4973d
commit a0033627cc
1 changed files with 67 additions and 15 deletions

View File

@ -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<Piece> pieces = board.getPieces();
ArrayList<Move> 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<Piece> pieces = board.getPieces();
boolean isWhite = board.isTurnWhite();
int bestPriority = Integer.MIN_VALUE;
List<Move> bestMoves = new ArrayList<>();
List<Integer> 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<Move> 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;
}
}