Skip to content

Commit

Permalink
Ignore up to one consecutive empty line between PGN headers (fixes ni…
Browse files Browse the repository at this point in the history
  • Loading branch information
niklasf committed Jun 11, 2020
1 parent 3511e1b commit 9b00831
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
13 changes: 9 additions & 4 deletions chess/pgn.py
Original file line number Diff line number Diff line change
Expand Up @@ -1226,12 +1226,19 @@ def read_game(handle: TextIO, *, Visitor = GameBuilder):
line = handle.readline()

# Parse game headers.
consecutive_empty_lines = 0
while line:
# Ignore comments.
if line.startswith("%") or line.startswith(";"):
line = handle.readline()
continue

# Ignore up to one consecutive empty line between headers.
if consecutive_empty_lines < 1 and line.isspace():
consecutive_empty_lines += 1
line = handle.readline()
continue

# First token of the game.
if not found_game:
found_game = True
Expand All @@ -1244,6 +1251,8 @@ def read_game(handle: TextIO, *, Visitor = GameBuilder):
if not line.startswith("["):
break

consecutive_empty_lines = 0

if not skipping_game:
tag_match = TAG_REGEX.match(line)
if tag_match:
Expand All @@ -1261,10 +1270,6 @@ def read_game(handle: TextIO, *, Visitor = GameBuilder):
if not skipping_game:
skipping_game = visitor.end_headers() is SKIP

# Ignore single empty line after headers.
if line.isspace():
line = handle.readline()

if not skipping_game:
# Chess variant.
headers = managed_headers if unmanaged_headers is None else unmanaged_headers
Expand Down
35 changes: 35 additions & 0 deletions data/pgn/chessbase-empty-line.pgn
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[Event "AlphaZero vs. Stockfish"]

[Date "2017.12.04"]
[Round "1"]
[White "Stockfish 8"]
[Black "AlphaZero"]
[Result "0-1"]
[Board "1"]
[WhiteCountry "NOR"]
[WhiteFideId "stockfish"]
[BlackCountry "ENG"]
[BlackFideId "deepmind"]

1. e4 e5 2. Nf3 Nc6 3. Bb5 Nf6 4. d3 Bc5
5. Bxc6 dxc6 6. O-O Nd7 7. Nbd2 O-O 8.
Qe1 f6 9. Nc4 Rf7 10. a4 Bf8 11. Kh1
Nc5 12. a5 Ne6 13. Ncxe5
fxe5 14. Nxe5 Rf6 15. Ng4 Rf7 16. Ne5
Re7 17. a6 c5 18. f4 Qe8 19. axb7 Bxb7
20. Qa5 Nd4 21. Qc3 Re6 22. Be3 Rb6 23. Nc4
Rb4 24. b3 a5 25. Rxa5 Rxa5 26. Nxa5 Ba6
27. Bxd4 Rxd4 28. Nc4 Rd8
29. g3 h6 30. Qa5 Bc8 31. Qxc7 Bh3 32.
Rg1 Rd7 33. Qe5 Qxe5 34. Nxe5 Ra7 35. Nc4
g5 36. Rc1 Bg7 37. Ne5 Ra8 38. Nf3 Bb2 39.
Rb1 Bc3 40. Ng1 Bd7 41. Ne2 Bd2 42. Rd1
Be3 43. Kg2 Bg4 44. Re1 Bd2 45. Rf1 Ra2 46.
h3 Bxe2 47. Rf2 Bxf4 48. Rxe2 Be5 49. Rf2
Kg7 50. g4 Bd4 51. Re2 Kf6 52. e5+ Bxe5 53.
Kf3 Ra1 54. Rf2 Re1 55. Kg2+ Bf4 56. c3
Rc1 57. d4 Rxc3 58. dxc5
Rxc5 59. b4 Rc3 60. h4 Ke5 61. hxg5
hxg5 62. Re2+ Kf6 63. Kf2
Be5 64. Ra2 Rc4 65. Ra6+ Ke7 66. Ra5
Ke6 67. Ra6+ Bd6 0-1
9 changes: 9 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2456,6 +2456,15 @@ def test_missing_setup_tag(self):
board = chess.Board("rbb1N1k1/pp1n1ppp/8/2Pp4/3P4/4P3/P1Q2PPq/R1BR1K2 b - - 0 1")
self.assertEqual(game.board(), board)

def test_chessbase_empty_line(self):
with open("data/pgn/chessbase-empty-line.pgn") as pgn:
game = chess.pgn.read_game(pgn)
self.assertEqual(game.headers["Event"], "AlphaZero vs. Stockfish")
self.assertEqual(game.headers["Round"], "1")
self.assertEqual(game.variations[0].move, chess.Move.from_uci("e2e4"))

self.assertTrue(chess.pgn.read_game(pgn) is None)

def test_game_from_board(self):
setup = "3k4/8/4K3/8/8/8/8/2R5 b - - 0 1"
board = chess.Board(setup)
Expand Down

0 comments on commit 9b00831

Please sign in to comment.