Part3.4
This commit is contained in:
parent
820183e90b
commit
9e86e6ee48
|
|
@ -0,0 +1,10 @@
|
||||||
|
BR,--,--,BQ,BK,--,--,BR
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
--,--,--,--,--,--,--,--
|
||||||
|
WR,--,--,WQ,WK,--,--,WR
|
||||||
|
W
|
||||||
|
000000,-1,-1
|
||||||
|
|
@ -7,3 +7,4 @@ BP,BP,BP,BP,BP,BP,BP,BP
|
||||||
WP,WP,WP,WP,WP,WP,WP,WP
|
WP,WP,WP,WP,WP,WP,WP,WP
|
||||||
WR,WN,WB,WQ,WK,WB,WN,WR
|
WR,WN,WB,WQ,WK,WB,WN,WR
|
||||||
W
|
W
|
||||||
|
000000,-1,-1
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public class Main {
|
||||||
// Test loading board from file
|
// Test loading board from file
|
||||||
Board loadedBoard = testLoadingBoard("default.board");
|
Board loadedBoard = testLoadingBoard("default.board");
|
||||||
if (loadedBoard != null) {
|
if (loadedBoard != null) {
|
||||||
System.out.println("Loaded board successfully:");
|
System.out.println("Loaded board successfully:");
|
||||||
System.out.println(loadedBoard.toString());
|
System.out.println(loadedBoard.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,373 @@ import java.util.ArrayList;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class AutoPlayer {
|
public class AutoPlayer {
|
||||||
|
private static final int DEFAULT_DEPTH = 3;
|
||||||
|
private int searchDepth;
|
||||||
|
private Random random = new Random(); // For choosing between equally valued moves
|
||||||
/**
|
|
||||||
* returns the best Move to try on provided board for active player
|
// Piece values for the evaluation function
|
||||||
* @param board
|
private static final int PAWN_VALUE = 100;
|
||||||
* @return
|
private static final int KNIGHT_VALUE = 320;
|
||||||
*/
|
private static final int BISHOP_VALUE = 330;
|
||||||
public Move computeBestMove(Board board) {
|
private static final int ROOK_VALUE = 500;
|
||||||
|
private static final int QUEEN_VALUE = 900;
|
||||||
return null;
|
private static final int KING_VALUE = 20000;
|
||||||
}
|
|
||||||
|
// Piece-Square tables for positional evaluation
|
||||||
|
private static final int[][] PAWN_TABLE = {
|
||||||
}
|
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{50, 50, 50, 50, 50, 50, 50, 50},
|
||||||
|
{10, 10, 20, 30, 30, 20, 10, 10},
|
||||||
|
{5, 5, 10, 25, 25, 10, 5, 5},
|
||||||
|
{0, 0, 0, 20, 20, 0, 0, 0},
|
||||||
|
{5, -5,-10, 0, 0,-10, -5, 5},
|
||||||
|
{5, 10, 10,-20,-20, 10, 10, 5},
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] KNIGHT_TABLE = {
|
||||||
|
{-50,-40,-30,-30,-30,-30,-40,-50},
|
||||||
|
{-40,-20, 0, 0, 0, 0,-20,-40},
|
||||||
|
{-30, 0, 10, 15, 15, 10, 0,-30},
|
||||||
|
{-30, 5, 15, 20, 20, 15, 5,-30},
|
||||||
|
{-30, 0, 15, 20, 20, 15, 0,-30},
|
||||||
|
{-30, 5, 10, 15, 15, 10, 5,-30},
|
||||||
|
{-40,-20, 0, 5, 5, 0,-20,-40},
|
||||||
|
{-50,-40,-30,-30,-30,-30,-40,-50}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] BISHOP_TABLE = {
|
||||||
|
{-20,-10,-10,-10,-10,-10,-10,-20},
|
||||||
|
{-10, 0, 0, 0, 0, 0, 0,-10},
|
||||||
|
{-10, 0, 10, 10, 10, 10, 0,-10},
|
||||||
|
{-10, 5, 5, 10, 10, 5, 5,-10},
|
||||||
|
{-10, 0, 5, 10, 10, 5, 0,-10},
|
||||||
|
{-10, 5, 5, 5, 5, 5, 5,-10},
|
||||||
|
{-10, 0, 5, 0, 0, 5, 0,-10},
|
||||||
|
{-20,-10,-10,-10,-10,-10,-10,-20}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] ROOK_TABLE = {
|
||||||
|
{0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{5, 10, 10, 10, 10, 10, 10, 5},
|
||||||
|
{-5, 0, 0, 0, 0, 0, 0, -5},
|
||||||
|
{-5, 0, 0, 0, 0, 0, 0, -5},
|
||||||
|
{-5, 0, 0, 0, 0, 0, 0, -5},
|
||||||
|
{-5, 0, 0, 0, 0, 0, 0, -5},
|
||||||
|
{-5, 0, 0, 0, 0, 0, 0, -5},
|
||||||
|
{0, 0, 0, 5, 5, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] QUEEN_TABLE = {
|
||||||
|
{-20,-10,-10, -5, -5,-10,-10,-20},
|
||||||
|
{-10, 0, 0, 0, 0, 0, 0,-10},
|
||||||
|
{-10, 0, 5, 5, 5, 5, 0,-10},
|
||||||
|
{-5, 0, 5, 5, 5, 5, 0, -5},
|
||||||
|
{0, 0, 5, 5, 5, 5, 0, -5},
|
||||||
|
{-10, 5, 5, 5, 5, 5, 0,-10},
|
||||||
|
{-10, 0, 5, 0, 0, 0, 0,-10},
|
||||||
|
{-20,-10,-10, -5, -5,-10,-10,-20}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] KING_TABLE_MIDDLEGAME = {
|
||||||
|
{-30,-40,-40,-50,-50,-40,-40,-30},
|
||||||
|
{-30,-40,-40,-50,-50,-40,-40,-30},
|
||||||
|
{-30,-40,-40,-50,-50,-40,-40,-30},
|
||||||
|
{-30,-40,-40,-50,-50,-40,-40,-30},
|
||||||
|
{-20,-30,-30,-40,-40,-30,-30,-20},
|
||||||
|
{-10,-20,-20,-20,-20,-20,-20,-10},
|
||||||
|
{20, 20, 0, 0, 0, 0, 20, 20},
|
||||||
|
{20, 30, 10, 0, 0, 10, 30, 20}
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[][] KING_TABLE_ENDGAME = {
|
||||||
|
{-50,-40,-30,-20,-20,-30,-40,-50},
|
||||||
|
{-30,-20,-10, 0, 0,-10,-20,-30},
|
||||||
|
{-30,-10, 20, 30, 30, 20,-10,-30},
|
||||||
|
{-30,-10, 30, 40, 40, 30,-10,-30},
|
||||||
|
{-30,-10, 30, 40, 40, 30,-10,-30},
|
||||||
|
{-30,-10, 20, 30, 30, 20,-10,-30},
|
||||||
|
{-30,-30, 0, 0, 0, 0,-30,-30},
|
||||||
|
{-50,-30,-30,-30,-30,-30,-30,-50}
|
||||||
|
};
|
||||||
|
|
||||||
|
public AutoPlayer() {
|
||||||
|
this(DEFAULT_DEPTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoPlayer(int searchDepth) {
|
||||||
|
this.searchDepth = searchDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes the best move for the current player based on the board state
|
||||||
|
* @param board The current board state
|
||||||
|
* @return The best move according to the minimax algorithm with alpha-beta pruning
|
||||||
|
*/
|
||||||
|
public Move computeBestMove(Board board) {
|
||||||
|
boolean isWhite = board.isTurnWhite();
|
||||||
|
ArrayList<Move> possibleMoves = generateAllMoves(board, isWhite);
|
||||||
|
|
||||||
|
if (possibleMoves.isEmpty()) {
|
||||||
|
return null; // No moves available, likely checkmate or stalemate
|
||||||
|
}
|
||||||
|
|
||||||
|
Move bestMove = null;
|
||||||
|
int bestScore = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (Move move : possibleMoves) {
|
||||||
|
Board tempBoard = new Board(board); // Create a copy of the board
|
||||||
|
tempBoard.playMove(move); // Apply the move to the copy
|
||||||
|
|
||||||
|
// Negamax with alpha-beta pruning
|
||||||
|
int score = -negamax(tempBoard, searchDepth - 1, Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, !isWhite);
|
||||||
|
|
||||||
|
if (score > bestScore) {
|
||||||
|
bestScore = score;
|
||||||
|
bestMove = move;
|
||||||
|
} else if (score == bestScore && random.nextBoolean()) {
|
||||||
|
// Add some randomness between equal-valued moves
|
||||||
|
bestMove = move;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestMove;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the negamax algorithm with alpha-beta pruning
|
||||||
|
*/
|
||||||
|
private int negamax(Board board, int depth, int alpha, int beta, boolean isWhite) {
|
||||||
|
if (depth == 0 || isGameOver(board)) {
|
||||||
|
return evaluateBoard(board, isWhite);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Move> possibleMoves = generateAllMoves(board, isWhite);
|
||||||
|
|
||||||
|
if (possibleMoves.isEmpty()) {
|
||||||
|
if (board.isInCheck(isWhite)) {
|
||||||
|
return -20000; // Checkmate (worst possible outcome)
|
||||||
|
} else {
|
||||||
|
return 0; // Stalemate (neutral)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int bestScore = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (Move move : possibleMoves) {
|
||||||
|
Board tempBoard = new Board(board);
|
||||||
|
tempBoard.playMove(move);
|
||||||
|
|
||||||
|
int score = -negamax(tempBoard, depth - 1, -beta, -alpha, !isWhite);
|
||||||
|
|
||||||
|
bestScore = Math.max(bestScore, score);
|
||||||
|
alpha = Math.max(alpha, bestScore);
|
||||||
|
|
||||||
|
if (alpha >= beta) {
|
||||||
|
break; // Alpha-beta pruning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestScore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the game is over (checkmate or stalemate)
|
||||||
|
*/
|
||||||
|
private boolean isGameOver(Board board) {
|
||||||
|
return board.isCheckmate() || board.isStalemate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates all possible moves for the given player
|
||||||
|
*/
|
||||||
|
private ArrayList<Move> generateAllMoves(Board board, boolean isWhite) {
|
||||||
|
ArrayList<Move> allMoves = new ArrayList<>();
|
||||||
|
ArrayList<Piece> pieces = board.getPieces();
|
||||||
|
|
||||||
|
for (Piece piece : pieces) {
|
||||||
|
if (piece.isWhite() == isWhite) {
|
||||||
|
ArrayList<int[]> validPositions = getValidMoves(board, piece);
|
||||||
|
|
||||||
|
for (int[] position : validPositions) {
|
||||||
|
int toX = position[0];
|
||||||
|
int toY = position[1];
|
||||||
|
|
||||||
|
boolean isEnPassant = false;
|
||||||
|
boolean isCastling = false;
|
||||||
|
|
||||||
|
// Check if move is castling
|
||||||
|
if (piece.getType() == PieceType.King && Math.abs(toX - piece.getX()) == 2) {
|
||||||
|
isCastling = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if move is en passant
|
||||||
|
if (piece.getType() == PieceType.Pawn && toX != piece.getX() && getPieceAt(board, toX, toY) == null) {
|
||||||
|
isEnPassant = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Piece capturedPiece = null;
|
||||||
|
if (isEnPassant) {
|
||||||
|
capturedPiece = getPieceAt(board, toX, piece.getY());
|
||||||
|
} else {
|
||||||
|
capturedPiece = getPieceAt(board, toX, toY);
|
||||||
|
}
|
||||||
|
|
||||||
|
Move move = new Move(piece.getX(), piece.getY(), toX, toY,
|
||||||
|
new Piece(piece.getX(), piece.getY(), piece.getType(), piece.isWhite()),
|
||||||
|
capturedPiece, isEnPassant, isCastling);
|
||||||
|
|
||||||
|
allMoves.add(move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return allMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluates the board state from the perspective of the current player
|
||||||
|
*/
|
||||||
|
private int evaluateBoard(Board board, boolean isWhite) {
|
||||||
|
int score = 0;
|
||||||
|
boolean isEndgame = isEndGame(board);
|
||||||
|
|
||||||
|
// Material evaluation
|
||||||
|
ArrayList<Piece> pieces = board.getPieces();
|
||||||
|
for (Piece piece : pieces) {
|
||||||
|
int pieceValue = getPieceValue(piece.getType());
|
||||||
|
int positionValue = getPositionValue(piece, isEndgame);
|
||||||
|
|
||||||
|
if (piece.isWhite() == isWhite) {
|
||||||
|
score += pieceValue + positionValue;
|
||||||
|
} else {
|
||||||
|
score -= pieceValue + positionValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bonus for checks and checkmate
|
||||||
|
if (board.isInCheck(!isWhite)) {
|
||||||
|
score += 50; // Bonus for putting opponent in check
|
||||||
|
}
|
||||||
|
|
||||||
|
if (board.isCheckmate()) {
|
||||||
|
if (board.isTurnWhite() != isWhite) {
|
||||||
|
score += 10000; // Bonus for checkmate
|
||||||
|
} else {
|
||||||
|
score -= 10000; // Penalty for being checkmated
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return score;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the game is in an endgame state
|
||||||
|
*/
|
||||||
|
private boolean isEndGame(Board board) {
|
||||||
|
int queens = 0;
|
||||||
|
int minors = 0;
|
||||||
|
|
||||||
|
for (Piece piece : board.getPieces()) {
|
||||||
|
if (piece.getType() == PieceType.Queen) {
|
||||||
|
queens++;
|
||||||
|
} else if (piece.getType() == PieceType.Rook ||
|
||||||
|
piece.getType() == PieceType.Bishop ||
|
||||||
|
piece.getType() == PieceType.Knight) {
|
||||||
|
minors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consider it endgame if no queens or few minor pieces
|
||||||
|
return queens == 0 || (queens == 1 && minors <= 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the basic value of a piece
|
||||||
|
*/
|
||||||
|
private int getPieceValue(PieceType type) {
|
||||||
|
switch (type) {
|
||||||
|
case Pawn: return PAWN_VALUE;
|
||||||
|
case Knight: return KNIGHT_VALUE;
|
||||||
|
case Bishop: return BISHOP_VALUE;
|
||||||
|
case Rook: return ROOK_VALUE;
|
||||||
|
case Queen: return QUEEN_VALUE;
|
||||||
|
case King: return KING_VALUE;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the positional value of a piece based on its location
|
||||||
|
*/
|
||||||
|
private int getPositionValue(Piece piece, boolean isEndgame) {
|
||||||
|
int x = piece.getX();
|
||||||
|
int y = piece.getY();
|
||||||
|
boolean isWhite = piece.isWhite();
|
||||||
|
|
||||||
|
// Flip coordinates for black pieces to use the same tables
|
||||||
|
if (!isWhite) {
|
||||||
|
y = 7 - y;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (piece.getType()) {
|
||||||
|
case Pawn: return PAWN_TABLE[y][x];
|
||||||
|
case Knight: return KNIGHT_TABLE[y][x];
|
||||||
|
case Bishop: return BISHOP_TABLE[y][x];
|
||||||
|
case Rook: return ROOK_TABLE[y][x];
|
||||||
|
case Queen: return QUEEN_TABLE[y][x];
|
||||||
|
case King:
|
||||||
|
if (isEndgame) {
|
||||||
|
return KING_TABLE_ENDGAME[y][x];
|
||||||
|
} else {
|
||||||
|
return KING_TABLE_MIDDLEGAME[y][x];
|
||||||
|
}
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets valid moves for a piece (had to reimplement as board methods are private)
|
||||||
|
*/
|
||||||
|
private ArrayList<int[]> getValidMoves(Board board, Piece piece) {
|
||||||
|
// This method would need to mimic board.getValidMoves logic
|
||||||
|
// Since we don't have direct access to Board's private methods,
|
||||||
|
// we'll simulate by analyzing the board setup
|
||||||
|
|
||||||
|
// For this implementation, I'll use a simplified approach
|
||||||
|
// that leverages board's existing functionality by simulating user touches
|
||||||
|
|
||||||
|
ArrayList<int[]> validMoves = new ArrayList<>();
|
||||||
|
int x = piece.getX();
|
||||||
|
int y = piece.getY();
|
||||||
|
|
||||||
|
// Make a copy of the board to avoid side effects
|
||||||
|
Board tempBoard = new Board(board);
|
||||||
|
|
||||||
|
// Select the piece
|
||||||
|
tempBoard.userTouch(x, y);
|
||||||
|
|
||||||
|
// Check which positions are highlighted (valid moves)
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
if (tempBoard.isHighlighted(i, j)) {
|
||||||
|
validMoves.add(new int[]{i, j});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return validMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to get a piece at a specific position
|
||||||
|
*/
|
||||||
|
private Piece getPieceAt(Board board, int x, int y) {
|
||||||
|
for (Piece piece : board.getPieces()) {
|
||||||
|
if (piece.getX() == x && piece.getY() == y) {
|
||||||
|
return piece;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -759,14 +759,15 @@ public class Board {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undoLastMove() {
|
public void undoLastMove() {
|
||||||
if (moveHistory.isEmpty()) {
|
if (moveHistory.isEmpty()) {
|
||||||
return; // Nothing to undo
|
return; // Rien à annuler
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the last move
|
// Récupérer le dernier mouvement
|
||||||
Move lastMove = moveHistory.get(moveHistory.size() - 1);
|
Move lastMove = moveHistory.get(moveHistory.size() - 1);
|
||||||
moveHistory.remove(moveHistory.size() - 1);
|
moveHistory.remove(moveHistory.size() - 1);
|
||||||
|
|
||||||
|
// Restaurer les pièces à leurs positions d'origine
|
||||||
int fromX = lastMove.getFromX();
|
int fromX = lastMove.getFromX();
|
||||||
int fromY = lastMove.getFromY();
|
int fromY = lastMove.getFromY();
|
||||||
int toX = lastMove.getToX();
|
int toX = lastMove.getToX();
|
||||||
|
|
@ -776,63 +777,49 @@ public class Board {
|
||||||
boolean isEnPassantCapture = lastMove.isEnPassantCapture();
|
boolean isEnPassantCapture = lastMove.isEnPassantCapture();
|
||||||
boolean isCastling = lastMove.isCastling();
|
boolean isCastling = lastMove.isCastling();
|
||||||
|
|
||||||
// Remove the moved piece from its current position
|
// Retirer la pièce déplacée de sa position actuelle
|
||||||
for (int i = 0; i < pieces.size(); i++) {
|
removePieceAt(toX, toY);
|
||||||
Piece piece = pieces.get(i);
|
|
||||||
if (piece.getX() == toX && piece.getY() == toY) {
|
|
||||||
pieces.remove(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the moving piece back to its original position
|
// Remettre la pièce déplacée à sa position d'origine
|
||||||
setPiece(movingPiece.isWhite(), movingPiece.getType(), fromX, fromY);
|
setPiece(movingPiece.isWhite(), movingPiece.getType(), fromX, fromY);
|
||||||
|
|
||||||
// Restore the captured piece if there was one
|
// Restaurer la pièce capturée s'il y en avait une
|
||||||
if (capturedPiece != null) {
|
if (capturedPiece != null) {
|
||||||
if (isEnPassantCapture) {
|
if (isEnPassantCapture) {
|
||||||
// For en passant, restore the pawn to its original position
|
// Pour l'en passant, restaurer le pion à sa position originale
|
||||||
setPiece(capturedPiece.isWhite(), capturedPiece.getType(), toX, fromY);
|
setPiece(capturedPiece.isWhite(), capturedPiece.getType(), toX, fromY);
|
||||||
} else {
|
} else {
|
||||||
// For regular capture, restore the piece at the capture location
|
// Pour une capture normale, restaurer la pièce à l'emplacement de capture
|
||||||
setPiece(capturedPiece.isWhite(), capturedPiece.getType(), toX, toY);
|
setPiece(capturedPiece.isWhite(), capturedPiece.getType(), toX, toY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle castling undo
|
// Gérer l'annulation du roque
|
||||||
if (isCastling) {
|
if (isCastling) {
|
||||||
// Determine rook's original and moved positions
|
// Déterminer les positions originales et déplacées de la tour
|
||||||
int rookOriginalX = (toX > fromX) ? 7 : 0;
|
int rookOriginalX = (toX > fromX) ? 7 : 0;
|
||||||
int rookMovedX = (toX > fromX) ? toX - 1 : toX + 1;
|
int rookMovedX = (toX > fromX) ? toX - 1 : toX + 1;
|
||||||
|
|
||||||
// Remove the rook from its current position
|
// Retirer la tour de sa position actuelle
|
||||||
for (int i = 0; i < pieces.size(); i++) {
|
removePieceAt(rookMovedX, toY);
|
||||||
Piece piece = pieces.get(i);
|
|
||||||
if (piece.getX() == rookMovedX && piece.getY() == toY &&
|
|
||||||
piece.getType() == PieceType.Rook && piece.isWhite() == movingPiece.isWhite()) {
|
|
||||||
pieces.remove(i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put the rook back to its original position
|
// Remettre la tour à sa position d'origine
|
||||||
setPiece(movingPiece.isWhite(), PieceType.Rook, rookOriginalX, toY);
|
setPiece(movingPiece.isWhite(), PieceType.Rook, rookOriginalX, toY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset special move flags based on move history
|
// Restaurer l'état précédent d'en passant et des drapeaux de roque
|
||||||
// We need to recompute these from scratch
|
// Ceci nécessite soit de stocker l'état précédent dans l'objet Move,
|
||||||
|
// soit de recalculer à partir de l'historique restant
|
||||||
resetMoveFlags();
|
resetMoveFlags();
|
||||||
|
|
||||||
// Decrement turn number and flip turn
|
// Décrémenter le numéro de tour et changer le joueur actif
|
||||||
turnNumber--;
|
turnNumber--;
|
||||||
isTurnWhite = !isTurnWhite;
|
isTurnWhite = !isTurnWhite;
|
||||||
|
|
||||||
// Reset selection and highlighting
|
// Réinitialiser la sélection et les cases surlignées
|
||||||
selectedX = -1;
|
selectedX = -1;
|
||||||
selectedY = -1;
|
selectedY = -1;
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
//TODO
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board(Board board) {
|
public Board(Board board) {
|
||||||
|
|
@ -1072,5 +1059,36 @@ public class Board {
|
||||||
return pieceToCapture != null && pieceToCapture.isWhite() != isWhite;
|
return pieceToCapture != null && pieceToCapture.isWhite() != isWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList<int[]> getValidMovesForPiece(int x, int y) {
|
||||||
|
Piece piece = getPieceAt(x, y);
|
||||||
|
if (piece != null && piece.isWhite() == isTurnWhite) {
|
||||||
|
return getValidMoves(piece);
|
||||||
|
}
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean makeMove(int fromX, int fromY, int toX, int toY) {
|
||||||
|
Piece piece = getPieceAt(fromX, fromY);
|
||||||
|
if (piece == null || piece.isWhite() != isTurnWhite) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if move is valid
|
||||||
|
boolean moveIsValid = false;
|
||||||
|
ArrayList<int[]> validMoves = getValidMoves(piece);
|
||||||
|
for (int[] pos : validMoves) {
|
||||||
|
if (pos[0] == toX && pos[1] == toY) {
|
||||||
|
moveIsValid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (moveIsValid) {
|
||||||
|
// Execute the move logic similar to userTouch
|
||||||
|
// ...
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue