OOP_Groupe_1A3_Project/src/backend/Board.java

323 lines
8.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 gamestate 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 Pieces 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;
}
}