323 lines
8.8 KiB
Java
323 lines
8.8 KiB
Java
package backend;
|
||
|
||
import java.util.ArrayList;
|
||
import java.util.List;
|
||
|
||
public class Board {
|
||
private int width;
|
||
private int height;
|
||
private Piece[][] board;//creating an array for the coordinates of the board
|
||
private Piece chosenPiece=null;
|
||
private int turnNumber=0;
|
||
private boolean isTurnWhite=true;
|
||
private ArrayList<int[]> highlightedSquares= new ArrayList<>(); //stores highlighted board positions
|
||
private Move lastMove; // Tracks the last move; needed for en-passant rule
|
||
private List<Board> previousStates = new ArrayList<>(); // i added this
|
||
|
||
|
||
|
||
public Board(int colNum, int lineNum) {
|
||
this.width=colNum;
|
||
this.height=lineNum;
|
||
this.board= new Piece[width][height];
|
||
}
|
||
|
||
/**
|
||
* Copy-constructor: take a complete snapshot of another Board.
|
||
*/
|
||
public Board(Board other) {
|
||
// 1) copy dimensions
|
||
this.width = other.width;
|
||
this.height = other.height;
|
||
|
||
// 2) deep-copy the board array
|
||
this.board = new Piece[width][height];
|
||
for (int x = 0; x < width; x++) {
|
||
for (int y = 0; y < height; y++) {
|
||
this.board[x][y] = other.board[x][y];
|
||
}
|
||
}
|
||
|
||
// 3) copy any “selected” piece
|
||
this.chosenPiece = other.chosenPiece;
|
||
|
||
// 4) turn state
|
||
this.turnNumber = other.turnNumber;
|
||
this.isTurnWhite = other.isTurnWhite;
|
||
|
||
// 5) highlighted squares
|
||
this.highlightedSquares = new ArrayList<>(other.highlightedSquares);
|
||
|
||
// 6) lastMove (for en-passant)
|
||
this.lastMove = other.lastMove;
|
||
|
||
// 7) start with an empty history
|
||
this.previousStates = new ArrayList<>();
|
||
}
|
||
|
||
|
||
public int getWidth() {
|
||
return width;
|
||
}
|
||
|
||
public int getHeight() {
|
||
return height;
|
||
}
|
||
|
||
public int getTurnNumber() {
|
||
return turnNumber;
|
||
}
|
||
|
||
public boolean isTurnWhite() {
|
||
return isTurnWhite;
|
||
}
|
||
|
||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||
board[y][x]= new Piece (x, y, type, isWhite);
|
||
}
|
||
|
||
public void populateBoard() {
|
||
PieceType[] values= PieceType.values();
|
||
//Pawn, Rook, Knight, Bishop, Queen, King
|
||
PieceType[] backRowPieces= {values[1], values[2], values[3], values[4], values[5], values[3], values[2], values[1]};
|
||
//row 2 and 7 using only pawns
|
||
for(int x=0; x<8; x++) {
|
||
board[x][1]= new Piece(x,1,values[0], false);
|
||
board[x][6]= new Piece(x,6,values[0], true);
|
||
}
|
||
//row 1 and 8 using other pieces
|
||
for(int x=0; x<8; x++ ) {
|
||
board[x][0]= new Piece(x, 0, backRowPieces[x], false);
|
||
board[x][7]= new Piece(x, 7, backRowPieces[x], true);
|
||
}
|
||
|
||
}
|
||
|
||
|
||
public void cleanBoard() {
|
||
for(int y=0; y<8; y++) {
|
||
for(int x=0; x<8; x++) {
|
||
board[x][y]= null;
|
||
}
|
||
}
|
||
}
|
||
|
||
public String toString() { //review the stringbuilder class that already exists in java aand see if we can replace it by smth else
|
||
StringBuilder builder= new StringBuilder();
|
||
for (int y=0; y< height; y++) {
|
||
for (int x=0; x<width; x++) {
|
||
Piece thePiece=board[x][y];
|
||
if(thePiece!=null) {
|
||
String color =thePiece.isWhite()? "w":"b";
|
||
builder.append(color).append(thePiece.getType().getSummary());
|
||
} else {
|
||
builder.append("--");
|
||
}
|
||
}
|
||
builder.append("\n");
|
||
}
|
||
|
||
return builder.toString();
|
||
}
|
||
|
||
|
||
public ArrayList<Piece> getPieces() {
|
||
ArrayList<Piece> pieces = new ArrayList<>();
|
||
for(int y=0; y<8; y++) {
|
||
for(int x=0; x<8; x++) {
|
||
if(board[x][y] != null) {
|
||
pieces.add(board[x][y]);
|
||
}
|
||
}
|
||
}
|
||
return pieces;
|
||
}
|
||
|
||
public void userTouch(int x, int y) {
|
||
Piece clickedPiece=board[x][y];
|
||
if(chosenPiece==null) {
|
||
//when no piece is selected
|
||
if(clickedPiece!=null && clickedPiece.isWhite()==isTurnWhite) {
|
||
chosenPiece=clickedPiece;
|
||
highlightedPossibleMoves(clickedPiece);
|
||
}
|
||
}
|
||
else { //if a piece is already selected
|
||
if(isSelected(x,y)) {
|
||
chosenPiece=null; //unselect the chosen piece to revert to normal state
|
||
highlightedSquares.clear();
|
||
}
|
||
else { //move selected piece to new position using MovePiece logics
|
||
MovePiece movement= new MovePiece(chosenPiece, this);
|
||
boolean movementSuccess=false;
|
||
if(chosenPiece.getType()==PieceType.Pawn) {
|
||
movementSuccess=movement.movePawn(x,y);
|
||
} else if (chosenPiece.getType()==PieceType.Rook) {
|
||
movementSuccess=movement.moveRook(x, y);
|
||
}else if (chosenPiece.getType()==PieceType.Bishop) {
|
||
movementSuccess=movement.moveBishop(x, y);
|
||
}else if (chosenPiece.getType()==PieceType.King) {
|
||
movementSuccess=movement.moveKing(x, y);
|
||
}else if (chosenPiece.getType()==PieceType.Queen) {
|
||
movementSuccess=movement.moveQueen(x, y);
|
||
}else if (chosenPiece.getType()==PieceType.Knight) {
|
||
movementSuccess=movement.moveKnight(x, y);
|
||
}
|
||
if(movementSuccess) {
|
||
chosenPiece=null;
|
||
highlightedSquares.clear();
|
||
turnNumber++;
|
||
isTurnWhite=! isTurnWhite;
|
||
} else { //invalid move
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public boolean isSelected(int x, int y) { //checks if any piece is selected and if its position matches that of the x,y coordinates
|
||
return chosenPiece != null && chosenPiece.getX()==x && chosenPiece.getY()==y;
|
||
}
|
||
|
||
|
||
public Piece getPiece(int x, int y) { //returns figure and gives coordinates
|
||
if (x >= 0 && x < width && y >= 0 && y < height) { //checks if coordinates are inside the board
|
||
return board[x][y]; //returns the piece which is currently on this coordinates
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public void movePiece(int oldX, int oldY, int newX, int newY) {
|
||
previousStates.add(new Board(this));
|
||
if (board[oldX][oldY] != null) { //checks if there is a piece at that position
|
||
Piece piece = board[oldX][oldY]; // we get the piece from the board
|
||
board[newX][newY] = piece; // we place the piece on the new position
|
||
board[oldX][oldY] = null; // we clear last position
|
||
|
||
// Update its internal coordinates
|
||
piece.setX(newX);
|
||
piece.setY(newY);
|
||
lastMove= new Move(oldX, oldY, newX, newY, piece);//tracks the last move made
|
||
System.out.println(" Move saved: " + oldX + "," + oldY + " to " + newX + "," + newY);
|
||
piece.setDidMove(true);// setting that the piece has been moved
|
||
|
||
|
||
|
||
}
|
||
}
|
||
/* saving-loading feature :*/
|
||
|
||
public String[] toFileRep() {
|
||
//TODO
|
||
return null;
|
||
}
|
||
|
||
public Board(String[] array) {
|
||
//TODO
|
||
|
||
}
|
||
|
||
/* The following methods require more work ! */
|
||
|
||
private void highlightedPossibleMoves(Piece piece) {
|
||
highlightedSquares.clear();
|
||
highlightedSquares.addAll(MoveHighlighter.getPossibleMoves(piece, this));
|
||
}
|
||
|
||
public boolean isHighlighted(int x, int y) {
|
||
for(int i=0; i<highlightedSquares.size();i++) { //loops through list of highlighted squares
|
||
int[] position= highlightedSquares.get(i); //gets position of highlighted square
|
||
if(position[0]==x && position[1]==y) { //checks if chosen highlighted square matches with position where piece can go
|
||
return true; //it is highlighted
|
||
}
|
||
}
|
||
return false; }
|
||
|
||
|
||
public void removePiece(int x, int y) {
|
||
board[x][y]= null;
|
||
}
|
||
|
||
|
||
public Move getLastMove() {
|
||
return lastMove;
|
||
}
|
||
|
||
|
||
|
||
|
||
/**
|
||
* Reverts the board state back one move.
|
||
*/
|
||
public void undoLastMove() {
|
||
if (previousStates.isEmpty()) {
|
||
System.out.println("There are no moves to undo.");
|
||
return;
|
||
}
|
||
|
||
// 1) Pop off the most recent snapshot
|
||
Board prev = previousStates.remove(previousStates.size() - 1);
|
||
|
||
// 2) Restore the board array
|
||
this.board = new Piece[width][height];
|
||
for (int x = 0; x < width; x++) {
|
||
for (int y = 0; y < height; y++) {
|
||
this.board[x][y] = prev.board[x][y];
|
||
}
|
||
}
|
||
|
||
// 3) Restore all other game‐state fields
|
||
this.chosenPiece = prev.chosenPiece;
|
||
this.turnNumber = prev.turnNumber;
|
||
this.isTurnWhite = prev.isTurnWhite;
|
||
this.lastMove = prev.lastMove;
|
||
this.highlightedSquares = new ArrayList<>(prev.highlightedSquares);
|
||
|
||
// 4) **Critical**: reset each Piece’s own coordinates to match its array slot
|
||
for (int x = 0; x < width; x++) {
|
||
for (int y = 0; y < height; y++) {
|
||
Piece p = this.board[x][y];
|
||
if (p != null) {
|
||
p.setX(x);
|
||
p.setY(y);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 5) Clear any lingering selection or highlights
|
||
this.chosenPiece = null;
|
||
this.highlightedSquares.clear();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
private void updateTurnLabel() {
|
||
// TODO Auto-generated method stub
|
||
|
||
}
|
||
|
||
private void repaint() {
|
||
// TODO Auto-generated method stub
|
||
|
||
}
|
||
|
||
/*public Board(Board board) {
|
||
//TODO
|
||
|
||
}*/
|
||
|
||
public void playMove(Move move) {
|
||
//TODO
|
||
|
||
}
|
||
/** Expose the raw 2D array for testing or drawing. */
|
||
public Piece[][] getBoardArray() {
|
||
return board;
|
||
}
|
||
|
||
|
||
|
||
|
||
} |