bhlangonijr / chesslib

chess library for legal move generation, FEN/PGN parsing and more
Apache License 2.0
229 stars 80 forks source link

Support for SAN for Board #45

Closed dlbbld closed 3 years ago

dlbbld commented 3 years ago

When using MoveList one can use SAN like "e4" to specify moves, that is fine:

final MoveList moveList = new MoveList();
moveList.loadFromSan("1. e4 Nf6 2. e5 d5 3. Bc4 Nc6 4. Bf1 Nb8 5. Bc4 Nc6 6. Bf1 Nb8");

final Board board = new Board();
final Iterator<Move> moves = moveList.iterator();
while (moves.hasNext()) {
  board.doMove(moves.next());
}

But when using the Board, I don't see an option to specify moves using SAN. I can only specify moves using a notation like board.doMove(new Move("b1c3", Side.WHITE)) (attention this is not LAN notation, which would be Nb1c3). Using SAN board.doMove(new Move("Nc3", Side.WHITE)); throws an exception. It would be a great enhancement of the API if it would support SAN here, for that is where I usually specify the moves.

dlbbld commented 3 years ago

Any feedback here? Something like board.doMove("Nc3") would be very handy.

bhlangonijr commented 3 years ago

This is something easy to add I believe a good suggestion. I will add that in the next release.

dlbbld commented 3 years ago

Great, thanks. For coming back to the standard example with the pinned knight (#38) please think of not allowing the invalid SAN:

Board board = new Board();
board.loadFromFen("4k3/8/8/8/1b6/2N5/8/4K1N1 w - - 0 1");
board.doMove("Nge2"); // don't allow
board.doMove("Ne2"); // ok

You are not giving the user anything by allowing it, on the contrary. The user only specifies Nge2 in the following cases:

When not allowing you give the user to chance to correct his wrong assumptions. Of course, you can provide a method which allows it, but that should be clearly stated. Something like board.doMove(String san, boolean isStrict) with board.doMove(String san) calling board.doMove(san, true) would do the needful. I hope you get the idea.

safield commented 3 years ago

I have the same requirement.

I have a very limited use case though.

Take a san movetext of formate ""1. e4 Nf6 2. e5 d5 3. Bc4 Nc6 4. Bf1 Nb8 5. Bc4 Nc6 6. Bf1 Nb8"", and determine if it is white or blacks move.

bhlangonijr commented 3 years ago

hello @safield , you could just play the moves on the board and call Board#getSideToMove() at the end. e.g.:

    @Test
    public void testSide() throws MoveConversionException {

        final MoveList moves = new MoveList();
        moves.loadFromSan("1. e4 Nf6 2. e5 d5 3. Bc4 Nc6 4. Bf1 Nb8 5. Bc4 Nc6 6. Bf1 Nb8");

        final Board board = new Board();
        for (Move move : moves) {
            board.doMove(move);
        }
        System.out.println(board.getSideToMove());
        assertEquals(Side.WHITE, board.getSideToMove());
    }

or even:

    @Test
    public void testSide() throws MoveConversionException {

        final MoveList moves = new MoveList();
        moves.loadFromSan("1. e4 Nf6 2. e5 d5 3. Bc4 Nc6 4. Bf1 Nb8 5. Bc4 Nc6 6. Bf1 Nb8");

        final Board board = new Board();
        board.loadFromFen(moves.getFen());
        System.out.println(board.getSideToMove());
        assertEquals(Side.WHITE, board.getSideToMove());
    }

should get:

WHITE
SR-Lut3t1um commented 3 years ago

Is there any Update on this?

bhlangonijr commented 3 years ago

Fixed release 1.3.0