taha1992's picture
Upload 695 files
2311079 verified
raw
history blame
5.49 kB
package com.tacticmaster.board;
import static java.lang.Math.abs;
import com.tacticmaster.puzzle.Puzzle;
import java.util.ArrayList;
import java.util.List;
public class Chessboard {
private final char[][] board;
private boolean whiteToMove;
private final List<int[]> moves;
private int movesIndex = 0;
private boolean firstMoveDone = false;
private final List<Character> promotions = new ArrayList<>();
public Chessboard(Puzzle puzzle) {
this.board = new char[8][8];
setupBoard(puzzle.fen());
var movesList = List.of(puzzle.moves().split(" "));
for (var move : movesList) {
if (move.length() == 5) {
promotions.add(move.charAt(4));
}
}
this.moves = convertMovesToCoordinates(movesList);
}
private List<int[]> convertMovesToCoordinates(List<String> moves) {
List<int[]> coordinates = new ArrayList<>();
for (String move : moves) {
int fromCol = move.charAt(0) - 'a';
int fromRow = 8 - (move.charAt(1) - '0');
int toCol = move.charAt(2) - 'a';
int toRow = 8 - (move.charAt(3) - '0');
if (!whiteToMove) {
fromRow = 7 - fromRow;
toRow = 7 - toRow;
}
coordinates.add(new int[]{fromRow, fromCol, toRow, toCol});
}
return coordinates;
}
private void setupBoard(String fen) {
String[] parts = fen.split(" ");
String[] rows = parts[0].split("/");
for (int i = 0; i < 8; i++) {
int col = 0;
for (char c : rows[i].toCharArray()) {
if (Character.isDigit(c)) {
int emptySquares = Character.getNumericValue(c);
for (int j = 0; j < emptySquares; j++) {
board[i][col++] = ' ';
}
} else {
board[i][col++] = c;
}
}
}
whiteToMove = parts[1].equals("b");//first move is made by opponent
if (!whiteToMove) {
for (int i = 0; i < 4; i++) {
var src = board[i];
board[i] = board[7 - i];
board[7 - i] = src;
}
}
}
public char[][] getBoard() {
return board;
}
public boolean isWhiteToMove() {
return whiteToMove;
}
public boolean isCorrectMove(int fromRow, int fromCol, int toRow, int toCol) {
if (movesIndex >= moves.size()) {
return false;
}
int[] move = moves.get(movesIndex);
return move[0] == fromRow && move[1] == fromCol && move[2] == toRow && move[3] == toCol;
}
public synchronized void makeFirstMove() {
if (firstMoveDone) {
return;
}
firstMoveDone = true;
makeNextMove();
}
public boolean isFirstMoveDone() {
return firstMoveDone;
}
public void makeNextMove() {
if (!firstMoveDone) {
return;
}
if (movesIndex >= moves.size()) {
return;
}
int[] move = moves.get(movesIndex);
movePiece(move[0], move[1], move[2], move[3]);
}
public boolean movePiece(int fromRow, int fromCol, int toRow, int toCol) {
if (Character.isUpperCase(board[fromRow][fromCol]) && Character.isUpperCase(board[toRow][toCol]) ||
Character.isLowerCase(board[fromRow][fromCol]) && Character.isLowerCase(board[toRow][toCol]) || board[fromRow][fromCol] == ' ') {
return false;
}
if ((board[fromRow][fromCol] == 'p' || board[fromRow][fromCol] == 'P') && board[toRow][toCol] == ' ' && fromCol != toCol) {
if (board[fromRow][fromCol] == 'p' && board[fromRow][toCol] == 'P' ||
board[fromRow][fromCol] == 'P' && board[fromRow][toCol] == 'p') {
board[fromRow][toCol] = ' ';
} else {
return false;
}
}
if (board[fromRow][fromCol] == 'K' && abs(fromCol - toCol) == 2 && fromRow == toRow) {
if (toCol == 6 && board[toRow][7] == 'R') {
board[toRow][5] = 'R';
board[toRow][7] = ' ';
} else if (toCol == 2 && board[toRow][0] == 'R') {
board[toRow][3] = 'R';
board[toRow][0] = ' ';
}
} else if (board[fromRow][fromCol] == 'k' && abs(fromCol - toCol) == 2 && fromRow == toRow) {
if (toCol == 6 && board[toRow][7] == 'r') {
board[toRow][5] = 'r';
board[toRow][7] = ' ';
} else if (toCol == 2 && board[toRow][0] == 'r') {
board[toRow][3] = 'r';
board[toRow][0] = ' ';
}
}
board[toRow][toCol] = board[fromRow][fromCol];
board[fromRow][fromCol] = ' ';
if (board[toRow][toCol] == 'P' && toRow == 0 || board[toRow][toCol] == 'P' && toRow == 7) {
board[toRow][toCol] = promotions.isEmpty() ? 'Q' : Character.toUpperCase(promotions.remove(0));
} else if (board[toRow][toCol] == 'p' && toRow == 0 || board[toRow][toCol] == 'p' && toRow == 7) {
board[toRow][toCol] = promotions.isEmpty() ? 'q' : Character.toLowerCase(promotions.remove(0));
}
movesIndex++;
return true;
}
public boolean solved() {
return movesIndex == moves.size();
}
}