adding all the movements possibility and highlighting the squares.

This commit is contained in:
Elève 2025-04-18 16:57:13 +02:00
parent 18c29cd2df
commit dc8c3d1faa
1 changed files with 296 additions and 195 deletions

View File

@ -4,55 +4,55 @@ import java.util.ArrayList;
public class Board { 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; // track current turn
private int width; private int width;
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
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
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
} }
public int getWidth() { public int getWidth() {
return width; return width;
} }
public int getHeight() { public int getHeight() {
return height; return height;
} }
// new piece on the board at x,y // new piece on the board at x,y
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 O are white's ones if (turnNumber % 2 == 0) { // even turns including 0 are white's ones
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() { //theses classes change the turn and the increment one solve a problem of infinite loop public int getTurnNumber() { // these classes change the turn and the increment one solves a problem of infinite loop
return turnNumber; return turnNumber;
} }
public void incrementTurn() { public void incrementTurn() {
turnNumber++; turnNumber++;
} }
//set up the chess board taking it as a matrix // set up the chess board taking it as a matrix
public void populateBoard() { public void populateBoard() {
// Black // Black
setPiece(false, PieceType.Rook, 0, 0); setPiece(false, PieceType.Rook, 0, 0);
setPiece(false, PieceType.Knight, 1, 0); setPiece(false, PieceType.Knight, 1, 0);
setPiece(false, PieceType.Bishop, 2, 0); setPiece(false, PieceType.Bishop, 2, 0);
@ -63,12 +63,12 @@ public class Board {
setPiece(false, PieceType.Rook, 7, 0); setPiece(false, PieceType.Rook, 7, 0);
// Black pawns // Black pawns
for(int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
setPiece(false, PieceType.Pawn, i, 1); setPiece(false, PieceType.Pawn, i, 1);
} }
// White pawns // White pawns
for(int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
setPiece(true, PieceType.Pawn, i, 6); setPiece(true, PieceType.Pawn, i, 6);
} }
@ -81,164 +81,265 @@ public class Board {
setPiece(true, PieceType.Bishop, 5, 7); setPiece(true, PieceType.Bishop, 5, 7);
setPiece(true, PieceType.Knight, 6, 7); setPiece(true, PieceType.Knight, 6, 7);
setPiece(true, PieceType.Rook, 7, 7); setPiece(true, PieceType.Rook, 7, 7);
} }
public void cleanBoard() { public void cleanBoard() {
for(int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for(int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
board[x][y] = null; //each position become empty board[x][y] = null; // each position becomes empty
} }
} }
} }
private void clearConsole() {
for (int i = 0; i < 50; i++) {
System.out.println(); // Print 50 empty lines to "clear" the console
}
}
private void clearConsole() { public String toString() {
for(int i = 0; i < 50; i++) { StringBuilder str = new StringBuilder();
System.out.println(); // Print 50 empty lines to "clear" the console str.append(" A B C D E F G H\n"); // columns letter at the top
}
}
public String toString() { // representation of the rows
StringBuilder str = new StringBuilder(); for (int y = 0; y < height; y++) {
str.append(8 - y).append(" "); // row number on the left
str.append(" A B C D E F G H\n"); //columns letter at the top for (int x = 0; x < width; x++) {
if (board[x][y] == null) {
str.append("- "); // empty positions
} else {
// convert each piece of both color into a character
Piece piece = board[x][y];
char pieceChar;
// representation of the rows switch (piece.getType()) { // switch function avoids too many if-else
for(int y = 0; y < height; y++) { case King: pieceChar = 'K'; break;
str.append(8 - y).append(" "); // row number on the left case Queen: pieceChar = 'Q'; break;
case Bishop: pieceChar = 'B'; break;
case Knight: pieceChar = 'N'; break; // N because we already have King
case Rook: pieceChar = 'R'; break;
case Pawn: pieceChar = 'P'; break;
default: pieceChar = '?'; break; // safety net
}
for(int x = 0; x < width; x++) { // Make black pieces in lowercase
if(board[x][y] == null) { if (!piece.isWhite()) {
str.append("- "); // empty positions pieceChar = Character.toLowerCase(pieceChar);
} else { }
// convert each piece of both color into a character str.append(pieceChar).append(" "); // gives structure to the output
Piece piece = board[x][y]; }
char pieceChar; //one character }
str.append("\n"); // change of row
}
switch(piece.getType()) { //switch function solve the problem of too many if-else // Additional infos for a proper output
case King: pieceChar = 'K'; break; //case is reading in king and break stop the switch function str.append("Turn ").append(getTurnNumber()).append(": ");
case Queen: pieceChar = 'Q'; break; str.append(isTurnWhite() ? "White" : "Black");
case Bishop: pieceChar = 'B'; break;
case Knight: pieceChar = 'N'; break; // N because we already have King
case Rook: pieceChar = 'R'; break;
case Pawn: pieceChar = 'P'; break;
default: pieceChar = '?'; break; //solve an issue of unresolved compilation and act as a safety net
}
// Make black pieces in lowercase return str.toString();
if(!piece.isWhite()) { }
pieceChar = Character.toLowerCase(pieceChar);
}
str.append(pieceChar).append(" "); //gives structure to the output // list the placement of the pieces on the board
} public ArrayList<Piece> getPieces() {
} ArrayList<Piece> pieces = new ArrayList<>();
str.append("\n"); //change of row // collect infos for the non-empty positions
} 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;
}
// Additional infos for a proper ouput // user clicks on the board
str.append("Turn ").append(getTurnNumber()).append(": "); //turnnumber public void userTouch(int x, int y) {
str.append(isTurnWhite() ? "White" : "Black"); //color's turn if (selectedX == -1 && selectedY == -1) {
// check if the position is empty and the color
if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) {
// select it as active location
selectedX = x;
selectedY = y;
highlightedPositions = getValidMoves(board[x][y]); // compute moves
}
} else {
if (x == selectedX && y == selectedY) {
// unselect it
selectedX = -1;
selectedY = -1;
highlightedPositions.clear();
} else {
// move if valid destination
boolean valid = false;
for (int[] pos : highlightedPositions) {
if (pos[0] == x && pos[1] == y) {
valid = true;
break;
}
}
return str.toString(); if (valid) {
} Piece pieceToMove = board[selectedX][selectedY];
board[x][y] = new Piece(x, y, pieceToMove.getType(), pieceToMove.isWhite());
board[selectedX][selectedY] = null;
incrementTurn();
}
//list the placement of the pieces on the board // reset selection
public ArrayList<Piece> getPieces() { selectedX = -1;
ArrayList<Piece> pieces = new ArrayList<>(); selectedY = -1;
//collect infos for the empty positions highlightedPositions.clear();
for(int x = 0; x < width; x++) { clearConsole();
for(int y = 0; y < height; y++) { System.out.println(toString());
if(board[x][y] != null) { }
pieces.add(board[x][y]); }
} }
}
}
return pieces;
}
//user click on the board public boolean isSelected(int x, int y) {
public void userTouch(int x, int y) { return (x == selectedX && y == selectedY); // true if matching position
// 1: no position was previously selected }
if (selectedX == -1 && selectedY == -1) {
// check if the position is empty and the color
if (board[x][y] != null && board[x][y].isWhite() == isTurnWhite()) {
// select it as active location
selectedX = x;
selectedY = y;
}
}
// 2: position was already selected
else {
// 2.1: click on the same position
if (x == selectedX && y == selectedY) {
// unselect it
selectedX = -1;
selectedY = -1;
}
// 2.2: click on a different position
else {
// Move piece
Piece pieceToMove = board[selectedX][selectedY];
board[x][y] = new Piece(x, y, pieceToMove.getType(), pieceToMove.isWhite());
board[selectedX][selectedY] = null;
// reset the choose of position public boolean isHighlighted(int x, int y) {
selectedX = -1; for (int[] pos : highlightedPositions) {
selectedY = -1; if (pos[0] == x && pos[1] == y) {
return true;
}
}
return false;
}
//update the game /* utility methods */
incrementTurn(); private boolean isInBounds(int x, int y) {
clearConsole(); return x >= 0 && x < width && y >= 0 && y < height;
System.out.println(toString()); }
}
}
} 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;
}
}
public boolean isSelected(int x, int y) { private ArrayList<int[]> getValidMoves(Piece piece) {
return (x == selectedX && y == selectedY);//true if matching position ArrayList<int[]> moves = new ArrayList<>();
} int x = piece.getX();
int y = piece.getY();
/* saving-loading feature :*/ switch (piece.getType()) {
case Pawn:
int direction = piece.isWhite() ? -1 : 1;
int nextY = y + direction;
public String[] toFileRep() { // forward move
//TODO if (isInBounds(x, nextY) && board[x][nextY] == null) {
return null; moves.add(new int[]{x, nextY});
}
public Board(String[] array) { // double move from starting position
//TODO 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;
/* The following methods require more work ! */ 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;
public boolean isHighlighted(int x, int y) { case Bishop:
//TODO addLinearMoves(moves, x, y, piece, 1, 1);
return false; addLinearMoves(moves, x, y, piece, -1, 1);
} addLinearMoves(moves, x, y, piece, 1, -1);
addLinearMoves(moves, x, y, piece, -1, -1);
break;
public void undoLastMove() { case Queen:
//TODO 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;
public Board(Board board) { case Knight:
//TODO 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;
}
public void playMove(Move move) { /* saving-loading feature : */
//TODO public String[] toFileRep() {
// TODO
return null;
}
} public Board(String[] array) {
// TODO
}
public boolean isEmpty(int x, int newY) { /* additional functionality to implement later */
// TODO Auto-generated method stub public void undoLastMove() {
return false; // TODO
} }
public void playMove(Move move) {
// TODO
}
public Board(Board board) {
// TODO
}
} }