pgn-parser
pgn-parser copied to clipboard
Support '...' in variations
The following pgn strings can not be distinguished from each other in the result:
let blackVariationPgn = `1. e4 d5 (1... e5 {blackalt}) *`
let whiteVariationPgn = `1. e4 d5 (1 e5 {whitealt}) *`
Will return the same data and it is not possible to distinguish that in the white variation the intent was to move e5 instead of e4 and in the black variation the intent was to move e5 instead of d5. (I understand this example is contrived and doesn't make much sense, but my goal is to illustrate that I can't get the information needed because the '...' is ignored)
Output of moves[0] in black variation:
{ moveNumber: null,
notation:
{ fig: null,
strike: null,
col: 'd',
row: '5',
check: null,
promotion: null,
notation: 'd5' },
variations:
[ [ { moveNumber: 1,
notation:
{ fig: null,
strike: null,
col: 'c',
row: '5',
check: null,
promotion: null,
notation: 'c5' },
commentAfter: 'blackalt',
variations: [],
nag: null,
commentDiag: { comment: 'blackalt' },
turn: 'b' } ] ],
nag: null,
commentDiag: null,
turn: 'b' }
Output of moves[0] in white variation:
{ moveNumber: null,
notation:
{ fig: null,
strike: null,
col: 'd',
row: '5',
check: null,
promotion: null,
notation: 'd5' },
variations:
[ [ { moveNumber: 1,
notation:
{ fig: null,
strike: null,
col: 'c',
row: '5',
check: null,
promotion: null,
notation: 'c5' },
commentAfter: 'whitealt',
variations: [],
nag: null,
commentDiag: { comment: 'whitealt' },
turn: 'b' } ] ],
nag: null,
commentDiag: null,
turn: 'b' }
Notice that the variation turn
is 'b' when it should be 'w'
Well, you are right, and the reason is, that the parser is just a parser, that is not able to play chess. The pgn 1. e4 d5 (1 e5 {whitealt}) *
is just wrong. Why is that the case?
- e4 --> blacks turn
- d5 --> whites turn
-
(e5 {whitealt})
is not true. e5 must be an alternative to d5 that is the main line.
If you read the pgn spec carefully, you will see that the dots between move number and move are not significant, they are just ignored at the end. See the relevant part of the spec.
That means that both were parsed the same, because from the notation, they are the same. If you want to have a different move order, something like 1. e4 d5 (1... e6 2. e5)
is possible and gives what you want. And yes, I could remove all dots and all move numbers, so e4 d5 (e6 e5)
gives at the end the same result (perhaps with missing move numbers). The reader then corrects that, if necessary.
Thanks for reply, apologies for the poor example. Updated example:
A: 1. e4 e6 2. d4 d6 (2 e5) B: 1. e4 e6 2. d4 d6 (2... e5)
Without knowing that the '...' was in the brackets it is not possible to know if e5 refers to a white move or a black move. You would have to parse the whole branch to determine if it was correct or not, and even then there is a chance that both interpretation produce a valid but different output.
Also, in the case of A
the parser will return a result that says [notation: 'e5', turn: 'b']
which is an incorrect parse since e5 is a white move.

Sorry, you did not understand my point. The parentheses with the moves in it are all the time a variation to the move directly before the parentheses. So in A, e5 is the variation to the black move d6 (which is valid, but a poor move). And for B, it is the same, variation to the black move. So the parser is correct, e5 is a black move in both examples, and it does not depend on the ...
. So the parsing only depends on the order of the moves, and not on numbers and / or dots. Never!
Look at the grammar with the 5 lines
moveNumber
= num:integer whiteSpace* dot* { return num; }
dot = "."
Translation: read any number of white space and dots after the move number, and just return the number. The move number is the number given in the notation, not the real half-move, and may be ignored or corrected later by the parser or reader.
So sorry, the notation (with stripped numbers and dots) will be the same, and therefore the parse result.