i add the saving and loading features to save and rebuild the board

state
This commit is contained in:
chloe 2025-05-13 15:01:37 +02:00
parent 68c043a279
commit 9331dc8b12
1 changed files with 323 additions and 626 deletions

View File

@ -1,633 +1,330 @@
package backend; package backend;
import java.util.ArrayList; import java.util.ArrayList;
public class Board { public class Board {
public int width;
public int height;
public int width; private Piece[][] board;
private boolean hasSelectedPiece = false;
public int height; private int selectedX = -1;
private int selectedY = -1;
private Piece[][] board; private int turnNumber = 0;
private boolean turnWhite = true;
private boolean hasSelectedPiece = false; private ArrayList<int[]> highlightedSquares = new ArrayList<>();
private int selectedX = -1; public Board(int colNum, int lineNum) {
this.width = colNum;
private int selectedY = -1; this.height = lineNum;
this.board = new Piece[width][height];
private int turnNumber = 0; }
private boolean turnWhite = true; public int getWidth() {
return width;
private ArrayList<int[]> highlightedSquares = new ArrayList<>(); }
public int getHeight() {
return height;
public Board(int colNum, int lineNum) { }
this.width = colNum; public int getTurnNumber() {
return turnNumber;
this.height = lineNum; }
this.board = new Piece[width][height]; public boolean isTurnWhite() {
return turnWhite;
} }
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
if (x >= 0 && x < width && y >= 0 && y < height) {
public int getWidth() { board[x][y] = new Piece(x, y, isWhite, type);
}
return width; }
} public void populateBoard() {
cleanBoard();
// White pawns
for (int x = 0; x < 8; x++) {
public int getHeight() { setPiece(true, PieceType.Pawn, x, 1);
}
return height; // Black pawns
for (int x = 0; x < 8; x++) {
} setPiece(false, PieceType.Pawn, x, 6);
}
PieceType[] backRow = {
public int getTurnNumber() { PieceType.Rook, PieceType.Knight, PieceType.Bishop,
PieceType.Queen, PieceType.King, PieceType.Bishop,
return turnNumber; PieceType.Knight, PieceType.Rook
};
}
// White back row
for (int x = 0; x < 8; x++) {
setPiece(true, backRow[x], x, 0);
public boolean isTurnWhite() { }
// Black back row
return turnWhite; for (int x = 0; x < 8; x++) {
setPiece(false, backRow[x], x, 7);
} }
}
public void cleanBoard() {
public void setPiece(boolean isWhite, PieceType type, int x, int y) { for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (x >= 0 && x < width && y >= 0 && y < height) { board[x][y] = null;
}
board[x][y] = new Piece(x, y, isWhite, type); }
}
}
public String toString() {
} StringBuilder stringboard= new StringBuilder();
for (int row = height - 1; row >= 0; row--) {
for (int column = 0; column < width; column++) {
public void populateBoard() { Piece piece = board[column][row];
if (piece == null) {
cleanBoard(); stringboard.append(". ");
} else {
// White pawns char sym = piece.getType().name().charAt(0);
stringboard.append(piece.isWhite() ? sym : Character.toLowerCase(sym))
for (int x = 0; x < 8; x++) { .append(' ');
}
setPiece(true, PieceType.Pawn, x, 1); }
stringboard.append("\n");
} }
stringboard.append(" ");
// Black pawns for (int x = 0; x < width; x++) {
stringboard.append((char)('a' + x)).append(' ');
for (int x = 0; x < 8; x++) { }
stringboard.append("\n");
setPiece(false, PieceType.Pawn, x, 6); stringboard.append("Turn: ").append(isTurnWhite() ? "White" : "Black");
return stringboard.toString();
} }
public ArrayList<Piece> getPieces() {
PieceType[] backRow = { ArrayList<Piece> pieces = new ArrayList<>();
for (int x = 0; x < width; x++) {
PieceType.Rook, PieceType.Knight, PieceType.Bishop, for (int y = 0; y < height; y++) {
if (board[x][y] != null) {
PieceType.Queen, PieceType.King, PieceType.Bishop, pieces.add(board[x][y]);
}
PieceType.Knight, PieceType.Rook }
}
}; return pieces;
// White back row
}
for (int x = 0; x < 8; x++) {
public boolean isSelected(int x, int y) {
setPiece(true, backRow[x], x, 0); return hasSelectedPiece && selectedX == x && selectedY == y;
}
}
private boolean inBounds(int x, int y) {
// Black back row return x >= 0 && x < width && y >= 0 && y < height;
}
for (int x = 0; x < 8; x++) {
setPiece(false, backRow[x], x, 7); private ArrayList<int[]> getValidMoves(Piece piece) {
ArrayList<int[]> moves = new ArrayList<>();
} int x = piece.getX();
int y = piece.getY();
} PieceType type = piece.getType();
if (type == PieceType.Pawn) {
int dir = piece.isWhite() ? 1 : -1;
public void cleanBoard() { int startRow = piece.isWhite() ? 1 : 6;
for (int x = 0; x < width; x++) { int oneStep = y + dir;
if (inBounds(x, oneStep) && board[x][oneStep] == null) {
for (int y = 0; y < height; y++) { moves.add(new int[]{x, oneStep});
board[x][y] = null; // If on start row, try two steps forward
int twoStep = y + 2 * dir;
} if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null) {
moves.add(new int[]{x, twoStep});
} }
}
}
// Capture diagonals
for (int dx : new int[]{-1, 1}) {
int nx = x + dx;
public String toString() { int ny = y + dir;
if (inBounds(nx, ny) && board[nx][ny] != null &&
StringBuilder stringboard= new StringBuilder(); board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
for (int row = height - 1; row >= 0; row--) { }
}
}
else if (type == PieceType.Rook) {
for (int column = 0; column < width; column++) { int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}};
for (int[] d : dirs) {
Piece piece = board[column][row]; int nx = x + d[0], ny = y + d[1];
while (inBounds(nx, ny)) {
if (piece == null) { if (board[nx][ny] == null) {
moves.add(new int[]{nx, ny});
stringboard.append(". "); } else {
if (board[nx][ny].isWhite() != piece.isWhite()) {
} else { moves.add(new int[]{nx, ny});
}
char sym = piece.getType().name().charAt(0); break;
}
stringboard.append(piece.isWhite() ? sym : Character.toLowerCase(sym)) nx += d[0]; ny += d[1];
}
.append(' '); }
}
}
else if (type == PieceType.Bishop) {
} int[][] dirs = {{1,1}, {-1,1}, {-1,-1}, {1,-1}};
for (int[] d : dirs) {
stringboard.append("\n"); int nx = x + d[0], ny = y + d[1];
while (inBounds(nx, ny)) {
} if (board[nx][ny] == null) {
moves.add(new int[]{nx, ny});
stringboard.append(" "); } else {
if (board[nx][ny].isWhite() != piece.isWhite()) {
for (int x = 0; x < width; x++) { moves.add(new int[]{nx, ny});
}
stringboard.append((char)('a' + x)).append(' '); break;
}
} nx += d[0]; ny += d[1];
}
stringboard.append("\n"); }
}
stringboard.append("Turn: ").append(isTurnWhite() ? "White" : "Black");
else if (type == PieceType.Queen) {
return stringboard.toString(); // Queen = Rook + Bishop
moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Rook)));
} moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Bishop)));
}
else if (type == PieceType.Knight) {
int[][] jumps = {
{2,1},{1,2},{-1,2},{-2,1},
public ArrayList<Piece> getPieces() { {-2,-1},{-1,-2},{1,-2},{2,-1}
};
ArrayList<Piece> pieces = new ArrayList<>(); for (int[] j : jumps) {
int nx = x + j[0], ny = y + j[1];
for (int x = 0; x < width; x++) { if (inBounds(nx, ny)) {
if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) {
for (int y = 0; y < height; y++) { moves.add(new int[]{nx, ny});
}
if (board[x][y] != null) { }
}
pieces.add(board[x][y]); }
} else if (type == PieceType.King) {
int[][] dirs = {
} {1,0}, {-1,0}, {0,1}, {0,-1},
{1,1}, {-1,1}, {-1,-1}, {1,-1}
} };
for (int[] d : dirs) {
return pieces; int nx = x + d[0], ny = y + d[1];
if (inBounds(nx, ny)) {
if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
}
}
}
}
return moves;
} }
public boolean isSelected(int x, int y) {
public void userTouch(int x, int y) {
return hasSelectedPiece && selectedX == x && selectedY == y; if (x < 0 || x >= width || y < 0 || y >= height) return;
} Piece clicked = board[x][y];
if (!hasSelectedPiece) {
if (clicked != null && clicked.isWhite() == turnWhite) {
private boolean inBounds(int x, int y) { // Select piece
selectedX = x;
return x >= 0 && x < width && y >= 0 && y < height; selectedY = y;
hasSelectedPiece = true;
} highlightedSquares = getValidMoves(clicked); // Highlight legal moves
}
} else {
// Check if clicked again on the same square to unselect
if (selectedX == x && selectedY == y) {
hasSelectedPiece = false;
private ArrayList<int[]> getValidMoves(Piece piece) { highlightedSquares.clear();
}
ArrayList<int[]> moves = new ArrayList<>(); // If clicked on a highlighted square, move there
else if (isHighlighted(x, y)) {
int x = piece.getX(); Piece selectedPiece = board[selectedX][selectedY];
int y = piece.getY(); // Move piece
board[x][y] = selectedPiece;
PieceType type = piece.getType(); board[selectedX][selectedY] = null;
selectedPiece.setX(x);
selectedPiece.setY(y);
if (type == PieceType.Pawn) { // Update turn
turnWhite = !turnWhite;
int dir = piece.isWhite() ? 1 : -1; turnNumber++;
int startRow = piece.isWhite() ? 1 : 6; // Clear selection & highlights
hasSelectedPiece = false;
highlightedSquares.clear();
}
int oneStep = y + dir; // Invalid move: just unselect
else {
if (inBounds(x, oneStep) && board[x][oneStep] == null) { hasSelectedPiece = false;
highlightedSquares.clear();
moves.add(new int[]{x, oneStep}); }
}
}
// If on start row, try two steps forward
int twoStep = y + 2 * dir; /* saving-loading feature */
public String[] toFileRep() {
if (y == startRow && inBounds(x, twoStep) && board[x][twoStep] == null) { ArrayList<String> fileLines = new ArrayList<>();
fileLines.add(turnNumber + "," + (turnWhite ? "white" : "black"));
moves.add(new int[]{x, twoStep}); fileLines.add(width + "," + height);
for (Piece piece : getPieces()) {
} StringBuilder sb = new StringBuilder();
sb.append(piece.getType()) // e.g. "Pawn"
} .append(",").append(piece.getX()) // file X
.append(",").append(piece.getY()) // file Y
.append(",").append(piece.isWhite() ? "W" : "B");
fileLines.add(sb.toString());
// Capture diagonals }
return fileLines.toArray(new String[0]);
for (int dx : new int[]{-1, 1}) { }
int nx = x + dx;
int ny = y + dir; public Board(String[] array) {
// TODO
if (inBounds(nx, ny) && board[nx][ny] != null && }
board[nx][ny].isWhite() != piece.isWhite()) { /* The following methods require more work */
public boolean isHighlighted(int x, int y) {
moves.add(new int[]{nx, ny}); for (int[] pos : highlightedSquares) {
if (pos[0] == x && pos[1] == y) {
} return true;
}
} }
return false;
} }
else if (type == PieceType.Rook) { public void undoLastMove() {
// TODO
int[][] dirs = {{1,0}, {-1,0}, {0,1}, {0,-1}}; }
for (int[] d : dirs) { public Board(Board board) {
// TODO helloyo
int nx = x + d[0], ny = y + d[1]; }
while (inBounds(nx, ny)) { public void playMove(Move move) {
// TODO
if (board[nx][ny] == null) { }
moves.add(new int[]{nx, ny});
} else {
if (board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
}
break;
}
nx += d[0]; ny += d[1];
}
}
}
else if (type == PieceType.Bishop) {
int[][] dirs = {{1,1}, {-1,1}, {-1,-1}, {1,-1}};
for (int[] d : dirs) {
int nx = x + d[0], ny = y + d[1];
while (inBounds(nx, ny)) {
if (board[nx][ny] == null) {
moves.add(new int[]{nx, ny});
} else {
if (board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
}
break;
}
nx += d[0]; ny += d[1];
}
}
}
else if (type == PieceType.Queen) {
// Queen = Rook + Bishop
moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Rook)));
moves.addAll(getValidMoves(new Piece(x, y, piece.isWhite(), PieceType.Bishop)));
}
else if (type == PieceType.Knight) {
int[][] jumps = {
{2,1},{1,2},{-1,2},{-2,1},
{-2,-1},{-1,-2},{1,-2},{2,-1}
};
for (int[] j : jumps) {
int nx = x + j[0], ny = y + j[1];
if (inBounds(nx, ny)) {
if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
}
}
}
}
else if (type == PieceType.King) {
int[][] dirs = {
{1,0}, {-1,0}, {0,1}, {0,-1},
{1,1}, {-1,1}, {-1,-1}, {1,-1}
};
for (int[] d : dirs) {
int nx = x + d[0], ny = y + d[1];
if (inBounds(nx, ny)) {
if (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, ny});
}
}
}
}
return moves;
}
public void userTouch(int x, int y) {
if (x < 0 || x >= width || y < 0 || y >= height) return;
Piece clicked = board[x][y];
if (!hasSelectedPiece) {
if (clicked != null && clicked.isWhite() == turnWhite) {
// Select piece
selectedX = x;
selectedY = y;
hasSelectedPiece = true;
highlightedSquares = getValidMoves(clicked); // Highlight legal moves
}
} else {
// Check if clicked again on the same square to unselect
if (selectedX == x && selectedY == y) {
hasSelectedPiece = false;
highlightedSquares.clear();
}
// If clicked on a highlighted square, move there
else if (isHighlighted(x, y)) {
Piece selectedPiece = board[selectedX][selectedY];
// Move piece
board[x][y] = selectedPiece;
board[selectedX][selectedY] = null;
selectedPiece.setX(x);
selectedPiece.setY(y);
// Update turn
turnWhite = !turnWhite;
turnNumber++;
// Clear selection & highlights
hasSelectedPiece = false;
highlightedSquares.clear();
}
// Invalid move: just unselect
else {
hasSelectedPiece = false;
highlightedSquares.clear();
}
}
}
/* saving-loading feature */
public String[] toFileRep() {
return null;
}
public Board(String[] array) {
// TODO
}
/* The following methods require more work */
public boolean isHighlighted(int x, int y) {
for (int[] pos : highlightedSquares) {
if (pos[0] == x && pos[1] == y) {
return true;
}
}
return false;
}
public void undoLastMove() {
// TODO
}
public Board(Board board) {
// TODO helloyo
}
public void playMove(Move move) {
// TODO
}
} }