Here is an open source code with all the rules of a classic chess game: https://github.com/cjortegon/basic-chess
You can start the project immediately after cloning the project (Android, iOS, Desktop and Web), or you can use the basic logic, which is located here: https://github.com/cjortegon/basic-chess/tree/master/libgdx/core / src / com / mountainreacher / chess / model
I based my decision on an algorithm with three points, the first moment is when the player selects a part from the board, and then when the destination of this piece is selected and finally when the piece reaches this position (given that this is an animated game, if not, you can combine steps 2 and 3).
The following code is implemented in Java. From the properties of the model class:
boolean turn; GenericPiece selected, conquest; ClassicBoard board; List<int[]> possibleMovements; int checkType;
The first method will process moments 1, 2 and the special moment of “conquest” (applies only to the workpiece):
public boolean onCellClick(int row, int column) { if (row == -1 && conquest != null) { checkType = 0; conquest.changeFigure(column); return true; } else if (selected != null) { if (possibleMovements != null) { for (int[] move : possibleMovements) { if (move[0] == row && move[1] == column) { // Move the PieceActor to the desired position if (selected.moveTo(row, column)) { turn = !turn; } break; } } } selected = null; possibleMovements = null; return true; } else { selected = board.getSelected(turn ? Piece.WHITE_TEAM : Piece.BLACK_TEAM, row, column); if (selected != null) { possibleMovements = new ArrayList<>(); possibleMovements.addAll(((GenericPiece) selected).getMoves(board, false)); // Checking the movements board.checkPossibleMovements(selected, possibleMovements); if (possibleMovements.size() == 0) { possibleMovements = null; selected = null; return false; } else { return true; } } } return false; }
And the following method will handle the third point (when the animation ends):
public void movedPiece(Piece piece) { Gdx.app.log(TAG, "movedPiece(" + piece.getType() + ")"); // Killing the enemy Piece killed = board.getSelectedNotInTeam(piece.getTeam(), piece.getRow(), piece.getColumn()); if (killed != null) { killed.setAvailable(false); } // Checking hacks GenericPiece[] threat = board.kingIsInDanger(); if (threat != null) { checkType = board.hasAvailableMoves(threat[0].getTeam()) ? CHECK : CHECK_MATE; } else { checkType = NO_CHECK; } // Checking castling if (piece.getFigure() == Piece.ROOK && ((GenericPiece) piece).getMovesCount() == 1) { Piece king = board.getSelected(piece.getTeam(), piece.getRow(), piece.getColumn() + 1); if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) { // Left Rook if (board.getSelected(piece.getRow(), piece.getColumn() - 1) == null) { king.moveTo(piece.getRow(), piece.getColumn() - 1); } } else { king = board.getSelected(piece.getTeam(), piece.getRow(), piece.getColumn() - 1); if (king != null && king.getFigure() == Piece.KING && ((GenericPiece) king).getMovesCount() == 0) { // Right Rook if (board.getSelected(piece.getRow(), piece.getColumn() + 1) == null) { king.moveTo(piece.getRow(), piece.getColumn() + 1); } } } } // Conquest else if (piece.getFigure() == Piece.PAWN && (piece.getRow() == 0 || piece.getRow() == board.getRows() - 1)) { conquest = (GenericPiece) piece; checkType = CONQUEST; } }
This code covers all the rules of classical chess, including: regular pieces, castling, check, checkmate and winning pawns.