Castling Done
This commit is contained in:
parent
b20a1a1c9c
commit
2bf326eae2
|
|
@ -0,0 +1,9 @@
|
||||||
|
BR,BN,BB,BQ,BK,BB,BN,BR
|
||||||
|
BP,BP,BP,BP,BP,..,BP,BP
|
||||||
|
..,..,..,..,..,..,..,..
|
||||||
|
..,..,..,..,..,BP,..,..
|
||||||
|
..,..,..,..,WP,..,..,..
|
||||||
|
..,..,..,..,..,..,..,..
|
||||||
|
WP,WP,WP,WP,..,WP,WP,WP
|
||||||
|
WR,WN,WB,WQ,WK,WB,WN,WR
|
||||||
|
W
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
package backend;
|
package backend;
|
||||||
|
//HI
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
|
|
@ -16,6 +16,14 @@ private int selectedX, selectedY; // if so, which square is “in hand”?
|
||||||
private int turnNumber = 0; // how many half-moves have been played?
|
private int turnNumber = 0; // how many half-moves have been played?
|
||||||
private boolean turnWhite = true; // true = White to play, false = Black
|
private boolean turnWhite = true; // true = White to play, false = Black
|
||||||
// ─────────────────────────────────────────────────────────────
|
// ─────────────────────────────────────────────────────────────
|
||||||
|
private boolean whiteKingMoved = false;
|
||||||
|
private boolean blackKingMoved = false;
|
||||||
|
private boolean whiteKingsideRookMoved = false;
|
||||||
|
private boolean whiteQueensideRookMoved = false;
|
||||||
|
private boolean blackKingsideRookMoved = false;
|
||||||
|
private boolean blackQueensideRookMoved = false;
|
||||||
|
|
||||||
|
|
||||||
public String[] toFileRep() {
|
public String[] toFileRep() {
|
||||||
String[] lines = new String[height + 1];
|
String[] lines = new String[height + 1];
|
||||||
|
|
||||||
|
|
@ -173,7 +181,6 @@ public String toString() {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
public void userTouch(int x, int y) {
|
public void userTouch(int x, int y) {
|
||||||
// 1) Find if you clicked on a piece at (x,y)
|
|
||||||
Piece clicked = null;
|
Piece clicked = null;
|
||||||
for (Piece p : Pieces) {
|
for (Piece p : Pieces) {
|
||||||
if (p.getX() == x && p.getY() == y) {
|
if (p.getX() == x && p.getY() == y) {
|
||||||
|
|
@ -182,7 +189,6 @@ public void userTouch(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2) If nothing is selected, select a piece of the correct color
|
|
||||||
if (!hasSelection) {
|
if (!hasSelection) {
|
||||||
if (clicked != null && clicked.isWhite() == turnWhite) {
|
if (clicked != null && clicked.isWhite() == turnWhite) {
|
||||||
hasSelection = true;
|
hasSelection = true;
|
||||||
|
|
@ -192,20 +198,13 @@ public void userTouch(int x, int y) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3) If you click the same square again → deselect
|
|
||||||
if (x == selectedX && y == selectedY) {
|
if (x == selectedX && y == selectedY) {
|
||||||
hasSelection = false;
|
hasSelection = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4) If the square is not highlighted (illegal), ignore it
|
if (!isHighlighted(x, y)) return;
|
||||||
if (!isHighlighted(x, y)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5) Do the move
|
|
||||||
|
|
||||||
// Capture (including en passant)
|
|
||||||
Piece captured = null;
|
Piece captured = null;
|
||||||
for (Piece p : Pieces) {
|
for (Piece p : Pieces) {
|
||||||
if (p.getX() == x && p.getY() == y) {
|
if (p.getX() == x && p.getY() == y) {
|
||||||
|
|
@ -214,7 +213,6 @@ public void userTouch(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the piece to move (only declare once!)
|
|
||||||
Piece toMove = null;
|
Piece toMove = null;
|
||||||
for (Piece p : Pieces) {
|
for (Piece p : Pieces) {
|
||||||
if (p.getX() == selectedX && p.getY() == selectedY) {
|
if (p.getX() == selectedX && p.getY() == selectedY) {
|
||||||
|
|
@ -223,54 +221,93 @@ public void userTouch(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// En passant condition
|
|
||||||
if (captured == null && toMove != null && toMove.getType() == PieceType.Pawn) {
|
if (captured == null && toMove != null && toMove.getType() == PieceType.Pawn) {
|
||||||
int dir = toMove.isWhite() ? -1 : 1;
|
int dir = toMove.isWhite() ? -1 : 1;
|
||||||
if (lastDoubleStepPawn != null &&
|
if (lastDoubleStepPawn != null &&
|
||||||
lastDoubleStepPawn.getX() == x &&
|
lastDoubleStepPawn.getX() == x &&
|
||||||
lastDoubleStepPawn.getY() == y - dir &&
|
lastDoubleStepPawn.getY() == y - dir &&
|
||||||
lastDoubleStepPawn.isWhite() != toMove.isWhite()) {
|
lastDoubleStepPawn.isWhite() != toMove.isWhite()) {
|
||||||
|
Pieces.removeIf(p -> p.getX() == lastDoubleStepPawn.getX() && p.getY() == lastDoubleStepPawn.getY());
|
||||||
Pieces.removeIf(p -> p.getX() == lastDoubleStepPawn.getX() && p.getY() == lastDoubleStepPawn.getY());
|
captured = lastDoubleStepPawn;
|
||||||
captured = lastDoubleStepPawn;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normal capture
|
if (captured != null) Pieces.remove(captured);
|
||||||
if (captured != null) {
|
|
||||||
Pieces.remove(captured);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move the selected piece
|
|
||||||
if (toMove != null) {
|
if (toMove != null) {
|
||||||
Pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
|
Pieces.removeIf(p -> p.getX() == selectedX && p.getY() == selectedY);
|
||||||
|
|
||||||
// Check for promotion
|
|
||||||
boolean isWhite = toMove.isWhite();
|
boolean isWhite = toMove.isWhite();
|
||||||
PieceType type = toMove.getType();
|
PieceType type = toMove.getType();
|
||||||
|
|
||||||
|
Piece rookPiece = null;
|
||||||
|
int rookFromX = -1, rookFromY = -1, rookToX = -1, rookToY = -1;
|
||||||
|
|
||||||
|
if (type == PieceType.King) {
|
||||||
|
if (isWhite) whiteKingMoved = true;
|
||||||
|
else blackKingMoved = true;
|
||||||
|
} else if (type == PieceType.Rook) {
|
||||||
|
if (isWhite && selectedX == 0 && selectedY == 7) whiteQueensideRookMoved = true;
|
||||||
|
if (isWhite && selectedX == 7 && selectedY == 7) whiteKingsideRookMoved = true;
|
||||||
|
if (!isWhite && selectedX == 0 && selectedY == 0) blackQueensideRookMoved = true;
|
||||||
|
if (!isWhite && selectedX == 7 && selectedY == 0) blackKingsideRookMoved = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == PieceType.King) {
|
||||||
|
if (isWhite) {
|
||||||
|
if (selectedX == 4 && selectedY == 7 && x == 6 && y == 7) {
|
||||||
|
Pieces.removeIf(p -> p.getX() == 7 && p.getY() == 7);
|
||||||
|
Pieces.add(new Piece(5, 7, true, PieceType.Rook));
|
||||||
|
whiteKingsideRookMoved = true;
|
||||||
|
rookPiece = new Piece(7, 7, true, PieceType.Rook);
|
||||||
|
rookFromX = 7; rookFromY = 7; rookToX = 5; rookToY = 7;
|
||||||
|
} else if (selectedX == 4 && selectedY == 7 && x == 2 && y == 7) {
|
||||||
|
Pieces.removeIf(p -> p.getX() == 0 && p.getY() == 7);
|
||||||
|
Pieces.add(new Piece(3, 7, true, PieceType.Rook));
|
||||||
|
whiteQueensideRookMoved = true;
|
||||||
|
rookPiece = new Piece(0, 7, true, PieceType.Rook);
|
||||||
|
rookFromX = 0; rookFromY = 7; rookToX = 3; rookToY = 7;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (selectedX == 4 && selectedY == 0 && x == 6 && y == 0) {
|
||||||
|
Pieces.removeIf(p -> p.getX() == 7 && p.getY() == 0);
|
||||||
|
Pieces.add(new Piece(5, 0, false, PieceType.Rook));
|
||||||
|
blackKingsideRookMoved = true;
|
||||||
|
rookPiece = new Piece(7, 0, false, PieceType.Rook);
|
||||||
|
rookFromX = 7; rookFromY = 0; rookToX = 5; rookToY = 0;
|
||||||
|
} else if (selectedX == 4 && selectedY == 0 && x == 2 && y == 0) {
|
||||||
|
Pieces.removeIf(p -> p.getX() == 0 && p.getY() == 0);
|
||||||
|
Pieces.add(new Piece(3, 0, false, PieceType.Rook));
|
||||||
|
blackQueensideRookMoved = true;
|
||||||
|
rookPiece = new Piece(0, 0, false, PieceType.Rook);
|
||||||
|
rookFromX = 0; rookFromY = 0; rookToX = 3; rookToY = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (type == PieceType.Pawn && ((isWhite && y == 0) || (!isWhite && y == 7))) {
|
if (type == PieceType.Pawn && ((isWhite && y == 0) || (!isWhite && y == 7))) {
|
||||||
// Promote to queen
|
|
||||||
Pieces.add(new Piece(x, y, isWhite, PieceType.Queen));
|
Pieces.add(new Piece(x, y, isWhite, PieceType.Queen));
|
||||||
} else {
|
} else {
|
||||||
// Normal move
|
|
||||||
Pieces.add(new Piece(x, y, isWhite, type));
|
Pieces.add(new Piece(x, y, isWhite, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track if this move is a double pawn move
|
|
||||||
if (type == PieceType.Pawn && Math.abs(y - toMove.getY()) == 2) {
|
if (type == PieceType.Pawn && Math.abs(y - toMove.getY()) == 2) {
|
||||||
lastDoubleStepPawn = new Piece(x, y, isWhite, PieceType.Pawn);
|
lastDoubleStepPawn = new Piece(x, y, isWhite, PieceType.Pawn);
|
||||||
} else {
|
} else {
|
||||||
lastDoubleStepPawn = null;
|
lastDoubleStepPawn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update state
|
Move move;
|
||||||
|
if (type == PieceType.King && rookPiece != null) {
|
||||||
|
move = new Move(toMove, x, y, captured, rookPiece, rookFromX, rookFromY, rookToX, rookToY);
|
||||||
|
} else {
|
||||||
|
move = new Move(toMove, x, y, captured);
|
||||||
|
}
|
||||||
|
|
||||||
|
moveHistory.push(move);
|
||||||
turnNumber++;
|
turnNumber++;
|
||||||
turnWhite = !turnWhite;
|
turnWhite = !turnWhite;
|
||||||
hasSelection = false;
|
hasSelection = false;
|
||||||
|
|
||||||
Move move = new Move(toMove, x, y, captured); // captured may be null
|
|
||||||
moveHistory.push(move);
|
|
||||||
System.out.println(this);
|
System.out.println(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -426,6 +463,8 @@ public boolean isHighlighted(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KING LOGIC
|
||||||
|
// KING LOGIC
|
||||||
// KING LOGIC
|
// KING LOGIC
|
||||||
if (selected.getType() == PieceType.King) {
|
if (selected.getType() == PieceType.King) {
|
||||||
int[][] directions = {
|
int[][] directions = {
|
||||||
|
|
@ -444,12 +483,66 @@ public boolean isHighlighted(int x, int y) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CASTLING — WHITE
|
||||||
|
if (isWhite && !whiteKingMoved) {
|
||||||
|
// Kingside: e1 → g1
|
||||||
|
if (x == 6 && y == 7 &&
|
||||||
|
!whiteKingsideRookMoved &&
|
||||||
|
getPieceAt(5, 7) == null &&
|
||||||
|
getPieceAt(6, 7) == null &&
|
||||||
|
getPieceAt(7, 7) != null &&
|
||||||
|
getPieceAt(7, 7).getType() == PieceType.Rook &&
|
||||||
|
getPieceAt(7, 7).isWhite()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queenside: e1 → c1
|
||||||
|
if (x == 2 && y == 7 &&
|
||||||
|
!whiteQueensideRookMoved &&
|
||||||
|
getPieceAt(1, 7) == null &&
|
||||||
|
getPieceAt(2, 7) == null &&
|
||||||
|
getPieceAt(3, 7) == null &&
|
||||||
|
getPieceAt(0, 7) != null &&
|
||||||
|
getPieceAt(0, 7).getType() == PieceType.Rook &&
|
||||||
|
getPieceAt(0, 7).isWhite()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CASTLING — BLACK
|
||||||
|
if (!isWhite && !blackKingMoved) {
|
||||||
|
// Kingside: e8 → g8
|
||||||
|
if (x == 6 && y == 0 &&
|
||||||
|
!blackKingsideRookMoved &&
|
||||||
|
getPieceAt(5, 0) == null &&
|
||||||
|
getPieceAt(6, 0) == null &&
|
||||||
|
getPieceAt(7, 0) != null &&
|
||||||
|
getPieceAt(7, 0).getType() == PieceType.Rook &&
|
||||||
|
!getPieceAt(7, 0).isWhite()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queenside: e8 → c8
|
||||||
|
if (x == 2 && y == 0 &&
|
||||||
|
!blackQueensideRookMoved &&
|
||||||
|
getPieceAt(1, 0) == null &&
|
||||||
|
getPieceAt(2, 0) == null &&
|
||||||
|
getPieceAt(3, 0) == null &&
|
||||||
|
getPieceAt(0, 0) != null &&
|
||||||
|
getPieceAt(0, 0).getType() == PieceType.Rook &&
|
||||||
|
!getPieceAt(0, 0).isWhite()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void undoLastMove() {
|
public void undoLastMove() {
|
||||||
|
|
||||||
if (moveHistory.isEmpty()) return;
|
if (moveHistory.isEmpty()) return;
|
||||||
|
|
||||||
// Get the last move from the history
|
// Get the last move from the history
|
||||||
|
|
@ -474,8 +567,26 @@ public void undoLastMove() {
|
||||||
|
|
||||||
// Clear selection
|
// Clear selection
|
||||||
hasSelection = false;
|
hasSelection = false;
|
||||||
}
|
// Revert the extra moved piece (e.g. rook in castling)
|
||||||
|
if (last.getExtraMovedPiece() != null) {
|
||||||
|
Piece rook = last.getExtraMovedPiece();
|
||||||
|
Pieces.removeIf(p -> p.getX() == last.getExtraToX() && p.getY() == last.getExtraToY());
|
||||||
|
Pieces.add(new Piece(last.getExtraFromX(), last.getExtraFromY(), rook.isWhite(), rook.getType()));
|
||||||
|
|
||||||
|
// 🛠 Restore castling flags too
|
||||||
|
if (rook.isWhite()) {
|
||||||
|
if (last.getExtraFromX() == 0 && last.getExtraFromY() == 7) whiteQueensideRookMoved = false;
|
||||||
|
if (last.getExtraFromX() == 7 && last.getExtraFromY() == 7) whiteKingsideRookMoved = false;
|
||||||
|
whiteKingMoved = false; // 👈 Also reset king flag
|
||||||
|
} else {
|
||||||
|
if (last.getExtraFromX() == 0 && last.getExtraFromY() == 0) blackQueensideRookMoved = false;
|
||||||
|
if (last.getExtraFromX() == 7 && last.getExtraFromY() == 0) blackKingsideRookMoved = false;
|
||||||
|
blackKingMoved = false; // 👈 Also reset king flag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public Board(Board board) {
|
public Board(Board board) {
|
||||||
this.width = board.width;
|
this.width = board.width;
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ public class Move {
|
||||||
private final int toY;
|
private final int toY;
|
||||||
private final Piece movedPiece;
|
private final Piece movedPiece;
|
||||||
private final Piece capturedPiece;
|
private final Piece capturedPiece;
|
||||||
|
private Piece extraMovedPiece; // the rook
|
||||||
|
private int extraFromX, extraFromY;
|
||||||
|
private int extraToX, extraToY;
|
||||||
|
|
||||||
// Constructor for a move (with or without capture)
|
// Constructor for a move (with or without capture)
|
||||||
public Move(Piece movedPiece, int toX, int toY, Piece capturedPiece) {
|
public Move(Piece movedPiece, int toX, int toY, Piece capturedPiece) {
|
||||||
|
|
@ -18,6 +21,15 @@ public class Move {
|
||||||
this.movedPiece = movedPiece;
|
this.movedPiece = movedPiece;
|
||||||
this.capturedPiece = capturedPiece;
|
this.capturedPiece = capturedPiece;
|
||||||
}
|
}
|
||||||
|
public Move(Piece movedPiece, int toX, int toY, Piece capturedPiece,
|
||||||
|
Piece extraMovedPiece, int extraFromX, int extraFromY, int extraToX, int extraToY) {
|
||||||
|
this(movedPiece, toX, toY, capturedPiece);
|
||||||
|
this.extraMovedPiece = extraMovedPiece;
|
||||||
|
this.extraFromX = extraFromX;
|
||||||
|
this.extraFromY = extraFromY;
|
||||||
|
this.extraToX = extraToX;
|
||||||
|
this.extraToY = extraToY;
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience constructor when there's no capture
|
// Convenience constructor when there's no capture
|
||||||
public Move(Piece movedPiece, int toX, int toY) {
|
public Move(Piece movedPiece, int toX, int toY) {
|
||||||
|
|
@ -48,4 +60,10 @@ public class Move {
|
||||||
public Piece getCapturedPiece() {
|
public Piece getCapturedPiece() {
|
||||||
return capturedPiece;
|
return capturedPiece;
|
||||||
}
|
}
|
||||||
|
public Piece getExtraMovedPiece() { return extraMovedPiece; }
|
||||||
|
public int getExtraFromX() { return extraFromX; }
|
||||||
|
public int getExtraFromY() { return extraFromY; }
|
||||||
|
public int getExtraToX() { return extraToX; }
|
||||||
|
public int getExtraToY() { return extraToY; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,5 +29,5 @@ public class Piece {
|
||||||
public boolean isWhite() {
|
public boolean isWhite() {
|
||||||
return isWhite;
|
return isWhite;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue