kevinludwig / pgn-parser Goto Github PK
View Code? Open in Web Editor NEWParse PGN files using peg.js
License: MIT License
Parse PGN files using peg.js
License: MIT License
The chess.com analysis tool puts ±, ∓, and = characters into its pgn text when computer analysis is included. These characters are not contained within move comments. This causes parsing to fail.
Below is example pgn text from chess.com. Note the ± character in move 8:
1. e4 d5 2. exd5 Qxd5 3. Nc3 Qa5 4. Nf3 Nf6 5. Bc4 e6 6. d3 Bb4 7. Bd2 O-O 8. a3
Bd6? ± {MISTAKE (+3.05) Critical mistake.} ({(+1.06) The best move was} 8...
Bxc3 9. Bxc3 Qf5 *
I'm not sure if this usage of the ±, ∓, and = characters is normal in pgn, but I think it would be good for this package to be able to handle all chess.com pgn strings.
I'm happy to work on a pull request to fix this, but I'm not sure how those characters should be handled. Any opinions on that? Maybe the character should be prepended to the comment that follows it?
I have tried to parse this pgn :
[Event "?"]
[Site "?"]
[Date "2022.04.11"]
[Round "?"]
[White "Sistema Colle"]
[Black "Defensa india de rey"]
[Result "*"]
[ECO "A70"]
[Annotator "sky10p"]
[PlyCount "26"]
[SourceVersionDate "2022.04.11"]
but it's thrown this error:
Expected " ", """, "\r", "\t", or "\x0C" but "\n" found.
Hi,
nice library! Unfortunately %cal and %cls (arrows and square highlighting on the chess board) information is currently not parsed and creates an error.
Example (from https://lichess.org/study/D6DfYHZe):
{ [%csl Gf3,Gc6][%cal Gd2d4] }
1. e4 { this is a comment } { [%csl Gd5,Gf5][%cal Ge4d5,Ge4f5] } *
Also could you add a license to the project so others (like me :) ) could use it?
The parser ignores comments with accented characters.
Example pgn:
[Event ""]
[Site ""]
[Date "????.??.??"]
[Round ""]
[White ""]
[Black ""]
[Result "*"]
1.e4 e5 2.f4 {A à E é I î O ô U ù Y} *
The comment is parsed as A E I O U Y
.
I've created a pull request to add typescript declarations to the DefinitelyTyped repo. Let me know if you see anything wrong with the type declaration. Thanks!
Pawn promotion(for example c8Q) doesn't work now.
peg$SyntaxError: Expected " ", "!!", "!", "!?", "#", "+", "=", "?!", "?", "??", "\n", "\r", "\t", or "\x0C" but "Q" found.
target pgn:
[Event "Altibox Norway Chess"]
[Site "chess24.com"]
[Date "2019.06.04"]
[Round "2"]
[White "Mamedyarov, Shakhriyar"]
[Black "Caruana, Fabiano"]
[Result "1-0"]
[Board "2"]
[WhiteElo "2774"]
[WhiteTitle "GM"]
[WhiteCountry "AZE"]
[WhiteFideId "13401319"]
[WhiteEloChange "6"]
[BlackElo "2819"]
[BlackTitle "GM"]
[BlackCountry "USA"]
[BlackFideId "2020009"]
[BlackEloChange "-6"]
1. d4 {[%clk 0:09:59]} Nf6 {[%clk 0:06:59]} 2. Bg5 {[%clk 0:09:58]} e6 {[%clk
0:06:57]} 3. e4 {[%clk 0:09:56]} h6 {[%clk 0:06:56]} 4. Bxf6 {[%clk 0:09:53]}
Qxf6 {[%clk 0:06:55]} 5. c3 {[%clk 0:09:48]} d5 {[%clk 0:06:53]} 6. Qe2 {[%clk
0:08:31]} dxe4 {[%clk 0:06:50]} 7. Qxe4 {[%clk 0:08:27]} Bd6 {[%clk 0:06:43]} 8.
Nf3 {[%clk 0:08:21]} O-O {[%clk 0:06:41]} 9. Bd3 {[%clk 0:08:15]} g6 {[%clk
0:06:39]} 10. Nbd2 {[%clk 0:08:10]} Nd7 {[%clk 0:06:30]} 11. Nc4 {[%clk 0:07:53]}
Qe7 {[%clk 0:06:25]} 12. O-O-O {[%clk 0:07:32]} Nf6 {[%clk 0:06:23]} 13. Qe2
{[%clk 0:07:30]} c5 {[%clk 0:06:07]} 14. Kb1 {[%clk 0:07:11]} cxd4 {[%clk
0:06:05]} 15. Nxd4 {[%clk 0:07:08]} Bc7 {[%clk 0:06:00]} 16. Rde1 {[%clk
0:06:24]} Kg7 {[%clk 0:05:59]} 17. g3 {[%clk 0:05:55]} Rd8 {[%clk 0:05:57]} 18.
f4 {[%clk 0:05:52]} Qc5 {[%clk 0:05:38]} 19. Ne5 {[%clk 0:05:46]} Bxe5 {[%clk
0:05:06]} 20. fxe5 {[%clk 0:05:44]} Nd5 {[%clk 0:05:05]} 21. Qf2 {[%clk 0:04:57]}
Qe7 {[%clk 0:05:02]} 22. h4 {[%clk 0:04:55]} Bd7 {[%clk 0:04:56]} 23. h5 {[%clk
0:04:41]} g5 {[%clk 0:04:55]} 24. Qe2 {[%clk 0:03:57]} Rac8 {[%clk 0:04:54]} 25.
Ka1 {[%clk 0:03:56]} a5 {[%clk 0:04:45]} 26. Rhf1 {[%clk 0:03:47]} a4 {[%clk
0:04:36]} 27. c4 {[%clk 0:03:38]} Nb4 {[%clk 0:04:32]} 28. Bb1 {[%clk 0:03:37]}
a3 {[%clk 0:04:19]} 29. bxa3 {[%clk 0:03:04]} Na6 {[%clk 0:04:16]} 30. Rf6 {[%clk
0:02:50]} Rh8 {[%clk 0:03:06]} 31. Ref1 {[%clk 0:02:49]} Be8 {[%clk 0:03:05]} 32.
Qf2 {[%clk 0:02:30]} Nc5 {[%clk 0:02:51]} 33. Qc2 {[%clk 0:02:23]} Rd8 {[%clk
0:02:44]} 34. Nb5 {[%clk 0:01:49]} Nd7 {[%clk 0:02:43]} 35. Qc3 {[%clk 0:01:41]}
Qc5 {[%clk 0:02:33]} 36. Nd6 {[%clk 0:01:23]} Nxf6 {[%clk 0:01:46]} 37. exf6+
{[%clk 0:01:17]} Kf8 {[%clk 0:01:46]} 38. Nxb7 {[%clk 0:01:15]} Qd4 {[%clk
0:01:45]} 39. Rf3 {[%clk 0:01:14]} Qxc3+ {[%clk 0:01:13]} 40. Rxc3 {[%clk
0:01:14]} Rd1 {[%clk 0:01:12]} 41. a4 {[%clk 0:00:46]} Bc6 {[%clk 0:01:08]} 42.
Nc5 {[%clk 0:00:45]} Rf1 {[%clk 0:00:59]} 43. Rb3 {[%clk 0:00:41]} Rxf6 {[%clk
0:00:54]} 44. Rb6 {[%clk 0:00:41]} Bxa4 {[%clk 0:00:44]} 45. Nxa4 {[%clk
0:00:38]} Kg7 {[%clk 0:00:43]} 46. c5 {[%clk 0:00:34]} Rf3 {[%clk 0:00:42]} 47.
Rb3 {[%clk 0:00:30]} Rf1 {[%clk 0:00:41]} 48. Kb2 {[%clk 0:00:28]} Rd8 {[%clk
0:00:40]} 49. Bc2 {[%clk 0:00:26]} Rf2 {[%clk 0:00:39]} 50. Rc3 {[%clk 0:00:26]}
Rb8+ {[%clk 0:00:33]} 51. Ka3 {[%clk 0:00:25]} Rc8 {[%clk 0:00:38]} 52. c6 {[%clk
0:00:25]} Rc7 {[%clk 0:00:37]} 53. Kb4 {[%clk 0:00:24]} f5 {[%clk 0:00:36]} 54.
Kb5 {[%clk 0:00:23]} f4 {[%clk 0:00:30]} 55. gxf4 {[%clk 0:00:23]} Rxf4 {[%clk
0:00:35]} 56. Kb6 {[%clk 0:00:22]} Rc8 {[%clk 0:00:34]} 57. Kb7 {[%clk 0:00:21]}
Rcf8 {[%clk 0:00:32]} 58. Nb6 {[%clk 0:00:14]} g4 {[%clk 0:00:28]} 59. c7 {[%clk
0:00:20]} R4f7 {[%clk 0:00:27]} 60. a4 {[%clk 0:00:21]} Kf6 {[%clk 0:00:27]} 61.
a5 {[%clk 0:00:23]} Rg8 {[%clk 0:00:29]} 62. a6 {[%clk 0:00:24]} g3 {[%clk
0:00:31]} 63. Be4 {[%clk 0:00:27]} Ke5 {[%clk 0:00:33]} 64. Bg2 {[%clk 0:00:29]}
Kd4 {[%clk 0:00:36]} 65. Rc2 {[%clk 0:00:30]} Kd3 {[%clk 0:00:38]} 66. Rc6 {[%clk
0:00:32]} Rf2 {[%clk 0:00:39]} 67. c8Q {[%clk 0:00:33]} Rxc8 {[%clk 0:00:41]} 68.
Rxc8 {[%clk 0:00:35]} Rxg2 {[%clk 0:00:43]} 69. a7 {[%clk 0:00:37]} Ra2 {[%clk
0:00:45]} 70. Rg8 {[%clk 0:00:39]} g2 {[%clk 0:00:45]} 71. a8Q {[%clk 0:00:38]}
1-0
Consider the following game
https://www.chess.com/live/game/4610358993
Move 49 is Qg8f7
because both rank and file are needed to disambiguate the move. So this is a valid pgn but while parsing we get the error:
Expected " ", "!!", "!", "!?", "#", "+", "?!", "?", "??", "\n", "\t", or "\x0C" but "f" found.
Full PGN is
[Event "Live Chess"]
[Site "Chess.com"]
[Date "2020.03.19"]
[Round "-"]
[White "eatmyrook8"]
[Black "TheZahlen"]
[Result "1/2-1/2"]
[ECO "D38"]
[ECOUrl "https://www.chess.com/openings/Queens-Gambit-Declined-Ragozin-Defense-5.Bg5"]
[CurrentPosition "k7/4QQQR/3Q4/8/4K3/2P5/P7/8 w - -"]
[Timezone "UTC"]
[UTCDate "2020.03.19"]
[UTCTime "01:08:13"]
[WhiteElo "1505"]
[BlackElo "1568"]
[TimeControl "60"]
[Termination "Game drawn by timeout vs insufficient material"]
[StartTime "01:08:13"]
[EndDate "2020.03.19"]
[EndTime "01:10:34"]
[Link "https://www.chess.com/live/game/4610358993"]
1. d4 {[%clk 0:00:59.9]} 1... d5 {[%clk 0:00:59.9]} 2. c4 {[%clk 0:00:59.8]} 2... e6 {[%clk 0:00:59.2]} 3. Nc3 {[%clk 0:00:59.7]} 3... Nf6 {[%clk 0:00:58.7]} 4. Nf3 {[%clk 0:00:59.6]} 4... Bb4 {[%clk 0:00:58.3]} 5. Bg5 {[%clk 0:00:59.5]} 5... O-O {[%clk 0:00:57.4]} 6. e3 {[%clk 0:00:59.4]} 6... h6 {[%clk 0:00:57]} 7. Bh4 {[%clk 0:00:59.3]} 7... g5 {[%clk 0:00:55.3]} 8. Nxg5 {[%clk 0:00:58.7]} 8... hxg5 {[%clk 0:00:55.2]} 9. Bxg5 {[%clk 0:00:58.3]} 9... Bxc3+ {[%clk 0:00:55.1]} 10. bxc3 {[%clk 0:00:57.5]} 10... b6 {[%clk 0:00:54.4]} 11. Qf3 {[%clk 0:00:56]} 11... Kg7 {[%clk 0:00:51]} 12. h4 {[%clk 0:00:55.2]} 12... Rh8 {[%clk 0:00:50.4]} 13. h5 {[%clk 0:00:54.6]} 13... Nbd7 {[%clk 0:00:48.2]} 14. Bd3 {[%clk 0:00:53.3]} 14... Kf8 {[%clk 0:00:47.3]} 15. cxd5 {[%clk 0:00:49.7]} 15... Ke7 {[%clk 0:00:46.6]} 16. dxe6 {[%clk 0:00:48.9]} 16... fxe6 {[%clk 0:00:45.1]} 17. e4 {[%clk 0:00:48.7]} 17... Kd6 {[%clk 0:00:44.4]} 18. e5+ {[%clk 0:00:48.2]} 18... Ke7 {[%clk 0:00:42.5]} 19. Bxf6+ {[%clk 0:00:47.7]} 19... Ke8 {[%clk 0:00:41.9]} 20. Bxd8 {[%clk 0:00:46.8]} 20... Kxd8 {[%clk 0:00:41.8]} 21. O-O-O {[%clk 0:00:42.9]} 21... Rf8 {[%clk 0:00:41.1]} 22. Qg3 {[%clk 0:00:40.6]} 22... Bb7 {[%clk 0:00:40.3]} 23. f3 {[%clk 0:00:38.7]} 23... Kc8 {[%clk 0:00:39.8]} 24. h6 {[%clk 0:00:38.2]} 24... Bc6 {[%clk 0:00:39.2]} 25. h7 {[%clk 0:00:37.8]} 25... Kb7 {[%clk 0:00:38.6]} 26. Qg7 {[%clk 0:00:35.5]} 26... Rh8 {[%clk 0:00:36.7]} 27. g4 {[%clk 0:00:32]} 27... Raf8 {[%clk 0:00:34.9]} 28. Rdf1 {[%clk 0:00:31.4]} 28... Bxf3 {[%clk 0:00:33.5]} 29. Rhg1 {[%clk 0:00:30.5]} 29... Nxe5 {[%clk 0:00:28.4]} 30. dxe5 {[%clk 0:00:29.5]} 30... Rd8 {[%clk 0:00:25.9]} 31. Rxf3 {[%clk 0:00:27.6]} 31... a6 {[%clk 0:00:23.6]} 32. g5 {[%clk 0:00:26.8]} 32... Ka8 {[%clk 0:00:23.5]} 33. g6 {[%clk 0:00:26.4]} 33... Rdf8 {[%clk 0:00:22.4]} 34. Rxf8+ {[%clk 0:00:24.4]} 34... Rxf8 {[%clk 0:00:21.7]} 35. Qxf8+ {[%clk 0:00:23.6]} 35... Kb7 {[%clk 0:00:21.6]} 36. h8=Q {[%clk 0:00:23.3]} 36... Kc6 {[%clk 0:00:21.5]} 37. g7 {[%clk 0:00:22.9]} 37... Kd7 {[%clk 0:00:19.1]} 38. g8=Q {[%clk 0:00:22.8]} 38... Kc6 {[%clk 0:00:18.4]} 39. Qxe6+ {[%clk 0:00:22]} 39... Kb7 {[%clk 0:00:18.3]} 40. Qeg8 {[%clk 0:00:18.6]} 40... Kc6 {[%clk 0:00:18.2]} 41. e6 {[%clk 0:00:18.1]} 41... Kb7 {[%clk 0:00:18.1]} 42. e7 {[%clk 0:00:18]} 42... Kc6 {[%clk 0:00:18]} 43. e8=Q+ {[%clk 0:00:17.9]} 43... Kb7 {[%clk 0:00:17.8]} 44. Be4+ {[%clk 0:00:16.5]} 44... Ka7 {[%clk 0:00:16.6]} 45. Bb7 {[%clk 0:00:16.4]} 45... Kxb7 {[%clk 0:00:15.4]} 46. Rg7 {[%clk 0:00:14.8]} 46... Ka7 {[%clk 0:00:14.6]} 47. Rh7 {[%clk 0:00:14.1]} 47... Kb7 {[%clk 0:00:13.8]} 48. Qhg7 {[%clk 0:00:14]} 48... Ka7 {[%clk 0:00:13.5]} 49. Qg8f7 {[%clk 0:00:13.9]} 49... Kb7 {[%clk 0:00:13.4]} 50. Qf8e7 {[%clk 0:00:13.8]} 50... Ka7 {[%clk 0:00:13.3]} 51. Q8d7 {[%clk 0:00:13.2]} 51... Kb7 {[%clk 0:00:13.2]} 52. Kd2 {[%clk 0:00:12.1]} 52... Ka7 {[%clk 0:00:13.1]} 53. Ke3 {[%clk 0:00:11.7]} 53... Kb7 {[%clk 0:00:13]} 54. Ke4 {[%clk 0:00:11.6]} 54... Ka7 {[%clk 0:00:12.9]} 55. Qxc7+ {[%clk 0:00:08.4]} 55... Ka8 {[%clk 0:00:11.9]} 56. Qc6+ {[%clk 0:00:04.5]} 56... Kb8 {[%clk 0:00:10.5]} 57. Qxb6+ {[%clk 0:00:04]} 57... Ka8 {[%clk 0:00:09.7]} 58. Qxa6+ {[%clk 0:00:03.5]} 58... Kb8 {[%clk 0:00:09.1]} 59. Qad6+ {[%clk 0:00:02.3]} 59... Ka8 {[%clk 0:00:08.5]} 1/2-1/2`
Single line comments start with a ;
character and go to the end of the line
https://en.wikipedia.org/wiki/Portable_Game_Notation#Comments
Sample PGN file from this url does not work.
https://zanchess.wordpress.com/2018/02/15/1st-american-chess-congress-new-york-1857/
;; <Paulsen // Raphael * (R3.1) 25 1-0>
;; <Raphael, Benjamin -- Paulsen, Louis (R3.1) 25 0-1>
[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.26"]
[Round "3.1"]
[White "Raphael, Benjamin"]
[Black "Paulsen, Louis"]
[Result "0-1"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "B40"]
[EventDate "1857.10.05"]
[PlyCount "50"]
1.e4 c5 2.d4 cxd4 3.Nf3 e6 4.Nxd4 Bc5 5.Nc3 Qb6 6.Na4 Qa5+ 7.c3 Bxd4 8.Qxd4 Nf6 9.f3 Nc6 10.Qd1 O-O 11.b4 Qe5 12.Bd3 Nxb4 13.cxb4 Qxa1 14.Qc2 Qd4 15.Bb2 Qe3+ 16.Kd1 Qh6 17.Bc1 Qh4 18.Nc3 d5 19.g3 Qh5 20.Qf2 Nxe4 21.Bxe4 dxe4 22.Nxe4 Qd5+ 23.Bd2 Qxa2 24.Re1 Bd7 25.Qe3 Bb5 0-1
;; <Paulsen // Raphael (R3.2) 47 1/2-1/2>
;; <Paulsen, Louis -- Raphael, Benjamin (R3.2) 47 1/2-1/2>
[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.27"]
[Round "3.2"]
[White "Paulsen, Louis"]
[Black "Raphael, Benjamin"]
[Result "1/2-1/2"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "C47"]
[EventDate "1857.10.05"]
[PlyCount "93"]
1.e4 e5 2.Nc3 Nf6 3.Nf3 Nc6 4.d4 Bb4 5.d5 Ne7 6.Nxe5 d6 7.Nf3 Nxe4 8.Qd4 Bxc3+ 9.bxc3 Nf6 10.Bc4 O-O 11.O-O h6 12.Bb3 a5 13.a4 Ng6 14.Ba3 Re8 15.Rfe1 Bg4 16.Nd2 Ne5 17.c4 Re7 18.c5 Qd7 19.cxd6 cxd6 20.c4 Rae8 21.c5 Nc6 22.Rxe7 Nxd4 23.Rxd7 Nxd7 24.f3 Re2 25.Rd1 Bh3 26.c6 Rxg2+ 27.Kh1 bxc6 28.dxc6 Ne5 29.Bxd6 Nexc6 30.Bc4 Rg6 31.Bg3 Nf5 32.Ne4 Ne3 33.Rc1 Bg2+ 34.Kg1 Bxf3 35.Bd3 f5 36.Nd6 Nd4 37.Rc5 Rf6 38.Rxa5 f4 39.Nc4 fxg3 40.Nxe3 gxh2+ 41.Kxh2 g5 42.Ra7 Kf8 43.a5 Rf7 44.Ra6 Re7 45.Rf6+ Ke8 46.Nf5 Nxf5 47.Bxf5 1/2-1/2
;; <Fiske // Marache (R1.4) 35 0-1>
;; <Fiske, Daniel -- Marache, Napoleon (R1.4) 35 0-1>
[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.19"]
[Round "1.4"]
[White "Fiske, Daniel"]
[Black "Marache, Napoleon"]
[Result "0-1"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "A84"]
[EventDate "1857.10.05"]
[PlyCount "70"]
1.d4 e6 2.c4 f5 3.Nc3 Nf6 4.e3 b6 5.Nf3 Bb4 6.a3 Bxc3+ 7.bxc3 O-O 8.Bd3 Bb7 9.O-O Nc6 10.Bb2 Ne7 11.Nh4 d6 12.f4 Qd7 13.Qc2 Ng4 14.Rae1 Rf6 15.e4 Rh6 16.Nf3 Rf8 17.h3 Nf6 18.exf5 exf5 19.d5 c6 20.Qe2 Ng6 21.dxc6 Qxc6 22.Nd4 Qc5 23.Qe6+ Kh8 24.Bxf5 Nh5 25.Qe8 Nf6 26.Qe2 Nh4 27.Qe7 Rb8 28.Bd3 Bxg2 29.Rf2 Bxh3 30.f5 Rh5 31.Bc1 Bxf5 32.Bxf5 Nxf5 33.Nxf5 Rxf5 34.Be3 Qe5 35.Qxa7 Qg3+ 0-1
;; <Lichtenhein // Perrin (R2.3) 30 1-0>
;; <Lichtenhein, Theodore -- Perrin, Frederick (R2.3) 30 1-0>
[Event "1st American Chess Congress"]
[Site "New York, NY USA"]
[Date "1857.10.19"]
[Round "2.3"]
[White "Lichtenhein, Theodore"]
[Black "Perrin, Frederick"]
[Result "1-0"]
[WhiteElo "?"]
[BlackElo "?"]
[ECO "B00"]
[EventDate "1857.10.05"]
[PlyCount "59"]
1.e4 b6 2.d4 Bb7 3.Bd3 e6 4.Ne2 g6 5.O-O Bg7 6.c3 Ne7 7.f4 f5 8.e5 d6 9.Nd2 dxe5 10.fxe5 Bxe5 11.Bc4 Bd6 12.Bxe6 Bd5 13.Bxd5 Nxd5 14.Nf3 Nc6 15.Bg5 Qd7 16.Qb3 h6 17.Bh4 Na5 18.Qc2 Ne3 19.Qd3 Nxf1 20.Rxf1 g5 21.Bg3 f4 22.Qe4+ Kf7 23.Bxf4 Kg7 24.Be5+ Bxe5 25.Nxe5 Qe6 26.Rf7+ Qxf7 27.Nxf7 Kxf7 28.b4 Rae8 29.Qf3+ Kg8 30.bxa5 1-0
I want to send a PGN game across the wire in json format. I then want to parse the json and transform it back to its original PGN file format. Is this possible with this library?
Some pgn's have null moves tabulated with --
, quite a few available at The Week in Chess (https://theweekinchess.com/).
Example:
[Event "Turkey Cup 2014"]
[Site "Kemer TUR"]
[Date "2014.02.02"]
[Round "2.71"]
[White "Subasi,Zeki"]
[Black "Yuvarlak,U"]
[Result "1/2-1/2"]
[WhiteElo "1714"]
[BlackElo "1850"]
[ECO "C45"]
[Opening "Scotch"]
[Variation "Schmidt variation"]
[WhiteFideId "6345433"]
[BlackFideId "6305598"]
[EventDate "2014.02.01"]
1. e4 e5 2. Nf3 Nc6 3. d4 exd4 4. Nxd4 Nf6 5. Nc3 Bb4 6. Nxc6 bxc6 7. Bd3 d5 8.
O-O Bxc3 9. bxc3 dxe4 10. Qe2 O-O 11. Bxe4 Re8 12. f3 Bf5 13. Bg5 -- 14. Rad1
Qe7 15. Bxf6 Qxf6 16. Qc4 Rad8 17. Bxc6 1/2-1/2
See also
https://lichess.org/forum/lichess-feedback/request-allow-null-moves-in-studies.
https://www.chess.com/forum/view/general/what-is-a-null-move-and-how-to-make-it
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.