This commit is contained in:
pierrepagot 2025-05-06 16:15:31 +02:00
commit 81460ad594
2 changed files with 130 additions and 114 deletions

View File

@ -7,8 +7,8 @@ public class Board {
private int selectedX = -1; // negative value means impossible x and y so unselected private int selectedX = -1; // negative value means impossible x and y so unselected
private int selectedY = -1; private int selectedY = -1;
private int turnNumber = 0; // track current turn private int turnNumber = 0; // tracks current turn
private int width; private int width; // enables to define the dimensions of board
private int height; private int height;
private Piece[][] board; // 2D array chess board private Piece[][] board; // 2D array chess board
private ArrayList<int[]> highlightedPositions = new ArrayList<>(); // list of valid positions to highlight private ArrayList<int[]> highlightedPositions = new ArrayList<>(); // list of valid positions to highlight
@ -16,7 +16,7 @@ public class Board {
public Board(int colNum, int lineNum) { public Board(int colNum, int lineNum) {
this.width = colNum; this.width = colNum;
this.height = lineNum; this.height = lineNum;
this.board = new Piece[width][height]; // first empty board this.board = new Piece[width][height]; // first empty board *********REVIEW************
clearConsole(); clearConsole();
System.out.println(toString()); // print the chess at the beginning of the game System.out.println(toString()); // print the chess at the beginning of the game
} }
@ -29,28 +29,28 @@ public class Board {
return height; return height;
} }
// new piece on the board at x,y // new piece on the board at x,y (More specifically changes the empty cell of coordinates x,y with a new chess piece)
public void setPiece(boolean isWhite, PieceType type, int x, int y) { public void setPiece(boolean isWhite, PieceType type, int x, int y) {
board[x][y] = new Piece(x, y, type, isWhite); board[x][y] = new Piece(x, y, type, isWhite);
} }
public boolean isTurnWhite() { public boolean isTurnWhite() {
if (turnNumber % 2 == 0) { // even turns including 0 are white's ones if (turnNumber % 2 == 0) { // even turns including 0 are white's ones (% calculates the reminder of the euclidean division)
return true; return true;
} else { // same reasoning, odd turns are black's ones } else { // same reasoning, odd turns are black's ones
return false; return false;
} }
} }
public int getTurnNumber() { // these classes change the turn and the increment one solves a problem of infinite loop public int getTurnNumber() { // this class enables to obtain the current turn number while increment adds 1 to this value for each turn
return turnNumber; return turnNumber; // Necessarly in two functions to get rid of an infinite loop ****WHY****
} }
public void incrementTurn() { public void incrementTurn() {
turnNumber++; turnNumber++;
} }
// set up the chess board taking it as a matrix // set up the classic chess board taking it as a matrix and putting each corresponding starting piece at its place 0,0 is the top left spot of the board
public void populateBoard() { public void populateBoard() {
// Black // Black
setPiece(false, PieceType.Rook, 0, 0); setPiece(false, PieceType.Rook, 0, 0);
@ -90,8 +90,12 @@ public class Board {
} }
} }
} }
public Piece getPiece(int x, int y) {
if (!isInBounds (x, y)) return null;
return board [x][y];
}
private void clearConsole() { private void clearConsole() { // ***************CONSOLE
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
System.out.println(); // Print 50 empty lines to "clear" the console System.out.println(); // Print 50 empty lines to "clear" the console
} }
@ -157,7 +161,7 @@ public class Board {
// user clicks on the board // user clicks on the board
public void userTouch(int x, int y) { public void userTouch(int x, int y) {
if (selectedX == -1 && selectedY == -1) { if (selectedX == -1 && selectedY == -1) { // This condition is only possible at the very start of the game
// check if the position is empty and the color // check if the position is empty and the color
if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) { if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) {
// select it as active location // select it as active location
@ -167,7 +171,7 @@ public class Board {
} }
} else { } else {
if (x == selectedX && y == selectedY) { if (x == selectedX && y == selectedY) {
// unselect it // unselect it if the destination is unvalid (not highlighted)
selectedX = -1; selectedX = -1;
selectedY = -1; selectedY = -1;
highlightedPositions.clear(); highlightedPositions.clear();
@ -212,112 +216,12 @@ public class Board {
} }
/* utility methods */ /* utility methods */
private boolean isInBounds(int x, int y) { public boolean isInBounds(int x, int y) {
return x >= 0 && x < width && y >= 0 && y < height; return x >= 0 && x < width && y >= 0 && y < height;
} }
private void addLinearMoves(ArrayList<int[]> moves, int x, int y, Piece piece, int dx, int dy) {
int nx = x + dx;
int ny = y + dy;
while (isInBounds(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 += dx;
ny += dy;
}
}
private ArrayList<int[]> getValidMoves(Piece piece) { private ArrayList<int[]> getValidMoves(Piece piece) {
ArrayList<int[]> moves = new ArrayList<>(); return piece.getValidMoves(this);
int x = piece.getX();
int y = piece.getY();
switch (piece.getType()) {
case Pawn:
int direction = piece.isWhite() ? -1 : 1;
int nextY = y + direction;
// forward move
if (isInBounds(x, nextY) && board[x][nextY] == null) {
moves.add(new int[]{x, nextY});
// double move from starting position
int startRow = piece.isWhite() ? 6 : 1;
int doubleStepY = y + 2 * direction;
if (y == startRow && isInBounds(x, doubleStepY) && board[x][doubleStepY] == null) {
moves.add(new int[]{x, doubleStepY});
}
}
// diagonal captures
for (int dx = -1; dx <= 1; dx += 2) {
int nx = x + dx;
if (isInBounds(nx, nextY) && board[nx][nextY] != null && board[nx][nextY].isWhite() != piece.isWhite()) {
moves.add(new int[]{nx, nextY});
}
}
break;
case Rook:
addLinearMoves(moves, x, y, piece, 1, 0);
addLinearMoves(moves, x, y, piece, -1, 0);
addLinearMoves(moves, x, y, piece, 0, 1);
addLinearMoves(moves, x, y, piece, 0, -1);
break;
case Bishop:
addLinearMoves(moves, x, y, piece, 1, 1);
addLinearMoves(moves, x, y, piece, -1, 1);
addLinearMoves(moves, x, y, piece, 1, -1);
addLinearMoves(moves, x, y, piece, -1, -1);
break;
case Queen:
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx != 0 || dy != 0) {
addLinearMoves(moves, x, y, piece, dx, dy);
}
}
}
break;
case King:
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx != 0 || dy != 0) {
int nx = x + dx;
int ny = y + dy;
if (isInBounds(nx, ny) && (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite())) {
moves.add(new int[]{nx, ny});
}
}
}
}
break;
case Knight:
int[][] jumps = {
{1, 2}, {2, 1}, {-1, 2}, {-2, 1},
{-1, -2}, {-2, -1}, {1, -2}, {2, -1}
};
for (int[] j : jumps) {
int nx = x + j[0];
int ny = y + j[1];
if (isInBounds(nx, ny) && (board[nx][ny] == null || board[nx][ny].isWhite() != piece.isWhite())) {
moves.add(new int[]{nx, ny});
}
}
break;
}
return moves;
} }
/* saving-loading feature : */ /* saving-loading feature : */

View File

@ -23,6 +23,7 @@ public class Piece {
return y; return y;
} }
public PieceType getType() { public PieceType getType() {
return type; return type;
} }
@ -30,5 +31,116 @@ public class Piece {
public boolean isWhite() { public boolean isWhite() {
return pieceColor; return pieceColor;
} }
public ArrayList<int[]> getValidMoves(Board board) {
ArrayList<int[]> moves = new ArrayList<>();
int x = this.getX();
int y = this.getY();
switch (type) {
case Pawn:
int direction = isWhite() ? -1 : 1;
int nextY = y + direction;
// forward move
if (board.isInBounds(x, nextY) && board.getPiece(x, nextY) == null) {
moves.add(new int[]{x, nextY});
// double move from starting position
int startRow = isWhite() ? 6 : 1;
int doubleStepY = y + 2 * direction;
if (y == startRow && board.isInBounds(x, doubleStepY) && board.getPiece(x, doubleStepY) == null) {
moves.add(new int[]{x, doubleStepY});
}
}
// diagonal captures
for (int dx = -1; dx <= 1; dx += 2) {
int nx = x + dx;
if (board.isInBounds(nx, nextY)) {
Piece target = board.getPiece(nx, nextY);
if (target != null && target.isWhite() != this.isWhite()) {
moves.add(new int[]{nx, nextY});
}
}
}
break;
case Rook:
addLinearMoves(board, moves, x, y, 1, 0);
addLinearMoves(board, moves, x, y, -1, 0);
addLinearMoves(board, moves, x, y, 0, 1);
addLinearMoves(board, moves, x, y, 0, -1);
break;
case Bishop:
addLinearMoves(board, moves, x, y, 1, 1);
addLinearMoves(board, moves, x, y, -1, 1);
addLinearMoves(board, moves, x, y, 1, -1);
addLinearMoves(board, moves, x, y, -1, -1);
break;
case Queen:
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx != 0 || dy != 0) {
addLinearMoves(board, moves, x, y, dx, dy);
}
}
}
break;
case King:
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
if (dx != 0 || dy != 0) {
int nx = x + dx;
int ny = y + dy;
if (board.isInBounds(nx, ny)) {
Piece target = board.getPiece(nx, ny);
if (target == null || target.isWhite() != this.isWhite()) {
moves.add(new int[]{nx, ny});
}
}
}
}
}
break;
case Knight:
int[][] jumps = {
{1, 2}, {2, 1}, {-1, 2}, {-2, 1},
{-1, -2}, {-2, -1}, {1, -2}, {2, -1}
};
for (int[] j : jumps) {
int nx = x + j[0];
int ny = y + j[1];
if (board.isInBounds(nx, ny)) {
Piece target = board.getPiece(nx, ny);
if (target == null || target.isWhite() != this.isWhite()) {
moves.add(new int[]{nx, ny});
}
}
}
break;
}
return moves;
}
private void addLinearMoves(Board board, ArrayList<int[]> moves, int x, int y, int dx, int dy) {
int nx = x + dx;
int ny = y + dy;
while (board.isInBounds(nx, ny)) {
Piece target = board.getPiece(nx, ny);
if (target == null) {
moves.add(new int[]{nx, ny});
} else {
if (target.isWhite() != this.isWhite()) {
moves.add(new int[]{nx, ny});
}
break;
}
nx += dx;
ny += dy;
}
}
} }