Skip to content

Commit

Permalink
Fixes exception in AbstractPGNWriter.getPGN if history contains bad move
Browse files Browse the repository at this point in the history
  • Loading branch information
fathzer committed Dec 5, 2024
1 parent 3e53d9d commit 99893a6
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 9 deletions.
10 changes: 8 additions & 2 deletions src/main/java/com/fathzer/jchess/pgn/AbstractPGNWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
import com.fathzer.games.MoveGenerator;
import com.fathzer.games.Status;
import com.fathzer.jchess.fen.FENUtils;
import com.fathzer.jchess.pgn.MoveAlgebraicNotationBuilder.IllegalMoveException;

public abstract class AbstractPGNWriter<M, B extends MoveGenerator<M>> {
//TODO why DATE_FORMAT is public
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy.MM.dd");

private static record ResultAndMoves (Status status, List<String> anMoves) {
Expand Down Expand Up @@ -98,7 +98,13 @@ private ResultAndMoves getMovesAndResult(GameHistory<M, B> history) {
} else {
buf.append(" ");
}
buf.append(getAlgebraicNotation(move, board));
String moveString;
try {
moveString = getAlgebraicNotation(move, board);
} catch (IllegalMoveException e) {
moveString = "{ Illegal move "+e.getMoveRepresentation()+" }";
}
buf.append(moveString);
}
if (buf.length()!=0) {
result.add(buf.toString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@
/** A class to get <a href="https://en.wikipedia.org/wiki/Algebraic_notation_(chess)">Algebraic notation</a> of moves.
*/
public class MoveAlgebraicNotationBuilder {

public class IllegalMoveException extends IllegalArgumentException {
private static final long serialVersionUID = 1L;
private final String moveRepresentation;

private IllegalMoveException(String message, String moveRepresentation) {
super(message);
this.moveRepresentation = moveRepresentation;
}

public String getMoveRepresentation() {
return this.moveRepresentation;
}
}

private String checkSymbol = "+";
private String checkmateSymbol = "#";
private char captureSymbol = 'x';
Expand All @@ -28,11 +43,11 @@ public class MoveAlgebraicNotationBuilder {
private boolean playMove;

/** Gets the algebraic notation of a move.
* <br>If sideEffect attribute is true, move is played on the board
* <br>If playMove attribute is true, move is played on the board
* @param board The board before the move occurs
* @param move The move to encode
* @return The move in algebraic notation
* @throws IllegalArgumentException if move is invalid
* @throws IllegalMoveException if move is invalid
*/
public String get(Board<Move> board, Move move) {
final StringBuilder builder = new StringBuilder();
Expand All @@ -42,7 +57,8 @@ public String get(Board<Move> board, Move move) {
final int to = move.getTo();
final List<Move> candidates = StreamSupport.stream(state.spliterator(),false).filter(m -> m.getTo()==to).toList();
if (!checkValidMove(move, candidates)) {
throw new IllegalArgumentException("Move "+moveToString(move, board)+" is not valid");
final String moveString = moveToString(move, board).toString();
throw new IllegalMoveException("Move "+moveString+" is not valid", moveString);
}
final Piece moved = board.getPiece(move.getFrom());
final Castling castling = moved.getKind()==KING ? board.getCastling(move.getFrom(), to) : null;
Expand All @@ -58,7 +74,7 @@ public String get(Board<Move> board, Move move) {
return builder.toString();
}

private CharSequence moveToString(Move move, Board<Move> board) {
private static CharSequence moveToString(Move move, Board<Move> board) {
final StringBuilder buf = new StringBuilder();
final CoordinatesSystem cs = board.getCoordinatesSystem();
buf.append(cs.getAlgebraicNotation(move.getFrom()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.fathzer.jchess.MoveBuilder;
import com.fathzer.jchess.Piece;
import com.fathzer.jchess.fen.FENUtils;
import com.fathzer.jchess.pgn.MoveAlgebraicNotationBuilder.IllegalMoveException;

class MoveAlgebraicNotationTest implements MoveBuilder {

Expand Down Expand Up @@ -57,11 +58,11 @@ void test() {
// Illegal moves
final Board<Move> board2 = (Board<Move>) board.fork();
final Move move2 = move(board, "f3","g2");
assertThrows(IllegalArgumentException.class, () -> san.get(board2, move2));
assertThrows(IllegalMoveException.class, () -> san.get(board2, move2));

final Board<Move> board3 = FENUtils.from("2kr3r/Rppppppp/8/8/2P1Q2Q/1P3K2/2PP2PP/RNB4Q w - - 0 1");
final Move move3 = move(board, "a7","a8", Piece.WHITE_QUEEN);
assertThrows(IllegalArgumentException.class, () -> san.get(board3, move3));
assertThrows(IllegalMoveException.class, () -> san.get(board3, move3));
}

@Test
Expand Down
16 changes: 15 additions & 1 deletion src/test/java/com/fathzer/jchess/pgn/PGNWriterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.junit.jupiter.api.Test;

import com.fathzer.games.GameHistory;
import com.fathzer.games.GameHistory.TerminationCause;
import com.fathzer.games.Status;
import com.fathzer.jchess.Board;
import com.fathzer.jchess.GameBuilders;
import com.fathzer.jchess.Move;
Expand All @@ -34,7 +36,6 @@ void test() {
.setEvent("A competition").setRound(5L).setSite("there").setDate(LocalDate.of(2020, 1, 8))
.build();
final List<String> pgn = writer.getPGN(headers, history);
System.out.println(pgn); //TODO
assertEquals("[Event \"A competition\"]", pgn.get(0));
assertEquals("[Site \"there\"]", pgn.get(1));
assertEquals("[Date \"2020.01.08\"]", pgn.get(2));
Expand Down Expand Up @@ -79,4 +80,17 @@ void nonStandardStartFENTest() {
final var fenIndex = pgn.indexOf("[FEN \"1r2k1r1/ppp1pp2/3p2pp/5bn1/P7/2N2B2/1PPPPP2/RR2K3 w Q - 4 11\"]");
assertTrue(fenIndex>setUpIndex);
}

@Test
void illegalMoveTest() {
final var board = FENUtils.from(FENUtils.NEW_STANDARD_GAME);
final var history = new GameHistory<>(board);
history.add(move(board, "e2", "e4"));
final Move illagalMove = move(board, "a1","a1");
assertFalse(history.add(illagalMove));
history.earlyEnd(Status.WHITE_WON, TerminationCause.RULES_INFRACTION);
final var writer = new PGNWriter();
final List<String> pgn = writer.getPGN(new PGNHeaders.Builder().build(), history);
assertEquals("1. e4 { Illegal move a1-a1 }", pgn.get(pgn.size()-1));
}
}

0 comments on commit 99893a6

Please sign in to comment.