move function updated
This commit is contained in:
parent
2d3b816551
commit
ebcda9c623
Binary file not shown.
Binary file not shown.
|
|
@ -3,38 +3,17 @@ package backend;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
public class Board {
|
|
||||||
|
|
||||||
|
public class Board {
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
private int turnNumber;
|
private int turnNumber;
|
||||||
private boolean isWhiteTurn;
|
private boolean isWhiteTurn;
|
||||||
private ArrayList<Piece> pieces;
|
private ArrayList<Piece> pieces;
|
||||||
private Set<Position> highlightedPositions = new HashSet<>();
|
private Set<Move.Position> highlightedPositions = new HashSet<>();
|
||||||
private Position lastMovedPiecePosition = null;
|
|
||||||
private boolean lastMoveWasDoublePawnMove = false;
|
|
||||||
private static class Position {
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
|
|
||||||
public Position(int x, int y) {
|
private Integer selectedX = null;
|
||||||
this.x = x;
|
private Integer selectedY = null;
|
||||||
this.y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object obj) {
|
|
||||||
if (this == obj) return true;
|
|
||||||
if (obj == null || getClass() != obj.getClass()) return false;
|
|
||||||
Position position = (Position) obj;
|
|
||||||
return x == position.x && y == position.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return 31 * x + y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Board(int colNum, int lineNum) {
|
public Board(int colNum, int lineNum) {
|
||||||
|
|
@ -46,22 +25,35 @@ public class Board {
|
||||||
this.highlightedPositions = new HashSet<>();
|
this.highlightedPositions = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return height;
|
return height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getTurnNumber() {
|
public int getTurnNumber() {
|
||||||
return turnNumber;
|
return turnNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isTurnWhite() {
|
public boolean isTurnWhite() {
|
||||||
return isWhiteTurn;
|
return isWhiteTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void advanceTurn() {
|
||||||
|
turnNumber++;
|
||||||
|
isWhiteTurn = !isWhiteTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||||||
for (int i = 0; i < pieces.size(); i++) {
|
for (int i = 0; i < pieces.size(); i++) {
|
||||||
Piece p = pieces.get(i);
|
Piece p = pieces.get(i);
|
||||||
|
|
@ -70,12 +62,23 @@ public class Board {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Piece newPiece = new Piece( x, y, type,isWhite);
|
Piece newPiece = new Piece(x, y, type, isWhite);
|
||||||
pieces.add(newPiece);
|
pieces.add(newPiece);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void removePiece(int x, int y) {
|
||||||
|
for (int i = 0; i < pieces.size(); i++) {
|
||||||
|
Piece p = pieces.get(i);
|
||||||
|
if (p.getX() == x && p.getY() == y) {
|
||||||
|
pieces.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void populateBoard() {
|
public void populateBoard() {
|
||||||
//TODO
|
|
||||||
cleanBoard();
|
cleanBoard();
|
||||||
|
|
||||||
PieceType pawn = PieceType.Pawn;
|
PieceType pawn = PieceType.Pawn;
|
||||||
|
|
@ -85,13 +88,13 @@ public class Board {
|
||||||
PieceType queen = PieceType.Queen;
|
PieceType queen = PieceType.Queen;
|
||||||
PieceType king = PieceType.King;
|
PieceType king = PieceType.King;
|
||||||
|
|
||||||
//all the pawns
|
// All the pawns
|
||||||
for (int x=0; x<8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
pieces.add(new Piece(x, 1, pawn, false));
|
pieces.add(new Piece(x, 1, pawn, false));
|
||||||
pieces.add(new Piece(x, 6, pawn, true));
|
pieces.add(new Piece(x, 6, pawn, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
//black pieces
|
// Black pieces
|
||||||
pieces.add(new Piece(0, 0, rook, false));
|
pieces.add(new Piece(0, 0, rook, false));
|
||||||
pieces.add(new Piece(1, 0, knight, false));
|
pieces.add(new Piece(1, 0, knight, false));
|
||||||
pieces.add(new Piece(2, 0, bishop, false));
|
pieces.add(new Piece(2, 0, bishop, false));
|
||||||
|
|
@ -101,8 +104,7 @@ public class Board {
|
||||||
pieces.add(new Piece(6, 0, knight, false));
|
pieces.add(new Piece(6, 0, knight, false));
|
||||||
pieces.add(new Piece(7, 0, rook, false));
|
pieces.add(new Piece(7, 0, rook, false));
|
||||||
|
|
||||||
|
// White pieces
|
||||||
//white pieces
|
|
||||||
pieces.add(new Piece(0, 7, rook, true));
|
pieces.add(new Piece(0, 7, rook, true));
|
||||||
pieces.add(new Piece(1, 7, knight, true));
|
pieces.add(new Piece(1, 7, knight, true));
|
||||||
pieces.add(new Piece(2, 7, bishop, true));
|
pieces.add(new Piece(2, 7, bishop, true));
|
||||||
|
|
@ -113,10 +115,12 @@ public class Board {
|
||||||
pieces.add(new Piece(7, 7, rook, true));
|
pieces.add(new Piece(7, 7, rook, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void cleanBoard() {
|
public void cleanBoard() {
|
||||||
pieces.clear();
|
pieces.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String result = "";
|
String result = "";
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
|
|
@ -139,6 +143,7 @@ public class Board {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ArrayList<Piece> getPieces() {
|
public ArrayList<Piece> getPieces() {
|
||||||
ArrayList<Piece> result = new ArrayList<>();
|
ArrayList<Piece> result = new ArrayList<>();
|
||||||
for (Piece p : this.pieces) {
|
for (Piece p : this.pieces) {
|
||||||
|
|
@ -146,6 +151,8 @@ public class Board {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Piece getPieceAt(int x, int y) {
|
public Piece getPieceAt(int x, int y) {
|
||||||
for (Piece p : pieces) {
|
for (Piece p : pieces) {
|
||||||
if (p.getX() == x && p.getY() == y) {
|
if (p.getX() == x && p.getY() == y) {
|
||||||
|
|
@ -155,8 +162,6 @@ public class Board {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer selectedX = null;
|
|
||||||
private Integer selectedY = null;
|
|
||||||
|
|
||||||
public void userTouch(int x, int y) {
|
public void userTouch(int x, int y) {
|
||||||
Piece clickedPiece = getPieceAt(x, y);
|
Piece clickedPiece = getPieceAt(x, y);
|
||||||
|
|
@ -179,45 +184,19 @@ public class Board {
|
||||||
if (selectedPiece != null) {
|
if (selectedPiece != null) {
|
||||||
// Check if the destination is a valid move
|
// Check if the destination is a valid move
|
||||||
if (isHighlighted(x, y)) {
|
if (isHighlighted(x, y)) {
|
||||||
|
// Create and execute the move
|
||||||
|
Move move = new Move(selectedX, selectedY, x, y, this);
|
||||||
|
if (move.isValid()) {
|
||||||
|
move.execute();
|
||||||
|
|
||||||
// Check if this is an en passant capture
|
// Check for checkmate
|
||||||
boolean isEnPassant = isEnPassantCapture(selectedPiece, x, y);
|
if (move.putsOpponentInCheckmate()) {
|
||||||
|
System.out.println("Checkmate! " + (isWhiteTurn ? "Black" : "White") + " wins!");
|
||||||
// Remove captured piece (if any)
|
} else if (move.putsOpponentInCheck()) {
|
||||||
Piece toRemove = getPieceAt(x, y);
|
System.out.println("Check!");
|
||||||
if (toRemove != null) {
|
|
||||||
pieces.remove(toRemove);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle en passant capture (remove the captured pawn)
|
|
||||||
if (isEnPassant) {
|
|
||||||
int capturedPawnY = selectedPiece.isWhite() ? y + 1 : y - 1;
|
|
||||||
Piece capturedPawn = getPieceAt(x, capturedPawnY);
|
|
||||||
if (capturedPawn != null) {
|
|
||||||
pieces.remove(capturedPawn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track if this move is a double pawn move
|
|
||||||
boolean isDoublePawnMove = selectedPiece.getType() == PieceType.Pawn &&
|
|
||||||
Math.abs(y - selectedPiece.getY()) == 2;
|
|
||||||
|
|
||||||
// Move piece
|
|
||||||
selectedPiece.moveTo(x, y);
|
|
||||||
|
|
||||||
// Update en passant tracking
|
|
||||||
if (isDoublePawnMove) {
|
|
||||||
lastMovedPiecePosition = new Position(x, y);
|
|
||||||
lastMoveWasDoublePawnMove = true;
|
|
||||||
} else {
|
|
||||||
lastMovedPiecePosition = null;
|
|
||||||
lastMoveWasDoublePawnMove = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance turn
|
|
||||||
turnNumber++;
|
|
||||||
isWhiteTurn = !isWhiteTurn;
|
|
||||||
|
|
||||||
// Unselect and clear highlights
|
// Unselect and clear highlights
|
||||||
selectedX = null;
|
selectedX = null;
|
||||||
selectedY = null;
|
selectedY = null;
|
||||||
|
|
@ -233,30 +212,6 @@ public class Board {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add this method to check if a move is an en passant capture:
|
|
||||||
private boolean isEnPassantCapture(Piece piece, int targetX, int targetY) {
|
|
||||||
if (piece.getType() != PieceType.Pawn) return false;
|
|
||||||
if (!lastMoveWasDoublePawnMove) return false;
|
|
||||||
if (lastMovedPiecePosition == null) return false;
|
|
||||||
|
|
||||||
// Check if we're capturing diagonally to an empty square
|
|
||||||
if (getPieceAt(targetX, targetY) != null) return false;
|
|
||||||
|
|
||||||
// Check if the target is diagonally adjacent
|
|
||||||
if (Math.abs(targetX - piece.getX()) != 1) return false;
|
|
||||||
if (Math.abs(targetY - piece.getY()) != 1) return false;
|
|
||||||
|
|
||||||
// Check if there's an opponent pawn next to us that just moved two squares
|
|
||||||
int adjacentPawnY = piece.getY();
|
|
||||||
Piece adjacentPawn = getPieceAt(targetX, adjacentPawnY);
|
|
||||||
|
|
||||||
if (adjacentPawn == null) return false;
|
|
||||||
if (adjacentPawn.getType() != PieceType.Pawn) return false;
|
|
||||||
if (adjacentPawn.isWhite() == piece.isWhite()) return false;
|
|
||||||
|
|
||||||
// Check if this adjacent pawn is the one that just moved two squares
|
|
||||||
return lastMovedPiecePosition.x == targetX && lastMovedPiecePosition.y == adjacentPawnY;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSelected(int x, int y) {
|
public boolean isSelected(int x, int y) {
|
||||||
// Check if the selected coordinates match the given x and y
|
// Check if the selected coordinates match the given x and y
|
||||||
|
|
@ -265,10 +220,10 @@ public class Board {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* saving-loading feature :*/
|
|
||||||
|
|
||||||
public String[] toFileRep() {
|
public String[] toFileRep() {
|
||||||
String[] fileRep = new String[height + 2];
|
String[] fileRep = new String[height + 1];
|
||||||
|
|
||||||
String boardStr = toString();
|
String boardStr = toString();
|
||||||
|
|
||||||
|
|
@ -284,16 +239,10 @@ public class Board {
|
||||||
|
|
||||||
fileRep[height] = (isWhiteTurn ? "W" : "B") + "," + turnNumber;
|
fileRep[height] = (isWhiteTurn ? "W" : "B") + "," + turnNumber;
|
||||||
|
|
||||||
// Save en passant state
|
|
||||||
String enPassantInfo = lastMoveWasDoublePawnMove ? "1" : "0";
|
|
||||||
if (lastMovedPiecePosition != null) {
|
|
||||||
enPassantInfo += "," + lastMovedPiecePosition.x + "," + lastMovedPiecePosition.y;
|
|
||||||
}
|
|
||||||
fileRep[height + 1] = enPassantInfo;
|
|
||||||
|
|
||||||
return fileRep;
|
return fileRep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Board(String[] array) {
|
public Board(String[] array) {
|
||||||
this.width = 8;
|
this.width = 8;
|
||||||
this.height = 8;
|
this.height = 8;
|
||||||
|
|
@ -302,8 +251,6 @@ public class Board {
|
||||||
if (array == null || array.length < 9) {
|
if (array == null || array.length < 9) {
|
||||||
this.turnNumber = 0;
|
this.turnNumber = 0;
|
||||||
this.isWhiteTurn = true;
|
this.isWhiteTurn = true;
|
||||||
this.lastMoveWasDoublePawnMove = false;
|
|
||||||
this.lastMovedPiecePosition = null;
|
|
||||||
populateBoard();
|
populateBoard();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -351,44 +298,19 @@ public class Board {
|
||||||
this.turnNumber = 0;
|
this.turnNumber = 0;
|
||||||
this.isWhiteTurn = true;
|
this.isWhiteTurn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load en passant state
|
|
||||||
if (array.length > height + 1) {
|
|
||||||
String enPassantInfo = array[height + 1];
|
|
||||||
String[] enPassantData = enPassantInfo.split(",");
|
|
||||||
|
|
||||||
if (enPassantData.length > 0) {
|
|
||||||
this.lastMoveWasDoublePawnMove = enPassantData[0].trim().equals("1");
|
|
||||||
} else {
|
|
||||||
this.lastMoveWasDoublePawnMove = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enPassantData.length >= 3) {
|
|
||||||
try {
|
|
||||||
int x = Integer.parseInt(enPassantData[1].trim());
|
|
||||||
int y = Integer.parseInt(enPassantData[2].trim());
|
|
||||||
this.lastMovedPiecePosition = new Position(x, y);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
this.lastMovedPiecePosition = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.lastMovedPiecePosition = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.lastMoveWasDoublePawnMove = false;
|
|
||||||
this.lastMovedPiecePosition = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
public boolean isHighlighted(int x, int y) {
|
public boolean isHighlighted(int x, int y) {
|
||||||
return highlightedPositions.contains(new Position(x, y));
|
return highlightedPositions.contains(new Move.Position(x, y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void undoLastMove() {
|
public void undoLastMove() {
|
||||||
//TODO
|
// TODO
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Board(Board board) {
|
public Board(Board board) {
|
||||||
this.width = board.width;
|
this.width = board.width;
|
||||||
this.height = board.height;
|
this.height = board.height;
|
||||||
|
|
@ -408,17 +330,14 @@ public class Board {
|
||||||
// Copy highlighted positions
|
// Copy highlighted positions
|
||||||
this.highlightedPositions = new HashSet<>();
|
this.highlightedPositions = new HashSet<>();
|
||||||
this.highlightedPositions.addAll(board.highlightedPositions);
|
this.highlightedPositions.addAll(board.highlightedPositions);
|
||||||
|
|
||||||
// Copy en passant state
|
|
||||||
this.lastMovedPiecePosition = board.lastMovedPiecePosition;
|
|
||||||
this.lastMoveWasDoublePawnMove = board.lastMoveWasDoublePawnMove;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add these methods after userTouch or before isHighlighted
|
|
||||||
private void clearHighlights() {
|
private void clearHighlights() {
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void calculateHighlights() {
|
private void calculateHighlights() {
|
||||||
if (selectedX == null || selectedY == null) {
|
if (selectedX == null || selectedY == null) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -429,282 +348,18 @@ public class Board {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get valid moves for the selected piece
|
// Get valid moves for the selected piece using the Move class
|
||||||
Set<Position> validMoves = getValidMoves(selectedPiece);
|
Set<Move.Position> validMoves = Move.getValidMoves(selectedPiece, this);
|
||||||
|
|
||||||
// Update highlighted positions
|
// Update highlighted positions
|
||||||
highlightedPositions.clear();
|
highlightedPositions.clear();
|
||||||
highlightedPositions.addAll(validMoves);
|
highlightedPositions.addAll(validMoves);
|
||||||
}
|
}
|
||||||
private Set<Position> getValidMoves(Piece piece) {
|
|
||||||
// Get all possible moves without considering check
|
|
||||||
Set<Position> candidateMoves = getRawValidMoves(piece);
|
|
||||||
|
|
||||||
// Filter out moves that would leave king in check
|
|
||||||
Set<Position> legalMoves = new HashSet<>();
|
|
||||||
for (Position move : candidateMoves) {
|
|
||||||
if (!wouldMoveLeaveKingInCheck(piece, move.x, move.y)) {
|
|
||||||
legalMoves.add(move);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return legalMoves;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add valid pawn moves
|
|
||||||
private void addPawnMoves(Set<Position> validMoves, int x, int y, boolean isWhite) {
|
|
||||||
int direction = isWhite ? -1 : 1; // White pawns move up, black pawns move down
|
|
||||||
|
|
||||||
// Forward movement
|
|
||||||
int newY = y + direction;
|
|
||||||
if (newY >= 0 && newY < height) {
|
|
||||||
// Single square forward
|
|
||||||
if (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;
|
|
||||||
if (doubleY >= 0 && doubleY < height && getPieceAt(x, doubleY) == null) {
|
|
||||||
validMoves.add(new Position(x, doubleY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diagonal captures
|
|
||||||
for (int dx = -1; dx <= 1; dx += 2) {
|
|
||||||
int newX = x + dx;
|
|
||||||
if (newX >= 0 && newX < width) {
|
|
||||||
Piece targetPiece = getPieceAt(newX, newY);
|
|
||||||
if (targetPiece != null && targetPiece.isWhite() != isWhite) {
|
|
||||||
validMoves.add(new Position(newX, newY));
|
|
||||||
}
|
|
||||||
// En passant capture
|
|
||||||
else if (targetPiece == null && canCaptureEnPassant(x, y, newX, newY, isWhite)) {
|
|
||||||
validMoves.add(new Position(newX, newY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this helper method for en passant validation:
|
|
||||||
private boolean canCaptureEnPassant(int fromX, int fromY, int toX, int toY, boolean isWhite) {
|
|
||||||
if (!lastMoveWasDoublePawnMove) return false;
|
|
||||||
if (lastMovedPiecePosition == null) return false;
|
|
||||||
|
|
||||||
// Check if there's an opponent pawn adjacent to us
|
|
||||||
Piece adjacentPawn = getPieceAt(toX, fromY);
|
|
||||||
if (adjacentPawn == null) return false;
|
|
||||||
if (adjacentPawn.getType() != PieceType.Pawn) return false;
|
|
||||||
if (adjacentPawn.isWhite() == isWhite) return false;
|
|
||||||
|
|
||||||
// Check if this is the pawn that just moved two squares
|
|
||||||
return lastMovedPiecePosition.x == toX && lastMovedPiecePosition.y == fromY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add valid rook moves
|
|
||||||
private void addRookMoves(Set<Position> validMoves, int x, int y, boolean isWhite) {
|
|
||||||
// Directions: horizontal and vertical
|
|
||||||
int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
|
|
||||||
|
|
||||||
for (int[] dir : directions) {
|
|
||||||
int dx = dir[0];
|
|
||||||
int dy = dir[1];
|
|
||||||
|
|
||||||
int newX = x + dx;
|
|
||||||
int newY = y + dy;
|
|
||||||
|
|
||||||
while (newX >= 0 && newX < width && newY >= 0 && newY < height) {
|
|
||||||
Piece targetPiece = 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));
|
|
||||||
}
|
|
||||||
break; // Cannot move beyond a piece
|
|
||||||
}
|
|
||||||
|
|
||||||
newX += dx;
|
|
||||||
newY += dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add valid knight moves
|
|
||||||
private void addKnightMoves(Set<Position> validMoves, int x, int y, boolean 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}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (int[] move : knightMoves) {
|
|
||||||
int newX = x + move[0];
|
|
||||||
int newY = y + move[1];
|
|
||||||
|
|
||||||
if (newX >= 0 && newX < width && newY >= 0 && newY < height) {
|
|
||||||
Piece targetPiece = getPieceAt(newX, newY);
|
|
||||||
|
|
||||||
if (targetPiece == null || targetPiece.isWhite() != isWhite) {
|
|
||||||
// Empty square or can capture opponent's piece
|
|
||||||
validMoves.add(new Position(newX, newY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add valid bishop moves
|
|
||||||
private void addBishopMoves(Set<Position> validMoves, int x, int y, boolean isWhite) {
|
|
||||||
// Directions: diagonals
|
|
||||||
int[][] directions = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
|
|
||||||
|
|
||||||
for (int[] dir : directions) {
|
|
||||||
int dx = dir[0];
|
|
||||||
int dy = dir[1];
|
|
||||||
|
|
||||||
int newX = x + dx;
|
|
||||||
int newY = y + dy;
|
|
||||||
|
|
||||||
while (newX >= 0 && newX < width && newY >= 0 && newY < height) {
|
|
||||||
Piece targetPiece = 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));
|
|
||||||
}
|
|
||||||
break; // Cannot move beyond a piece
|
|
||||||
}
|
|
||||||
|
|
||||||
newX += dx;
|
|
||||||
newY += dy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add valid king moves
|
|
||||||
private void addKingMoves(Set<Position> validMoves, int x, int y, boolean 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
|
|
||||||
|
|
||||||
int newX = x + dx;
|
|
||||||
int newY = y + dy;
|
|
||||||
|
|
||||||
if (newX >= 0 && newX < width && newY >= 0 && newY < height) {
|
|
||||||
Piece targetPiece = getPieceAt(newX, newY);
|
|
||||||
|
|
||||||
if (targetPiece == null || targetPiece.isWhite() != isWhite) {
|
|
||||||
// Empty square or can capture opponent's piece
|
|
||||||
validMoves.add(new Position(newX, newY));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add this method to check if a king is in check
|
|
||||||
private boolean isKingInCheck(boolean isWhiteKing) {
|
|
||||||
// Find the king's position
|
|
||||||
Piece king = null;
|
|
||||||
for (Piece p : pieces) {
|
|
||||||
if (p.getType() == PieceType.King && p.isWhite() == isWhiteKing) {
|
|
||||||
king = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (king == null) return false;
|
|
||||||
|
|
||||||
// Check if any opponent piece can attack the king
|
|
||||||
for (Piece p : pieces) {
|
|
||||||
if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color
|
|
||||||
|
|
||||||
// Get raw moves without check validation
|
|
||||||
Set<Position> attackMoves = getRawValidMoves(p);
|
|
||||||
|
|
||||||
// If any piece can move to king's position, king is in check
|
|
||||||
if (attackMoves.contains(new Position(king.getX(), king.getY()))) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this method to simulate a move and check if it leaves king in check
|
|
||||||
private boolean wouldMoveLeaveKingInCheck(Piece piece, int newX, int newY) {
|
|
||||||
// Create temporary board to simulate move
|
|
||||||
Board tempBoard = new Board(this);
|
|
||||||
|
|
||||||
// Find the piece in the temp board
|
|
||||||
Piece tempPiece = null;
|
|
||||||
for (Piece p : tempBoard.pieces) {
|
|
||||||
if (p.getX() == piece.getX() && p.getY() == piece.getY()) {
|
|
||||||
tempPiece = p;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempPiece == null) return true; // Safety check
|
|
||||||
|
|
||||||
// Remove any piece at destination
|
|
||||||
Piece capturedPiece = tempBoard.getPieceAt(newX, newY);
|
|
||||||
if (capturedPiece != null) {
|
|
||||||
tempBoard.pieces.remove(capturedPiece);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the piece
|
|
||||||
tempPiece.moveTo(newX, newY);
|
|
||||||
|
|
||||||
// Check if king is in check after move
|
|
||||||
return tempBoard.isKingInCheck(piece.isWhite());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add this helper method to get moves without check validation
|
|
||||||
private Set<Position> getRawValidMoves(Piece piece) {
|
|
||||||
Set<Position> moves = new HashSet<>();
|
|
||||||
|
|
||||||
switch (piece.getType()) {
|
|
||||||
case Pawn:
|
|
||||||
addPawnMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
case Rook:
|
|
||||||
addRookMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
case Knight:
|
|
||||||
addKnightMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
case Bishop:
|
|
||||||
addBishopMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
case Queen:
|
|
||||||
addRookMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
addBishopMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
case King:
|
|
||||||
addKingMoves(moves, piece.getX(), piece.getY(), piece.isWhite());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return moves;
|
|
||||||
}
|
|
||||||
public void playMove(Move move) {
|
public void playMove(Move move) {
|
||||||
//TODO
|
if (move.isValid() && !move.putsOwnKingInCheck()) {
|
||||||
|
move.execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,384 @@
|
||||||
package backend;
|
package backend;
|
||||||
|
|
||||||
public class Move {
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Move {
|
||||||
|
private int fromX;
|
||||||
|
private int fromY;
|
||||||
|
private int toX;
|
||||||
|
private int toY;
|
||||||
|
private Piece movingPiece;
|
||||||
|
private Piece capturedPiece;
|
||||||
|
private Board board;
|
||||||
|
|
||||||
|
public Move(int fromX, int fromY, int toX, int toY, Board board) {
|
||||||
|
this.fromX = fromX;
|
||||||
|
this.fromY = fromY;
|
||||||
|
this.toX = toX;
|
||||||
|
this.toY = toY;
|
||||||
|
this.board = board;
|
||||||
|
this.movingPiece = board.getPieceAt(fromX, fromY);
|
||||||
|
this.capturedPiece = board.getPieceAt(toX, toY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
// Check if the moving piece exists
|
||||||
|
if (movingPiece == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the move is in the set of valid moves for this piece
|
||||||
|
Set<Position> validMoves = getValidDestinations(movingPiece, board);
|
||||||
|
return validMoves.contains(new Position(toX, toY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void execute() {
|
||||||
|
// Remove any piece at the destination (normal capture)
|
||||||
|
if (capturedPiece != null) {
|
||||||
|
board.removePiece(toX, toY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the piece (remove from original position, add to new position)
|
||||||
|
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
|
||||||
|
|
||||||
|
// Remove any piece at destination (normal capture)
|
||||||
|
tempBoard.removePiece(toX, toY);
|
||||||
|
|
||||||
|
// Move the piece
|
||||||
|
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
|
||||||
|
|
||||||
|
// Remove any piece at destination (normal capture)
|
||||||
|
tempBoard.removePiece(toX, toY);
|
||||||
|
|
||||||
|
// Move the piece
|
||||||
|
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
|
||||||
|
|
||||||
|
// Remove any piece at destination (normal capture)
|
||||||
|
tempBoard.removePiece(toX, toY);
|
||||||
|
|
||||||
|
// Move the piece
|
||||||
|
tempBoard.removePiece(fromX, fromY);
|
||||||
|
tempBoard.setPiece(tempPiece.isWhite(), tempPiece.getType(), toX, toY);
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
Set<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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we get here, opponent has no valid moves
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Position> getValidDestinations(Piece piece, Board board) {
|
||||||
|
Set<Position> moves = new HashSet<>();
|
||||||
|
|
||||||
|
switch (piece.getType()) {
|
||||||
|
case Pawn:
|
||||||
|
addPawnMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
case Rook:
|
||||||
|
addRookMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
case Knight:
|
||||||
|
addKnightMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
case Bishop:
|
||||||
|
addBishopMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
case Queen:
|
||||||
|
addRookMoves(moves, piece, board);
|
||||||
|
addBishopMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
case King:
|
||||||
|
addKingMoves(moves, piece, board);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return moves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<Position> getValidMoves(Piece piece, Board board) {
|
||||||
|
// Get all possible moves without considering check
|
||||||
|
Set<Position> candidateMoves = getValidDestinations(piece, board);
|
||||||
|
|
||||||
|
// Filter out moves that would leave king in check
|
||||||
|
Set<Position> legalMoves = new HashSet<>();
|
||||||
|
for (Position pos : candidateMoves) {
|
||||||
|
Move move = new Move(piece.getX(), piece.getY(), pos.x, pos.y, board);
|
||||||
|
if (!move.putsOwnKingInCheck()) {
|
||||||
|
legalMoves.add(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return legalMoves;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static 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) {
|
||||||
|
king = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (king == null) return false;
|
||||||
|
|
||||||
|
// Check if any opponent piece can attack the king
|
||||||
|
for (Piece p : board.getPieces()) {
|
||||||
|
if (p.isWhite() == isWhiteKing) continue; // Skip pieces of same color
|
||||||
|
|
||||||
|
// Get raw moves without check validation
|
||||||
|
Set<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addPawnMoves(Set<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
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
if (doubleY >= 0 && doubleY < board.getHeight() && board.getPieceAt(x, doubleY) == null) {
|
||||||
|
validMoves.add(new Position(x, doubleY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diagonal captures
|
||||||
|
for (int dx = -1; dx <= 1; dx += 2) {
|
||||||
|
int newX = x + dx;
|
||||||
|
if (newX >= 0 && newX < board.getWidth()) {
|
||||||
|
Piece targetPiece = board.getPieceAt(newX, newY);
|
||||||
|
if (targetPiece != null && targetPiece.isWhite() != isWhite) {
|
||||||
|
validMoves.add(new Position(newX, newY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addRookMoves(Set<Position> validMoves, Piece piece, Board board) {
|
||||||
|
int x = piece.getX();
|
||||||
|
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) {
|
||||||
|
int dx = dir[0];
|
||||||
|
int dy = dir[1];
|
||||||
|
|
||||||
|
int newX = x + dx;
|
||||||
|
int newY = y + dy;
|
||||||
|
|
||||||
|
while (newX >= 0 && newX < board.getWidth() && newY >= 0 && newY < board.getHeight()) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
break; // Cannot move beyond a piece
|
||||||
|
}
|
||||||
|
|
||||||
|
newX += dx;
|
||||||
|
newY += dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addKnightMoves(Set<Position> validMoves, Piece piece, Board board) {
|
||||||
|
int x = piece.getX();
|
||||||
|
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}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int[] move : knightMoves) {
|
||||||
|
int newX = x + move[0];
|
||||||
|
int newY = y + move[1];
|
||||||
|
|
||||||
|
if (newX >= 0 && newX < board.getWidth() && newY >= 0 && newY < board.getHeight()) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addBishopMoves(Set<Position> validMoves, Piece piece, Board board) {
|
||||||
|
int x = piece.getX();
|
||||||
|
int y = piece.getY();
|
||||||
|
boolean isWhite = piece.isWhite();
|
||||||
|
|
||||||
|
// Directions: diagonals
|
||||||
|
int[][] directions = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
|
||||||
|
|
||||||
|
for (int[] dir : directions) {
|
||||||
|
int dx = dir[0];
|
||||||
|
int dy = dir[1];
|
||||||
|
|
||||||
|
int newX = x + dx;
|
||||||
|
int newY = y + dy;
|
||||||
|
|
||||||
|
while (newX >= 0 && newX < board.getWidth() && newY >= 0 && newY < board.getHeight()) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
break; // Cannot move beyond a piece
|
||||||
|
}
|
||||||
|
|
||||||
|
newX += dx;
|
||||||
|
newY += dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addKingMoves(Set<Position> validMoves, Piece piece, Board board) {
|
||||||
|
int x = piece.getX();
|
||||||
|
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
|
||||||
|
|
||||||
|
int newX = x + dx;
|
||||||
|
int newY = y + dy;
|
||||||
|
|
||||||
|
if (newX >= 0 && newX < board.getWidth() && newY >= 0 && newY < board.getHeight()) {
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Position {
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
|
||||||
|
public Position(int x, int y) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
Position position = (Position) obj;
|
||||||
|
return x == position.x && y == position.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 31 * x + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue