capicue / pgn Goto Github PK
View Code? Open in Web Editor NEWA chess file parser for ruby
License: MIT License
A chess file parser for ruby
License: MIT License
PGN doesn't seem to like this file:
(which I lost, because I did a retarded Bishop sacrifice, iirc)
[Event "---"]
[Site "---"]
[Date "---"]
[Round "---"]
[White "Ruben De Smet"]
[Black "---"]
[Result "*"]
[ECO "D52"]
[WhiteElo ""]
[BlackElo ""]
[TimeControl ""]
[Time ""]
[PlyCount "60"]
[EventDate ""]
[Annotator ""]
1. d4 e6 2. c4 d5 3. Nc3 c6 4. Nf3 Nf6 5. Bg5 Nbd7 6. e3 Qa5 7. a3 (7. cxd5
Nxd5 8. Rc1 {Analyzer's primary variation: 8... Bb4 9. Qd2 e5 10. e4 Nxc3 11.
bxc3 Ba3 12. Rb1 h6 13. Be3 O-O 14. Bc4 exd4 15. cxd4 Qxd2+ 16. Nxd2 a5 17. O-O
b5 18. Be2 Rd8 19. d5 cxd5 20. exd5 Nc5 21. Rxb5 Rxd5 {+0.30/21} }) 7... Ne4 8.
Rc1 Nxg5 9. Nxg5 dxc4 10. Bxc4 Qxg5 11. O-O Nf6 12. Qf3 Qg4 13. Qxg4 Nxg4 14.
Ne4 Be7 15. b4 O-O 16. Rce1 Nf6 17. Ng5 ({Better is} 17. Nxf6+ gxf6 {-4.08/31}
(17... Bxf6) (17... gxf6)) (17. Nxf6+) 17... h6 18. Nf3 Ne4 ({Treatening} 18...
-- 19. Ra1 b5 {-4.05/31}) ({Better is} 18... a5 19. Be2 {-4.55/31}) 19. Bd3 Ng5
({Treatening} 19... -- 20. Bxe4 a5 21. Rb1 axb4 22. axb4 Ra4 23. b5 c5 24. Bc2
Ra3 25. Rfc1 cxd4 26. Nxd4 Rd8 27. b6 Ra5 28. Be4 Rc5 29. f4 g5 30. g3 f5 31.
Bg2 Kf7 32. Bf3 g4 33. Bg2 Kf6 34. Ra1 Kf7 35. Rab1 {0.00/36}) ({Better is}
19... Nc3 20. Ra1 {-4.02/33}) 20. Ne5 Bd6 21. Nc4 Rd8 22. f4 Nh7 23. Na5 Bc7
24. Nb3 ({Better is} 24. Bc4 Nf6 25. Rb1 g5 26. g3 gxf4 27. gxf4 Kf8 28. Rfc1
Ng4 29. Rc3 Ke7 30. Rb2 Bb6 31. Nb3 Nf6 32. Rcc2 Rg8+ 33. Rg2 Rxg2+ 34. Kxg2 a5
35. bxa5 Bxa5 36. Nxa5 Rxa5 37. Rb3 b5 38. Be2 Ra4 39. Rc3 Bd7 40. Bf3
{-3.58/30}) 24... Nf6 25. e4 ({Better is} 25. Ra1 a5 26. Kf2 Ng4+ 27. Ke2 Nxh2
28. Rfc1 Bb6 29. Nc5 axb4 30. axb4 Rxa1 31. Rxa1 Ng4 32. b5 cxb5 33. Bxb5 Nf6
34. Ra8 Nd5 35. Ra3 Bc7 36. Nd3 g6 37. Bc4 Kg7 38. Kf3 h5 39. Ra1 b6 40. Kf2
Nf6 41. Ra7 Ng4+ 42. Ke2 Bd6 {-4.21/28}) 25... Bd7 26. e5 Nd5 27. f5 exf5 28.
Bxf5 ({Treatening} 28. -- Ne7 29. Bc2 Be6 30. Nc5 Rxd4 31. Nxe6 fxe6 32. Rd1
Rxd1 33. Rxd1 Nd5 34. Bb3 Bxe5 35. a4 Kf7 36. b5 c5 37. Kf2 Bxh2 38. Re1 Rd8
39. a5 Nf4 40. Rd1 Rxd1 41. Bxd1 c4 42. g3 Nd3+ 43. Kg2 {+5.66/25}) ({Better
is} 28. Nc5 Bb6 {-4.87/28}) 28... Bxf5 29. Rxf5 Bb6 ({Treatening} 29... -- 30.
Nc5 Bb6 31. Rff1 Re8 32. Rf2 f6 33. Rfe2 fxe5 34. Rxe5 Rxe5 35. Rxe5 a5 36.
bxa5 Bxa5 37. Nxb7 Bc3 38. Re4 Nf6 39. Re6 Bxd4+ 40. Kf1 Rxa3 41. Rxc6 Ng4 42.
Rc8+ Kh7 43. Ke2 Nxh2 44. Rc4 Bg1 45. Re4 Kg6 46. Nd6 Ra2+ 47. Kd3 Rxg2
{-4.52/25}) ({Better is} 29... a5 30. Nxa5 {-5.43/26}) 30. Ref1 ({Better is}
30. Rf3 a5 {-4.81/28}) 30... Ne3 *
(I censored black's name, the date and the tournament)
I'm still trying to figure out why; but I get this:
Error: Unmatched input "}) 7... Ne4 8.\nRc1 Nxg5 [SNIP]" on line 20
(I cut it at [SNIP], it just dumps the rest of the file)
To me, this looks like PGN doesn't like pgn
files with variations halfway a move (move 7., in this case, first line. Long variation that lasts until line 20), but I'm not sure. I'm trying to read the parser spec atm. If I can fix it, I'll make a PR. Any help is appreciated though; reading a parser spec is not so easy :')
I'm trying to use this library to automatically get my chess games on my blog, using Jekyll!
This file was created by PyChess, which I use to enter my games.
Hey,
First nice gem!
Secondly, I had to include require 'io/console'
to make it work.
Hi,
Is there a hidden method somewhere not mentioned that parses a PGN with timestamps included? I noticed that the method in the README doesn't work for it, and the example doesn't include timestamps.
I could always just remove the timestamps manually with regex before parsing, but I'm wondering if the library might have an option for it already.
Thanks for your time. Cool library btw. There is no similarly simple and powerful python equivalent.
Error: Parse error: expected :game_termination but got "(" on line 52.
Kf6 {+2.00/28} ) 25. Ne4 {[%eval 1.84/34]} {[%eval 1.84/34]} ( {Threatening}
... ^ ... occurred here
I don't really get what's happening here, got an idea?
Hi!
The gem (v0.2.0) seems unable to parse PGNs without headers, which seem optional.
Does not parse:
1. e4 a6 2. Bc4 a5 3. Ne2 a4 4. O-O Ra7
5. e5 f5 6. exf6 a5 0-1
Error:
Whittle::ParseError: Parse error: expected one of :$end, "[" but got :move_number_indication on line 1.
1. e4 a6 2. Bc4 a5 3. Ne2 a4 4. O-O Ra7
^ ... occurred here
Parses:
[Event "Live Chess"]
1. e4 a6 2. Bc4 a5 3. Ne2 a4 4. O-O Ra7
5. e5 f5 6. exf6 a5 0-1
I downloaded some games from lichess, and got this error:
/home/frank/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/whittle-0.0.8/lib/whittle/parser.rb:282:in `error': Parse error: expected :game_termination but got :tag_name on line 277080. (Whittle::ParseError)
1. e4 Nc6 2. Nf3 Nf6 3. Nc3 d5 4. exd5 Nxd5 5. Bc4 e6 6. d3 Bb4 7. Bd2 Bxc3 8. bxc3 P@g4 9. P@h6 gxf3 10. hxg7 Rg8 11. Bxd5 exd5 12. Qxf3 Qe7+ 13. Be3 B@f6 14. P@d4 Rxg7 15. P@h6 Rg8 1
... ^ ... occurred here
from /home/frank/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/whittle-0.0.8/lib/whittle/parser.rb:231:in `block (2 levels) in parse'
from /home/frank/.rbenv/versions/3.1.0/lib/ruby/gems/3.1.0/gems/whittle-0.0.8/lib/whittle/parser.rb:207:in `loop'
The chess.pgn library from Python has no problems with it.
After 1. e4, the fen should be rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
Instead it is rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 0
The following PGN appears in the http://chessgames.com archive of games played in 2014:
[Event "Bunratty Masters"]
[Site "Bunratty Co. Clare, Ireland"]
[Date "2014.02.08"]
[EventDate "2014.??.??"]
[Round "3"]
[Result "1-0"]
[White "Drahoslav Stejskal"]
[Black "Brendan Lyons"]
[ECO "B01"]
[WhiteElo "2129"]
[BlackElo "1888"]
[PlyCount "60"]
1. e4 d5 2. exd5 Nf6 3. Bb5+ Bd7 4. Be2 Bf5 5. Nf3 Nxd5 6. c3
e6 7. d4 Bd6 8. Bg5 f6 9. Be3 Nf4 10. Bxf4 Bxf4 11. Nh4 Be4
12. Bc4 Qd6 13. Qg4 Nd7 14. Qxe6+ Qxe6 15. Bxe6 Bc6 16. a4
O-O-O 17. O-O Bg5 18. Nf3 Bxf3 19. gxf3 Rhe8 20. Bc4 Nb6
21. Bd3 g6 22. Na3 c5 23. Nb5 Re7 24. dxc5 Nd7 25. Bc4 Nxc5
26. Rad1 Bf4 27. b4 Nd7 28. Nd6+ Kc7 29. Ne4 f5 30. Ng3 {...}
1-0
Trying to parse this with PGN raises the following error:
Whittle::UnconsumedInputError: Unmatched input "{...}\n1-0" on line 19
from /Users/greg/.rvm/gems/ruby-1.9.3-p362/gems/whittle-0.0.8/lib/whittle/parser.rb:251:in `block in lex'
from /Users/greg/.rvm/gems/ruby-1.9.3-p362/gems/whittle-0.0.8/lib/whittle/parser.rb:250:in `tap'
from /Users/greg/.rvm/gems/ruby-1.9.3-p362/gems/whittle-0.0.8/lib/whittle/parser.rb:250:in `lex'
from /Users/greg/.rvm/gems/ruby-1.9.3-p362/gems/whittle-0.0.8/lib/whittle/parser.rb:204:in `parse'
from /Users/greg/.rvm/gems/ruby-1.9.3-p362/gems/pgn-0.0.6/lib/pgn.rb:23:in `parse'
from (irb):5
from /Users/greg/.rvm/rubies/ruby-1.9.3-p362/bin/irb:16:in `<main>'
I think that "{...}" is meant to indicate an incomplete move log. Even though it doesn't appear in any PGN documentation that I can find. Not sure what the best policy in parsing is here, however the current result where I'm PGN crashes midway through parsing this archive of ~10,000 games and forces me to write code that splits up the games myself with a regex and iterates over the resulting strings in order to pass them one-by-one into PGN to rescue just the one that crashes is probably not the optimal situation.
Hi!
The gem (v0.2.0) seems unable to parse incomplete games. Adding a result portion solves this.
Parses:
[Event "Live Chess"]
[Site "Chess.com"]
[Date "2017.11.12"]
[White "piguik"]
[Black "Epigene"]
[Result "0-1"]
[ECO "B54"]
[WhiteElo "1325"]
[BlackElo "1375"]
[TimeControl "300"]
1. e4 a6 2. Bc4 a5 3. Ne2 a4 4. O-O Ra7
5. e5 f5 6. exf6 a5 0-1
Does not parse:
[Event "Live Chess"]
[Site "Chess.com"]
[Date "2017.11.12"]
[White "piguik"]
[Black "Epigene"]
[Result "0-1"]
[ECO "B54"]
[WhiteElo "1325"]
[BlackElo "1375"]
[TimeControl "300"]
1. e4 a6 2. Bc4 a5 3. Ne2 a4 4. O-O Ra7
5. e5 f5 6. exf6 a5
'FEN' tag is ignored, parser always start from initial position.
Hi again!
I find myself in need of obtaining check and checkmate status information from chess positions.
It would be great if I could do
fen = PGN::FEN.new("r1bk3r/p2pBpNp/n4n2/1p1NP2P/6P1/3P4/P1P1K3/q5b1 b - - 1 22")
position = fen.to_position
position.features #=> {side_in_check: "white"} or {side_in_checkmate: "black"} etc.
Seeing how this gem implements play logic, I imagine such functionality either exists or you could point me in the direction of writing it up.
Thanks!
This is an awesome gem! However, it doesn't support the PGN format fully; it doesn't even support the strict "export" format. I see that the grammar rules for comments and variations are commented out, and I'm assuming that's because Whittle, as a LALR parser, doesn't handle the ambiguity. Did you consider using something like Parslet or Citrus instead? Why didn't you end up with that?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.