alexobviously / bishop

A chess logic package for Dart with flexible variant support
https://pub.dev/packages/bishop
Other
19 stars 8 forks source link

ParsePgn cannot handle alternative move lines in Lichess Pgn files #73

Open Mercutio1243 opened 9 months ago

Mercutio1243 commented 9 months ago

First thing to note: PGN files are a real pain.

Anyways, I wanted to share that the PgnData parsePgn(String pgn) method struggles with the PGN export format of Lichess, when it contains autogenerated comments and especially alternative move lines.

The moves part of a "commented" Lichess Pgn looks like the following: 1. e4 { [%eval 0.2] [%clk 0:10:00] } 1... e5 { [%eval 0.18] [%clk 0:10:00] } 2. Nf3 { [%eval 0.21] [%clk 0:09:59] } 2... d6 { [%eval 0.64] [%clk 0:09:59] } { C41 Philidor Defense } 3. Bb5+ { [%eval 0.13] [%clk 0:09:47] } 3... Bd7 { [%eval 0.4] [%clk 0:09:55] } 4. Nc3 { [%eval 0.14] [%clk 0:09:37] } 4... Nc6?! { (0.14 → 0.80) Inaccuracy. Bxb5 was best. } { [%eval 0.8] [%clk 0:09:45] } (4... Bxb5 5. Nxb5 c6 6. Nc3 Nd7 7. d4 Ngf6 8. h3 Be7 9. a4) 5. O-O { [%eval 0.65] [%clk 0:09:27] } 5... Nd4 { [%eval 0.88] [%clk 0:09:24] } 6. Bxd7+ { [%eval 0.82] [%clk 0:08:52] } 6... Qxd7 { [%eval 0.83] [%clk 0:09:22] } 7. d3 { [%eval 0.32] [%clk 0:08:32] } 7... Qg4? { (0.32 → 1.67) Mistake. g6 was best. } { [%eval 1.67] [%clk 0:09:17] } (7... g6 8. Nxd4 exd4 9. Nd5 c6 10. Nf4 Bg7 11. a4 Ne7 12. Re1) 8. Nxd4 { [%eval 1.73] [%clk 0:08:21] } 8... Qxd1 { [%eval 1.65] [%clk 0:09:10] } 9. Rxd1 { [%eval 1.58] [%clk 0:08:18] } 9... exd4 { [%eval 1.6] [%clk 0:09:08] } 10. Nd5? { (1.60 → 0.26) Mistake. Nb5 was best. } { [%eval 0.26] [%clk 0:08:03] } (10. Nb5 Kd7 11. Nxd4 g6 12. c3 Bg7 13. Nc2 Re8 14. Re1 Ne7 15. g3 f5 16. Kg2 a5) 10... O-O-O { [%eval 0.31] [%clk 0:09:00] }

The alternative move line (4... Bxb5 5. Nxb5 c6 6. Nc3 Nd7 7. d4 Ngf6 8. h3 Be7 9. a4) is parsed as if it were regular moves, resulting to the following List of String pgnData.moves: [e4, e5, Nf3, d6, Bb5+, Bd7, Nc3, Nc6?!, (4..., Bxb5, Nxb5, c6, Nc3, Nd7, d4, Ngf6, h3, Be7, a4), O-O, Nd4, Bxd7+, Qxd7, d3, Qg4?, (7..., g6, Nxd4, exd4, Nd5, c6, Nf4, Bg7, a4, Ne7, Re1), Nxd4, Qxd1, Rxd1, exd4, Nd5?, (10., Nb5, Kd7, Nxd4, g6, c3, Bg7, Nc2,

I would assess this to be unwanted behavior. To avoid this, it seems, however, sufficient to just ignore information in regular brackets in PGN move data.

if (substr[0] == '(') { 
int variationEnd = substr.indexOf(')');
i += variationEnd + 1;
continue; 
}

Furthermore, I am not sure whether the parser / move objects get along with moves annotated by !, ?, +, !!, etc. so I have them replaced before adding them to moves: move = move.replaceAll(RegExp(r'[!?+]'), '');

Random example game: https://lichess.org/1BD1ORO4