Encerramento prematuro da partida sem um xeque-mate válido devido à promoção automática para rainha
A promoção automática da rainha dentro da função 'performChessMove()' pode alterar as variáveis 'check' ou 'checkMate', fazendo com que o programa acuse xeque ou xeque-mate inexistentes quando o jogador promover seu peão para uma peça que não ataque o rei do oponente.
Para reproduzir o bug, basta iniciar a partida sem as peças que não são peões no lado do rei das peças negras e um peão branco na casa H7. No primeiro movimento, promova o peão branco para um bispo ou cavalo. A partida será encerrada com um xeque-mate inexistente.
Solução sugerida: Remover o código 'promoted = replacePromotedPiece("Q");' na função 'performChessMove()' e alterar o código 'return promoted;' na função 'replacePromotedPiece()' para algo como 'throw new IllegalStateException("No valid piece for promotion was provided.");'. Em seguida atualizar os valores das variáveis 'check', 'checkMate' e 'currentPlayer' antes de finalizar a função replacePromotedPiece():
public ChessPiece replacePromotedPiece(String type) {
if (promoted == null) {
throw new IllegalStateException("There is no piece to be promoted");
}
if (!type.equals("B") && !type.equals("N") && !type.equals("R") & !type.equals("Q")) {
throw new IllegalStateException("No valid piece for promotion was provided.");
}
Position pos = promoted.getChessPosition().toPosition();
Piece p = board.removePiece(pos);
piecesOnTheBoard.remove(p);
ChessPiece newPiece = newPiece(type, promoted.getColor());
board.placePiece(newPiece, pos);
piecesOnTheBoard.add(newPiece);
check = (testCheck(currentPlayer)) ? true : false;
if (testCheckMate(currentPlayer)) {
checkMate = true;
currentPlayer = opponent(currentPlayer);
}
return newPiece;
}
Esse problema eu resolvi no meu codigo trocando a peça padrão da promoção por um Knight, assim não da o xeque-mate automatico
@silassefas1 Ainda assim o bug pode acontecer, dependendo da posição do rei adversário.
@luan-github, o mais simples é adicionar uma nova chamada à ChessMatch.testCheck() dentro de ChessMatch.replacePromotedPiece()
class ChessMatch {
// ...
public ChessPiece replacePromotedPiece(String type) {
if (promoted == null) {
throw new IllegalStateException("There is no piece to be promoted");
}
if (!type.equals("B") && !type.equals("N") && !type.equals("R") & !type.equals("Q")) {
return promoted;
}
Position pos = promoted.getChessPosition().toPosition();
Piece p = board.removePiece(pos);
piecesOnTheBoard.remove(p);
ChessPiece newPiece = newPiece(type, promoted.getColor());
board.placePiece(newPiece, pos);
piecesOnTheBoard.add(newPiece);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// ADICIONE ESSA CHAMADA AQUI!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
check = (testCheck(opponent(newPiece.getColor()))) ? true : false;
return newPiece;
}
// ...
}
Criei um PR para isso: #9