to avoid dumb autoplayer best move + random
This commit is contained in:
parent
ef14d4973d
commit
a0033627cc
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue