chess-system-java icon indicating copy to clipboard operation
chess-system-java copied to clipboard

Encerramento prematuro da partida sem um xeque-mate válido devido à promoção automática para rainha

Open luan-github opened this issue 2 years ago • 3 comments

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.

Captura de tela de 2023-06-15 19-14-04

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;
}

luan-github avatar Jun 15 '23 22:06 luan-github

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 avatar Jun 07 '24 13:06 silassefas1

@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;
	}
   // ...
}

dfeprado avatar Aug 16 '24 00:08 dfeprado

Criei um PR para isso: #9

dfeprado avatar Aug 16 '24 00:08 dfeprado