OOP_1B6_Project/src/backend/Board.java

330 lines
10 KiB
Java

package backend;
import java.util.ArrayList;
public class Board {
private int selectedX = -1;
private int selectedY = -1;
private int turnNumber = 0;
public int width;
public int height;
private Piece[][] board;
private ArrayList<int[]> highlightedPositions = new ArrayList<>();
private int[] lastPawnDoubleMove = null; // Added for en passant tracking
public Board(int colNum, int lineNum) {
this.width = colNum;
this.height = lineNum;
this.board = new Piece[width][height];
clearConsole();
System.out.println(toString());
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
board[x][y] = new Piece(x, y, type, isWhite);
}
public boolean isTurnWhite() {
return turnNumber % 2 == 0;
}
public int getTurnNumber() {
return turnNumber;
}
public void incrementTurn() {
turnNumber++;
}
public void populateBoard() {
// Black
setPiece(false, PieceType.Rook, 0, 0);
setPiece(false, PieceType.Knight, 1, 0);
setPiece(false, PieceType.Bishop, 2, 0);
setPiece(false, PieceType.Queen, 3, 0);
setPiece(false, PieceType.King, 4, 0);
setPiece(false, PieceType.Bishop, 5, 0);
setPiece(false, PieceType.Knight, 6, 0);
setPiece(false, PieceType.Rook, 7, 0);
// Black pawns
for (int i = 0; i < 8; i++) {
setPiece(false, PieceType.Pawn, i, 1);
}
// White pawns
for (int i = 0; i < 8; i++) {
setPiece(true, PieceType.Pawn, i, 6);
}
// White
setPiece(true, PieceType.Rook, 0, 7);
setPiece(true, PieceType.Knight, 1, 7);
setPiece(true, PieceType.Bishop, 2, 7);
setPiece(true, PieceType.Queen, 3, 7);
setPiece(true, PieceType.King, 4, 7);
setPiece(true, PieceType.Bishop, 5, 7);
setPiece(true, PieceType.Knight, 6, 7);
setPiece(true, PieceType.Rook, 7, 7);
}
public void cleanBoard() {
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
board[x][y] = null;
}
}
}
public Piece getPiece(int x, int y) {
if (!isInBounds(x, y)) return null;
return board[x][y];
}
private void clearConsole() {
for (int i = 0; i < 50; i++) {
System.out.println();
}
}
public boolean isEnPassantTarget(int x, int y) {
if (lastPawnDoubleMove == null) return false;
if (lastPawnDoubleMove[2] != turnNumber - 1) return false;
return (lastPawnDoubleMove[0] == x && lastPawnDoubleMove[1] == y);
}
public void userTouch(int x, int y) {
if (selectedX == -1 && selectedY == -1) {
if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) {
selectedX = x;
selectedY = y;
highlightedPositions = getValidMoves(board[x][y]);
}
} else {
if (x == selectedX && y == selectedY) {
selectedX = -1;
selectedY = -1;
highlightedPositions.clear();
} else {
boolean valid = false;
for (int[] pos : highlightedPositions) {
if (pos[0] == x && pos[1] == y) {
valid = true;
break;
}
}
if (valid) {
Piece pieceToMove = board[selectedX][selectedY];
// Check for en passant capture
if (pieceToMove.getType() == PieceType.Pawn &&
x != selectedX &&
board[x][y] == null) {
board[x][selectedY] = null; // Capture the pawn
}
// Handle castling
if(pieceToMove.getType() == PieceType.King && Math.abs(x - selectedX)==2) {
y = selectedY;
if (x == 6) {
board[5][y] = board[7][y];
board[7][y] = null;
board[5][y].setMoved(true);
board[5][y].setX(5);
board[5][y].setY(y);
} else if (x == 2) {
board[3][y] = board[0][y];
board[0][y] = null;
board[3][y].setMoved(true);
board[3][y].setX(3);
board[3][y].setY(y);
}
}
// Track pawn double move for en passant
if (pieceToMove.getType() == PieceType.Pawn &&
Math.abs(y - selectedY) == 2) {
lastPawnDoubleMove = new int[]{x, y, turnNumber};
} else {
lastPawnDoubleMove = null;
}
// Move the piece
board[x][y] = new Piece(x, y, pieceToMove.getType(), pieceToMove.isWhite());
board[x][y].setMoved(true);
board[selectedX][selectedY] = null;
incrementTurn();
clearConsole();
}
selectedX = -1;
selectedY = -1;
highlightedPositions.clear();
System.out.println(toString());
}
}
}
public boolean isSelected(int x, int y) {
return (x == selectedX && y == selectedY);
}
public boolean isHighlighted(int x, int y) {
for (int[] pos : highlightedPositions) {
if (pos[0] == x && pos[1] == y) {
return true;
}
}
return false;
}
public boolean isInBounds(int x, int y) {
return x >= 0 && x < width && y >= 0 && y < height;
}
private ArrayList<int[]> getValidMoves(Piece piece) {
return piece.getValidMoves(this);
}
public ArrayList<Piece> getPieces() {
ArrayList<Piece> pieces = new ArrayList<>();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (board[x][y] != null) {
pieces.add(board[x][y]);
}
}
}
return pieces;
}
public String toString() {
StringBuilder str = new StringBuilder();
str.append(" A B C D E F G H\n");
for (int y = 0; y < height; y++) {
str.append(8 - y).append(" ");
for (int x = 0; x < width; x++) {
if (board[x][y] == null) {
str.append("- ");
} else {
Piece piece = board[x][y];
char pieceChar;
switch (piece.getType()) {
case King: pieceChar = 'K'; break;
case Queen: pieceChar = 'Q'; break;
case Bishop: pieceChar = 'B'; break;
case Knight: pieceChar = 'N'; break;
case Rook: pieceChar = 'R'; break;
case Pawn: pieceChar = 'P'; break;
default: pieceChar = '?'; break;
}
if (!piece.isWhite()) {
pieceChar = Character.toLowerCase(pieceChar);
}
str.append(pieceChar).append(" ");
}
}
str.append("\n");
}
str.append("Turn ").append(getTurnNumber()).append(": ");
str.append(isTurnWhite() ? "White" : "Black");
return str.toString();
}
public String[] toFileRep() {
String[] rep = new String[height + 1];
for (int y = 0; y < height; y++) {
StringBuilder line = new StringBuilder();
for (int x = 0; x < width; x++) {
if (board[x][y] == null) {
line.append("-");
} else {
Piece piece = board[x][y];
String pieceChar = piece.getType().getSummary();
if (!piece.isWhite()) {
pieceChar = pieceChar.toLowerCase();
}
line.append(pieceChar);
}
if (x < width - 1) {
line.append(",");
}
}
rep[y] = line.toString();
}
rep[height] = isTurnWhite() ? "W" : "B";
return rep;
}
public Board(String[] fileRepresentation) {
this.height = fileRepresentation.length - 1;
this.width = fileRepresentation[0].split(",").length;
this.board = new Piece[width][height];
this.selectedX = -1;
this.selectedY = -1;
this.highlightedPositions = new ArrayList<>();
for (int y = 0; y < height; y++) {
String[] squares = fileRepresentation[y].split(",");
for (int x = 0; x < width; x++) {
String squareData = squares[x];
if (squareData.equals("-")) {
continue;
}
char pieceChar = squareData.charAt(0);
boolean isWhite = Character.isUpperCase(pieceChar);
if (!isWhite) {
pieceChar = Character.toUpperCase(pieceChar);
}
PieceType type = PieceType.fromSummary(pieceChar);
setPiece(isWhite, type, x, y);
}
}
String turnInfo = fileRepresentation[height];
this.turnNumber = turnInfo.equals("W") ? 0 : 1;
clearConsole();
System.out.println(toString());
}
public void undoLastMove() {
// TODO
}
public void playMove(Move move) {
// TODO
}
public Board(Board board) {
// TODO
}
}