adding all the movements possibility and highlighting the squares.
This commit is contained in:
parent
18c29cd2df
commit
dc8c3d1faa
|
|
@ -3,56 +3,56 @@ package backend;
|
||||||
import java.util.ArrayList;
|
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 selectedY = -1;
|
|
||||||
|
|
||||||
private int turnNumber = 0; //track current turn
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private Piece[][] board; //2D array chess board
|
|
||||||
|
|
||||||
public Board(int colNum, int lineNum) {
|
private int selectedX = -1; // negative value means impossible x and y so unselected
|
||||||
this.width = colNum;
|
private int selectedY = -1;
|
||||||
this.height = lineNum;
|
|
||||||
this.board = new Piece[width][height]; //first empty board
|
|
||||||
clearConsole();
|
|
||||||
System.out.println(toString()); //print the chess at the beginning of the game
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth() {
|
private int turnNumber = 0; // track current turn
|
||||||
return width;
|
private int width;
|
||||||
}
|
private int height;
|
||||||
|
private Piece[][] board; // 2D array chess board
|
||||||
|
private ArrayList<int[]> highlightedPositions = new ArrayList<>(); // list of valid positions to highlight
|
||||||
|
|
||||||
public int getHeight() {
|
public Board(int colNum, int lineNum) {
|
||||||
return height;
|
this.width = colNum;
|
||||||
}
|
this.height = lineNum;
|
||||||
|
this.board = new Piece[width][height]; // first empty board
|
||||||
// new piece on the board at x,y
|
clearConsole();
|
||||||
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
System.out.println(toString()); // print the chess at the beginning of the game
|
||||||
board[x][y] = new Piece(x, y, type, isWhite);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isTurnWhite() {
|
|
||||||
if (turnNumber % 2 == 0) { // even turns including O are white's ones
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else { // same reasoning, odd turns are black's ones
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTurnNumber() { //theses classes change the turn and the increment one solve a problem of infinite loop
|
|
||||||
return turnNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementTurn() {
|
|
||||||
turnNumber++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//set up the chess board taking it as a matrix
|
public int getWidth() {
|
||||||
public void populateBoard() {
|
return width;
|
||||||
// Black
|
}
|
||||||
|
|
||||||
|
public int getHeight() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new piece on the board at x,y
|
||||||
|
public void setPiece(boolean isWhite, PieceType type, int x, int y) {
|
||||||
|
board[x][y] = new Piece(x, y, type, isWhite);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTurnWhite() {
|
||||||
|
if (turnNumber % 2 == 0) { // even turns including 0 are white's ones
|
||||||
|
return true;
|
||||||
|
} else { // same reasoning, odd turns are black's ones
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTurnNumber() { // these classes change the turn and the increment one solves a problem of infinite loop
|
||||||
|
return turnNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementTurn() {
|
||||||
|
turnNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set up the chess board taking it as a matrix
|
||||||
|
public void populateBoard() {
|
||||||
|
// 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() {
|
|
||||||
for(int x = 0; x < width; x++) {
|
|
||||||
for(int y = 0; y < height; y++) {
|
|
||||||
board[x][y] = null; //each position become empty
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void clearConsole() {
|
public void cleanBoard() {
|
||||||
for(int i = 0; i < 50; i++) {
|
for (int x = 0; x < width; x++) {
|
||||||
System.out.println(); // Print 50 empty lines to "clear" the console
|
for (int y = 0; y < height; y++) {
|
||||||
}
|
board[x][y] = null; // each position becomes empty
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public String toString() {
|
}
|
||||||
StringBuilder str = new StringBuilder();
|
|
||||||
|
|
||||||
str.append(" A B C D E F G H\n"); //columns letter at the top
|
|
||||||
|
|
||||||
// representation of the rows
|
|
||||||
for(int y = 0; y < height; y++) {
|
|
||||||
str.append(8 - y).append(" "); // row number on the left
|
|
||||||
|
|
||||||
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; //one character
|
|
||||||
|
|
||||||
switch(piece.getType()) { //switch function solve the problem of too many if-else
|
|
||||||
case King: pieceChar = 'K'; break; //case is reading in king and break stop the switch function
|
|
||||||
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; //solve an issue of unresolved compilation and act as a safety net
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make black pieces in lowercase
|
|
||||||
if(!piece.isWhite()) {
|
|
||||||
pieceChar = Character.toLowerCase(pieceChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
str.append(pieceChar).append(" "); //gives structure to the output
|
|
||||||
}
|
|
||||||
}
|
|
||||||
str.append("\n"); //change of row
|
|
||||||
}
|
|
||||||
|
|
||||||
// Additional infos for a proper ouput
|
|
||||||
str.append("Turn ").append(getTurnNumber()).append(": "); //turnnumber
|
|
||||||
str.append(isTurnWhite() ? "White" : "Black"); //color's turn
|
|
||||||
|
|
||||||
return str.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
//list the placement of the pieces on the board
|
|
||||||
public ArrayList<Piece> getPieces() {
|
|
||||||
ArrayList<Piece> pieces = new ArrayList<>();
|
|
||||||
//collect infos for the 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//user click on the board
|
private void clearConsole() {
|
||||||
public void userTouch(int x, int y) {
|
for (int i = 0; i < 50; i++) {
|
||||||
// 1: no position was previously selected
|
System.out.println(); // Print 50 empty lines to "clear" the console
|
||||||
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
|
|
||||||
selectedX = -1;
|
|
||||||
selectedY = -1;
|
|
||||||
|
|
||||||
//update the game
|
|
||||||
incrementTurn();
|
|
||||||
clearConsole();
|
|
||||||
System.out.println(toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSelected(int x, int y) {
|
|
||||||
return (x == selectedX && y == selectedY);//true if matching position
|
|
||||||
}
|
|
||||||
|
|
||||||
/* saving-loading feature :*/
|
|
||||||
|
|
||||||
public String[] toFileRep() {
|
public String toString() {
|
||||||
//TODO
|
StringBuilder str = new StringBuilder();
|
||||||
return null;
|
str.append(" A B C D E F G H\n"); // columns letter at the top
|
||||||
}
|
|
||||||
|
|
||||||
public Board(String[] array) {
|
// representation of the rows
|
||||||
//TODO
|
for (int y = 0; y < height; y++) {
|
||||||
|
str.append(8 - y).append(" "); // row number on the left
|
||||||
|
|
||||||
}
|
for (int x = 0; x < width; x++) {
|
||||||
|
if (board[x][y] == null) {
|
||||||
/* The following methods require more work ! */
|
str.append("- "); // empty positions
|
||||||
|
} else {
|
||||||
|
// convert each piece of both color into a character
|
||||||
|
Piece piece = board[x][y];
|
||||||
|
char pieceChar;
|
||||||
|
|
||||||
public boolean isHighlighted(int x, int y) {
|
switch (piece.getType()) { // switch function avoids too many if-else
|
||||||
//TODO
|
case King: pieceChar = 'K'; break;
|
||||||
return false;
|
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
|
||||||
|
}
|
||||||
|
|
||||||
public void undoLastMove() {
|
// Make black pieces in lowercase
|
||||||
//TODO
|
if (!piece.isWhite()) {
|
||||||
|
pieceChar = Character.toLowerCase(pieceChar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Board(Board board) {
|
str.append(pieceChar).append(" "); // gives structure to the output
|
||||||
//TODO
|
}
|
||||||
|
}
|
||||||
|
str.append("\n"); // change of row
|
||||||
|
}
|
||||||
|
|
||||||
}
|
// Additional infos for a proper output
|
||||||
|
str.append("Turn ").append(getTurnNumber()).append(": ");
|
||||||
public void playMove(Move move) {
|
str.append(isTurnWhite() ? "White" : "Black");
|
||||||
//TODO
|
|
||||||
|
|
||||||
}
|
return str.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isEmpty(int x, int newY) {
|
// list the placement of the pieces on the board
|
||||||
// TODO Auto-generated method stub
|
public ArrayList<Piece> getPieces() {
|
||||||
return false;
|
ArrayList<Piece> pieces = new ArrayList<>();
|
||||||
}
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// user clicks on the board
|
||||||
|
public void userTouch(int x, int y) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
Piece pieceToMove = board[selectedX][selectedY];
|
||||||
|
board[x][y] = new Piece(x, y, pieceToMove.getType(), pieceToMove.isWhite());
|
||||||
|
board[selectedX][selectedY] = null;
|
||||||
|
incrementTurn();
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset selection
|
||||||
|
selectedX = -1;
|
||||||
|
selectedY = -1;
|
||||||
|
highlightedPositions.clear();
|
||||||
|
clearConsole();
|
||||||
|
System.out.println(toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelected(int x, int y) {
|
||||||
|
return (x == selectedX && y == selectedY); // true if matching position
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isHighlighted(int x, int y) {
|
||||||
|
for (int[] pos : highlightedPositions) {
|
||||||
|
if (pos[0] == x && pos[1] == y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* utility methods */
|
||||||
|
private boolean isInBounds(int x, int y) {
|
||||||
|
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) {
|
||||||
|
ArrayList<int[]> moves = new ArrayList<>();
|
||||||
|
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 : */
|
||||||
|
public String[] toFileRep() {
|
||||||
|
// TODO
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(String[] array) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/* additional functionality to implement later */
|
||||||
|
public void undoLastMove() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playMove(Move move) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board(Board board) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue