final push

This commit is contained in:
cleme 2025-05-23 23:56:06 +02:00
parent 02a7fe387b
commit 97deab60e7
5 changed files with 234 additions and 129 deletions

View File

@ -21,6 +21,7 @@ public class Board {
private Move lastMove = null;
private Enpassant enpassantHandler;
private CastlingHandler castlingHandler;
public Board(int colNum, int lineNum) {
this.width = colNum;
@ -33,6 +34,7 @@ public class Board {
this.sound = new Sound();
this.lastMove = null;
this.enpassantHandler = new Enpassant(this);
this.castlingHandler = new CastlingHandler(this);
}
public int getWidth() {
@ -186,17 +188,24 @@ public class Board {
if (isHighlighted(x, y)) {
saveCurrentState();
Move move = new Move(selectedX, selectedY, x, y, this);
if (move.isValid()) {
move.execute();
this.lastMove = move;
CastlingHandler.CastlingMove castlingMove = castlingHandler.getCastlingMove(selectedX, selectedY, x, y);
if (castlingMove != null && castlingHandler.isCastlingValid(castlingMove)) {
castlingHandler.executeCastling(castlingMove);
this.lastMove = new Move(selectedX, selectedY, x, y, this);
sound.playMoveSound();
if (move.putsOpponentInCheckmate()) {
System.out.println("Checkmate! " + (isWhiteTurn ? "Black" : "White") + " wins!");
} else if (move.putsOpponentInCheck()) {
System.out.println("Check!");
} else {
Move move = new Move(selectedX, selectedY, x, y, this);
if (move.isValid()) {
move.execute();
this.lastMove = move;
sound.playMoveSound();
if (move.putsOpponentInCheckmate()) {
System.out.println("Checkmate! " + (isWhiteTurn ? "Black" : "White") + " wins!");
} else if (move.putsOpponentInCheck()) {
System.out.println("Check!");
}
}
}
@ -252,6 +261,7 @@ public class Board {
this.sound = new Sound();
this.lastMove = null;
this.enpassantHandler = new Enpassant(this);
this.castlingHandler = new CastlingHandler(this);
for (int y = 0; y < height; y++) {
if (y >= array.length) {
@ -334,6 +344,7 @@ public class Board {
this.sound = new Sound();
this.enpassantHandler = new Enpassant(this);
this.castlingHandler = new CastlingHandler(this);
}
private void clearHighlights() {
@ -367,6 +378,13 @@ public class Board {
}
}
if (selectedPiece.getType() == PieceType.King) {
List<CastlingHandler.Position> castlingMoves = castlingHandler.getCastlingPositions(selectedPiece);
for (CastlingHandler.Position castlingPos : castlingMoves) {
convertedMoves.add(new Position(castlingPos.x, castlingPos.y));
}
}
highlightedPositions.clear();
highlightedPositions.addAll(convertedMoves);
}
@ -439,6 +457,14 @@ public class Board {
return enpassantHandler;
}
public CastlingHandler getCastlingHandler() {
return castlingHandler;
}
public List<Board> getBoardHistory() {
return new ArrayList<>(boardHistory);
}
public class Position {
public int x;
public int y;

View File

@ -11,9 +11,9 @@ public class CastlingHandler {
}
public class CastlingMove {
public final int kingFromX, kingFromY, kingToX, kingToY;
public final int rookFromX, rookFromY, rookToX, rookToY;
public final boolean isKingside;
public int kingFromX, kingFromY, kingToX, kingToY;
public int rookFromX, rookFromY, rookToX, rookToY;
public boolean isKingside;
public CastlingMove(int kingFromX, int kingFromY, int kingToX, int kingToY,
int rookFromX, int rookFromY, int rookToX, int rookToY,
@ -28,6 +28,12 @@ public class CastlingHandler {
this.rookToY = rookToY;
this.isKingside = isKingside;
}
public String toString() {
return (isKingside ? "Kingside" : "Queenside") + " Castling: King(" +
kingFromX + "," + kingFromY + ")->(" + kingToX + "," + kingToY +
"), Rook(" + rookFromX + "," + rookFromY + ")->(" + rookToX + "," + rookToY + ")";
}
}
public class Position {
@ -45,15 +51,19 @@ public class CastlingHandler {
Position position = (Position) obj;
return x == position.x && y == position.y;
}
public int hashCode() {
return 31 * x + y;
}
public String toString() {
return "(" + x + ", " + y + ")";
}
}
/**
* Checks if castling is possible and returns the castling move details
*/
public CastlingMove getCastlingMove(int fromX, int fromY, int toX, int toY) {
Piece piece = board.getPieceAt(fromX, fromY);
// Must be a king
if (piece == null || piece.getType() != PieceType.King) {
return null;
}
@ -61,12 +71,10 @@ public class CastlingHandler {
boolean isWhite = piece.isWhite();
int kingRow = isWhite ? 7 : 0;
// King must be on its starting position
if (fromY != kingRow || fromX != 4) {
return null;
}
// Check if this is a castling move (king moves 2 squares horizontally)
if (fromY != toY || Math.abs(toX - fromX) != 2) {
return null;
}
@ -80,21 +88,16 @@ public class CastlingHandler {
isKingside);
}
/**
* Validates if castling is legal
*/
public boolean isCastlingValid(CastlingMove castling) {
if (castling == null) return false;
Piece king = board.getPieceAt(castling.kingFromX, castling.kingFromY);
Piece rook = board.getPieceAt(castling.rookFromX, castling.rookFromY);
// Verify pieces exist and are correct type/color
if (king == null || king.getType() != PieceType.King) return false;
if (rook == null || rook.getType() != PieceType.Rook) return false;
if (king.isWhite() != rook.isWhite()) return false;
// Check if king or rook have moved (simplified - assumes starting positions)
boolean isWhite = king.isWhite();
int expectedKingRow = isWhite ? 7 : 0;
if (castling.kingFromY != expectedKingRow || castling.kingFromX != 4) return false;
@ -102,7 +105,62 @@ public class CastlingHandler {
if (castling.isKingside && castling.rookFromX != 7) return false;
if (!castling.isKingside && castling.rookFromX != 0) return false;
// Check path is clear between king and rook
if (hasKingOrRookMoved(isWhite, castling.isKingside)) {
return false;
}
if (!isPathClear(castling)) {
return false;
}
if (isKingInCheck(isWhite)) {
return false;
}
return !wouldKingPassThroughCheck(castling, isWhite);
}
private boolean hasKingOrRookMoved(boolean isWhite, boolean isKingside) {
List<Board> history = board.getBoardHistory();
if (history.isEmpty()) return false;
int kingRow = isWhite ? 7 : 0;
int rookX = isKingside ? 7 : 0;
for (Board previousBoard : history) {
Piece kingInHistory = previousBoard.getPieceAt(4, kingRow);
Piece rookInHistory = previousBoard.getPieceAt(rookX, kingRow);
if (kingInHistory == null || kingInHistory.getType() != PieceType.King ||
kingInHistory.isWhite() != isWhite) {
return true;
}
if (rookInHistory == null || rookInHistory.getType() != PieceType.Rook ||
rookInHistory.isWhite() != isWhite) {
return true;
}
}
Move lastMove = board.getLastMove();
if (lastMove != null) {
Piece lastMovedPiece = board.getPieceAt(lastMove.getToX(), lastMove.getToY());
if (lastMovedPiece != null) {
if (lastMovedPiece.getType() == PieceType.King && lastMovedPiece.isWhite() == isWhite) {
return true;
}
if (lastMovedPiece.getType() == PieceType.Rook && lastMovedPiece.isWhite() == isWhite) {
if ((isKingside && lastMove.getFromX() == 7) || (!isKingside && lastMove.getFromX() == 0)) {
return true;
}
}
}
}
return false;
}
private boolean isPathClear(CastlingMove castling) {
int startX = Math.min(castling.kingFromX, castling.rookFromX) + 1;
int endX = Math.max(castling.kingFromX, castling.rookFromX) - 1;
@ -111,49 +169,42 @@ public class CastlingHandler {
return false;
}
}
return true;
}
private boolean wouldKingPassThroughCheck(CastlingMove castling, boolean isWhite) {
int step = castling.isKingside ? 1 : -1;
// Check that king is not in check
if (isKingInCheck(isWhite)) {
return false;
}
// Check that king doesn't pass through check
for (int x = castling.kingFromX; x != castling.kingToX + (castling.isKingside ? 1 : -1);
x += castling.isKingside ? 1 : -1) {
for (int x = castling.kingFromX; x != castling.kingToX + step; x += step) {
if (x == castling.kingFromX) continue;
// Create temporary board with king at this position
Board tempBoard = new Board(board);
tempBoard.removePiece(castling.kingFromX, castling.kingFromY);
tempBoard.setPiece(isWhite, PieceType.King, x, castling.kingFromY);
CastlingHandler tempHandler = new CastlingHandler(tempBoard);
if (tempHandler.isKingInCheck(isWhite)) {
return false;
return true;
}
}
return true;
return false;
}
/**
* Executes the castling move on the board
*/
public void executeCastling(CastlingMove castling) {
if (!isCastlingValid(castling)) {
throw new IllegalArgumentException("Invalid castling move");
}
Piece king = board.getPieceAt(castling.kingFromX, castling.kingFromY);
Piece rook = board.getPieceAt(castling.rookFromX, castling.rookFromY);
// Move the king
board.removePiece(castling.kingFromX, castling.kingFromY);
board.setPiece(king.isWhite(), king.getType(), castling.kingToX, castling.kingToY);
// Move the rook
board.removePiece(castling.rookFromX, castling.rookFromY);
board.setPiece(king.isWhite(), king.getType(), castling.kingToX, castling.kingToY);
board.setPiece(rook.isWhite(), rook.getType(), castling.rookToX, castling.rookToY);
}
/**
* Gets all possible castling moves for a king
*/
public List<Position> getCastlingPositions(Piece king) {
List<Position> castlingMoves = new ArrayList<>();
@ -164,18 +215,15 @@ public class CastlingHandler {
boolean isWhite = king.isWhite();
int kingRow = isWhite ? 7 : 0;
// King must be on starting position
if (king.getX() != 4 || king.getY() != kingRow) {
return castlingMoves;
}
// Check kingside castling
CastlingMove kingsideCastling = getCastlingMove(4, kingRow, 6, kingRow);
if (isCastlingValid(kingsideCastling)) {
castlingMoves.add(new Position(6, kingRow));
}
// Check queenside castling
CastlingMove queensideCastling = getCastlingMove(4, kingRow, 2, kingRow);
if (isCastlingValid(queensideCastling)) {
castlingMoves.add(new Position(2, kingRow));
@ -184,8 +232,41 @@ public class CastlingHandler {
return castlingMoves;
}
public List<Position> getAllCastlingMoves(boolean isWhite) {
List<Position> castlingMoves = new ArrayList<>();
int kingRow = isWhite ? 7 : 0;
Piece king = board.getPieceAt(4, kingRow);
if (king != null && king.getType() == PieceType.King && king.isWhite() == isWhite) {
castlingMoves.addAll(getCastlingPositions(king));
}
return castlingMoves;
}
public boolean isCastlingMove(int fromX, int fromY, int toX, int toY) {
return getCastlingMove(fromX, fromY, toX, toY) != null;
}
public boolean wouldCastlingPutKingInCheck(CastlingMove castling) {
if (castling == null) return true;
Board tempBoard = new Board(board);
CastlingHandler tempHandler = new CastlingHandler(tempBoard);
try {
Piece originalKing = board.getPieceAt(castling.kingFromX, castling.kingFromY);
if (originalKing == null) return true;
tempHandler.executeCastling(castling);
return tempHandler.isKingInCheck(originalKing.isWhite());
} catch (Exception e) {
return true;
}
}
public boolean isKingInCheck(boolean isWhiteKing) {
// Find the king's position
Piece king = null;
for (Piece p : board.getPieces()) {
if (p.getType() == PieceType.King && p.isWhite() == isWhiteKing) {
@ -200,14 +281,11 @@ public class CastlingHandler {
}
private boolean checkIfKingUnderAttack(boolean isWhiteKing, Piece king) {
// Check if any opponent piece can attack the king
for (Piece p : board.getPieces()) {
if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color
if (p.isWhite() == isWhiteKing) continue;
// Get raw moves without check validation
List<Position> attackMoves = getValidDestinations(p);
// If any piece can move to king's position, king is in check
for (Position pos : attackMoves) {
if (pos.x == king.getX() && pos.y == king.getY()) {
return true;
@ -223,7 +301,7 @@ public class CastlingHandler {
switch (piece.getType()) {
case Pawn:
addPawnMoves(moves, piece);
addPawnAttackMoves(moves, piece);
break;
case Rook:
addRookMoves(moves, piece);
@ -246,15 +324,14 @@ public class CastlingHandler {
return moves;
}
private void addPawnMoves(List<Position> validMoves, Piece piece) {
private void addPawnAttackMoves(List<Position> validMoves, Piece piece) {
int x = piece.getX();
int y = piece.getY();
boolean isWhite = piece.isWhite();
int direction = isWhite ? -1 : 1;
// Diagonal captures only (for attack patterns)
int newY = y + direction;
if (newY >= 0 && newY < board.getHeight()) {
for (int dx = -1; dx <= 1; dx += 2) {
int newX = x + dx;
@ -283,7 +360,7 @@ public class CastlingHandler {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece != null) {
break; // Cannot move beyond a piece
break;
}
newX += dx;
@ -329,7 +406,7 @@ public class CastlingHandler {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece != null) {
break; // Cannot move beyond a piece
break;
}
newX += dx;

View File

@ -12,7 +12,9 @@ public class Move {
private Piece capturedPiece;
private Board board;
private boolean isEnPassant = false;
private boolean isCastling = false;
private Piece enPassantCapturedPiece = null;
private CastlingHandler.CastlingMove castlingMove = null;
public Move(int fromX, int fromY, int toX, int toY, Board board) {
this.fromX = fromX;
@ -23,17 +25,15 @@ public class Move {
this.movingPiece = board.getPieceAt(fromX, fromY);
this.capturedPiece = board.getPieceAt(toX, toY);
// Check if this is an en passant move
checkEnPassant();
checkCastling();
}
private void checkEnPassant() {
if (movingPiece != null && movingPiece.getType() == PieceType.Pawn) {
// Utiliser la classe Enpassant pour vérifier
Enpassant enpassantHandler = board.getEnpassantHandler();
if (enpassantHandler.isEnPassantValid(fromX, fromY, toX, toY)) {
isEnPassant = true;
// Obtenir la position du pion capturé
Enpassant.Position capturedPos = enpassantHandler.getCapturedPawnPosition(toX, toY);
if (capturedPos != null) {
enPassantCapturedPiece = board.getPieceAt(capturedPos.x, capturedPos.y);
@ -41,103 +41,119 @@ public class Move {
}
}
}
private void checkCastling() {
if (movingPiece != null && movingPiece.getType() == PieceType.King) {
CastlingHandler castlingHandler = board.getCastlingHandler();
castlingMove = castlingHandler.getCastlingMove(fromX, fromY, toX, toY);
if (castlingMove != null && castlingHandler.isCastlingValid(castlingMove)) {
isCastling = true;
}
}
}
public boolean isValid() {
// Check if the moving piece exists
if (movingPiece == null) {
return false;
}
// Check if the move is in the list of valid moves for this piece
if (isCastling) {
CastlingHandler castlingHandler = board.getCastlingHandler();
return castlingHandler.isCastlingValid(castlingMove);
}
List<Position> validMoves = getValidDestinations(movingPiece, board);
return validMoves.contains(new Position(toX, toY));
}
public void execute() {
if (isEnPassant) {
// Utiliser la classe Enpassant pour l'exécution
if (isCastling) {
CastlingHandler castlingHandler = board.getCastlingHandler();
castlingHandler.executeCastling(castlingMove);
} else if (isEnPassant) {
Enpassant enpassantHandler = board.getEnpassantHandler();
enpassantHandler.executeEnPassant(fromX, fromY, toX, toY);
} else {
// Normal move or capture
if (capturedPiece != null) {
board.removePiece(toX, toY);
}
// Move the piece
board.removePiece(fromX, fromY);
board.setPiece(movingPiece.isWhite(), movingPiece.getType(), toX, toY);
}
// Advance turn
board.advanceTurn();
}
public boolean putsOwnKingInCheck() {
// Create a temporary board to simulate the move
Board tempBoard = new Board(board);
// Find the piece in the temp board
Piece tempPiece = tempBoard.getPieceAt(fromX, fromY);
if (tempPiece == null) return true; // Safety check
if (tempPiece == null) return true;
if (isEnPassant) {
// Simulate en passant on temp board
if (isCastling) {
CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler();
CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY);
if (tempCastlingMove != null) {
return tempCastlingHandler.wouldCastlingPutKingInCheck(tempCastlingMove);
}
return true;
} else if (isEnPassant) {
Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler();
tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY);
} else {
// Normal move simulation
tempBoard.removePiece(toX, toY);
tempBoard.removePiece(fromX, fromY);
tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY);
}
// Check if king is in check after move
return isKingInCheck(tempBoard, tempPiece.isWhite());
}
public boolean putsOpponentInCheck() {
// Create a temporary board to simulate the move
Board tempBoard = new Board(board);
// Find the piece in the temp board
Piece tempPiece = tempBoard.getPieceAt(fromX, fromY);
if (tempPiece == null) return false; // Safety check
if (tempPiece == null) return false;
if (isEnPassant) {
// Simulate en passant on temp board
if (isCastling) {
CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler();
CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY);
if (tempCastlingMove != null) {
tempCastlingHandler.executeCastling(tempCastlingMove);
}
} else if (isEnPassant) {
Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler();
tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY);
} else {
// Normal move simulation
tempBoard.removePiece(toX, toY);
tempBoard.removePiece(fromX, fromY);
tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY);
}
// Check if opponent's king is in check after move
return isKingInCheck(tempBoard, !tempPiece.isWhite());
}
public boolean putsOpponentInCheckmate() {
// First, check if the move puts the opponent in check
if (!putsOpponentInCheck()) {
return false;
}
// Create a temporary board to simulate the move
Board tempBoard = new Board(board);
// Find the piece in the temp board
Piece tempPiece = tempBoard.getPieceAt(fromX, fromY);
if (tempPiece == null) return false; // Safety check
if (tempPiece == null) return false;
if (isEnPassant) {
// Simulate en passant on temp board
if (isCastling) {
CastlingHandler tempCastlingHandler = tempBoard.getCastlingHandler();
CastlingHandler.CastlingMove tempCastlingMove = tempCastlingHandler.getCastlingMove(fromX, fromY, toX, toY);
if (tempCastlingMove != null) {
tempCastlingHandler.executeCastling(tempCastlingMove);
}
} else if (isEnPassant) {
Enpassant tempEnpassantHandler = tempBoard.getEnpassantHandler();
tempEnpassantHandler.executeEnPassant(fromX, fromY, toX, toY);
} else {
// Normal move simulation
tempBoard.removePiece(toX, toY);
tempBoard.removePiece(fromX, fromY);
tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY);
@ -145,23 +161,19 @@ public class Move {
boolean opponentColor = !tempPiece.isWhite();
// Try all possible moves for all opponent pieces
for (Piece p : tempBoard.getPieces()) {
if (p.isWhite() != opponentColor) continue; // Skip pieces of the wrong color
if (p.isWhite() != opponentColor) continue;
List<Position> possibleMoves = getValidDestinations(p, tempBoard);
for (Position pos : possibleMoves) {
// Create a temporary move
Move testMove = new Move(p.getX(), p.getY(), pos.x, pos.y, tempBoard);
// Check if this move would get the opponent out of check
if (!testMove.putsOwnKingInCheck()) {
return false; // Opponent has at least one valid move
return false;
}
}
}
// If we get here, opponent has no valid moves
return true;
}
@ -187,6 +199,7 @@ public class Move {
return moves;
case King:
addKingMoves(moves, piece, board);
addCastlingMoves(moves, piece, board);
return moves;
}
@ -194,10 +207,8 @@ public class Move {
}
public List<Position> getValidMoves(Piece piece, Board board) {
// Get all possible moves without considering check
List<Position> candidateMoves = getValidDestinations(piece, board);
// Filter out moves that would leave king in check
List<Position> legalMoves = new ArrayList<>();
for (Position pos : candidateMoves) {
Move move = new Move(piece.getX(), piece.getY(), pos.x, pos.y, board);
@ -210,7 +221,6 @@ public class Move {
}
public boolean isKingInCheck(Board board, boolean isWhiteKing) {
// Find the king's position
Piece king = null;
for (Piece p : board.getPieces()) {
if (p.getType() == PieceType.King && p.isWhite() == isWhiteKing) {
@ -223,14 +233,11 @@ public class Move {
}
private boolean checkIfKingUnderAttack(Board board, boolean isWhiteKing, Piece king) {
// Check if any opponent piece can attack the king
for (Piece p : board.getPieces()) {
if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color
if (p.isWhite() == isWhiteKing) continue;
// Get raw moves without check validation
List<Position> attackMoves = getValidDestinations(p, board);
// If any piece can move to king's position, king is in check
if (attackMoves.contains(new Position(king.getX(), king.getY()))) {
return true;
}
@ -239,21 +246,31 @@ public class Move {
return false;
}
private void addCastlingMoves(List<Position> validMoves, Piece piece, Board board) {
if (piece.getType() != PieceType.King) {
return;
}
CastlingHandler castlingHandler = board.getCastlingHandler();
List<CastlingHandler.Position> castlingPositions = castlingHandler.getCastlingPositions(piece);
for (CastlingHandler.Position castlingPos : castlingPositions) {
validMoves.add(new Position(castlingPos.x, castlingPos.y));
}
}
private void addPawnMoves(List<Position> validMoves, Piece piece, Board board) {
int x = piece.getX();
int y = piece.getY();
boolean isWhite = piece.isWhite();
int direction = isWhite ? -1 : 1; // White pawns move up, black pawns move down
int direction = isWhite ? -1 : 1;
// Forward movement
int newY = y + direction;
if (newY >= 0 && newY < board.getHeight()) {
// Single square forward
if (board.getPieceAt(x, newY) == null) {
validMoves.add(new Position(x, newY));
// Initial double move
int startRow = isWhite ? 6 : 1;
if (y == startRow) {
int doubleY = newY + direction;
@ -263,7 +280,6 @@ public class Move {
}
}
// Diagonal captures (normal)
for (int dx = -1; dx <= 1; dx += 2) {
int newX = x + dx;
if (newX >= 0 && newX < board.getWidth()) {
@ -275,7 +291,6 @@ public class Move {
}
}
// EN PASSANT: Ajouter les mouvements en passant en utilisant la classe Enpassant
Enpassant enpassantHandler = board.getEnpassantHandler();
List<Enpassant.Position> enPassantMoves = enpassantHandler.getPossibleEnPassantMoves(x, y);
for (Enpassant.Position enPos : enPassantMoves) {
@ -288,7 +303,6 @@ public class Move {
int y = piece.getY();
boolean isWhite = piece.isWhite();
// Directions: horizontal and vertical
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
for (int[] dir : directions) {
@ -303,15 +317,12 @@ public class Move {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece == null) {
// Empty square
validMoves.add(new Position(newX, newY));
} else {
// Occupied square
if (targetPiece.isWhite() != isWhite) {
// Capture opponent's piece
validMoves.add(new Position(newX, newY));
}
continueInDirection = false; // Cannot move beyond a piece
continueInDirection = false;
}
if (continueInDirection) {
@ -327,7 +338,6 @@ public class Move {
int y = piece.getY();
boolean isWhite = piece.isWhite();
// All possible knight moves: L-shapes
int[][] knightMoves = {
{-2, -1}, {-2, 1}, {-1, -2}, {-1, 2},
{1, -2}, {1, 2}, {2, -1}, {2, 1}
@ -341,7 +351,6 @@ public class Move {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece == null || targetPiece.isWhite() != isWhite) {
// Empty square or can capture opponent's piece
validMoves.add(new Position(newX, newY));
}
}
@ -353,7 +362,6 @@ public class Move {
int y = piece.getY();
boolean isWhite = piece.isWhite();
// Directions: diagonals
int[][] directions = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
for (int[] dir : directions) {
@ -368,15 +376,12 @@ public class Move {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece == null) {
// Empty square
validMoves.add(new Position(newX, newY));
} else {
// Occupied square
if (targetPiece.isWhite() != isWhite) {
// Capture opponent's piece
validMoves.add(new Position(newX, newY));
}
continueInDirection = false; // Cannot move beyond a piece
continueInDirection = false;
}
if (continueInDirection) {
@ -392,10 +397,9 @@ public class Move {
int y = piece.getY();
boolean isWhite = piece.isWhite();
// All adjacent squares
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx == 0 && dy == 0) continue; // Skip the current position
if (dx == 0 && dy == 0) continue;
int newX = x + dx;
int newY = y + dy;
@ -404,7 +408,6 @@ public class Move {
Piece targetPiece = board.getPieceAt(newX, newY);
if (targetPiece == null || targetPiece.isWhite() != isWhite) {
// Empty square or can capture opponent's piece
validMoves.add(new Position(newX, newY));
}
}
@ -421,7 +424,6 @@ public class Move {
this.y = y;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
@ -429,19 +431,19 @@ public class Move {
return x == position.x && y == position.y;
}
@Override
public int hashCode() {
return 31 * x + y;
}
}
// Getters
public int getFromX() { return fromX; }
public int getFromY() { return fromY; }
public int getToX() { return toX; }
public int getToY() { return toY; }
public boolean isEnPassant() { return isEnPassant; }
public boolean isCastling() { return isCastling; }
public Piece getMovingPiece() { return movingPiece; }
public Piece getCapturedPiece() { return capturedPiece; }
public Piece getEnPassantCapturedPiece() { return enPassantCapturedPiece; }
public CastlingHandler.CastlingMove getCastlingMove() { return castlingMove; }
}