jhlywa / chess.js

A TypeScript chess library for chess move generation/validation, piece placement/movement, and check/checkmate/draw detection
BSD 2-Clause "Simplified" License
3.71k stars 892 forks source link

pgn parsing #153

Open kevinludwig opened 7 years ago

kevinludwig commented 7 years ago

A few comments based on my usage today. I would be willing to provide PR for any (although some of these are a rather large effort), assuming there is interest in chess.js having support for these use cases.

  1. It was rejecting PGN files because I had notated castling as "0-0" instead of "O-O" (e.g. zeros not upper case letter O). I checked the PGN spec and it turns out that upper case O is correct although I'll just say that these PGN files are accepted by SCID (and probably other parsers). I tried setting the sloppy flag but it made no difference.

  2. It also rejects symbols like "=" or "+/=". Again, I know this is not technically valid (its supposed to use NAG symbols like $10 and $14). But existing parsers like SCID allow this.

  3. It does not store the token that caused the error. I eventually realized I could do chess.pgn() to convert back to PGN whatever it had successfully parsed, and by extension, whatever the next token was is the one that caused the problem. It would be nice if I could just do chess.error() and get back something like {token: "0-0", at: 37, move: 7}, i.e. at character 37, move number 7, the token 0-0 was invalid. Then I could generate some kind of reasonable error message based on a parse error.

  4. Speaking of chess.pgn(), since the chess.load_pgn() function essentially throws everything away except the moves and the headers, it means that chess.load_pgn() and chess.pgn() are not reversible operations. I.e. it would be impossible to implement a PGN editor on top of this.

  5. It discards RAV, so it is not suitable for loading a PGN file that contains analysis, since all of the analysis in the RAV variations would be ditched. (Or, in my case, I wanted to use chess.js to validate a PGN file that is manually entered to ensure its syntactically correct, and it can't do this because it ignores RAV, so only the mainline variation is checked).

kevinludwig commented 7 years ago

Not sure if this is of interest, but https://github.com/kevinludwig/pgn-parser. This parses PGN into a javascript object, and keeps all the tokens associated with each move (and handles RAVs).

waltertamboer commented 6 years ago

Any update on this? I'd love to build a player like Chessbase has (e.g. https://en.chessbase.com/post/tactic-blog-oliver-reeh-29-12-17e). So showing the PGN next to my chessboard.

ngocdaothanh commented 6 years ago

I think that this library is better than https://github.com/kevinludwig/pgn-parser: https://github.com/shaack/cm-pgn

pgaskin commented 6 years ago

Note that to recreate the history for chess.history({verbose: true}) (including promotions, captures, castling, etc) which is lost after parsing a pgn, you can replay the moves (from calling history on the parsed chess object) one by one in another chess object. This almost completely fixes point 4 mentioned in the issue.