The following PGN was exported from Lichess.org (line breaks added by me to highlight moves 42 and 54):
1. Nf3 Nc6 2. Nc3 Nf6 3. Rb1 Rg8 4. Rg1 Rb8 5. Rh1 Ra8 6. Ra1 Rh8 7. Nb1 Ng8 8. Ng1 Nb8 9. Nf3 Nc6 10. Nh4 Na5 11. b4 g5 12. bxa5 gxh4 13. Ba3 Bh6 14. Bd6 Be3 15. fxe3 cxd6 16. h3 a6 17. Nc3 Nf6 18. Nb5 Ng4 19. hxg4 axb5 20. Rb1 Rg8 21. Rb4 Rg5 22. Rf4 Rc5 23. d4 e5 24. dxc5 exf4 25. Qd2 Qc7 26. Kd1 Kf8 27. Kc1 Kg8 28. Kb1 Kh8 29. Ka1 h6 30. a4 h5 31. Qe1 Qd8 32. a6 h3 33. a7 h2 34. Rg1 Rb8 35. axb8=Q hxg1=Q 36. Qxc8 Qxf1 37. Qb1 Qg8 38. a5 h4 39. a6 h3 40. a7 h2 41. a8=Q h1=Q
42. Qa2 Qh7
43. e4 d5 44. e5 d4 45. e4 d5 46. e6 d3 47. e7 d2 48. c6 f3 49. e5 d4 50. c4 f5 51. c5 f4 52. Qf5 Qfc4 53. Qfc2 Qcf7
54. Qbc1 Qgf8
55. Kb2 Kg7 56. Ka3 Kh6 57. e8=Q d1=Q 58. Qa8 Qh1 59. Qaa4 Qhh5 60. e6 d3 61. e7 d2 62. e8=Q d1=Q 63. Qea8 Qdh1 64. Kb4 Kg5 65. Kc3 Kf6 66. Kd2 Ke7 67. g5 b4 68. g4 b5 69. g6 b3 70. g5 b4 71. g7 b2 72. g8=Q b1=Q 73. Qgg6 Qbb3 74. Qgd3 Qbe6 75. g6 b3 76. g7 b2 77. g8=Q b1=Q 78. Qda3 Qeh6 79. Qgg6 Qbb3 80. Qgd3 Qbe6 81. c7 f2 82. c8=Q f1=Q 83. Qca6 Qfh3 84. Kc3 Kf6 85. Kb2 Kg7 86. Ka1 Kh8 87. Qc2b1 Qf7g8 88. Qcb2+ Qfg7 89. c6 f3 90. c7 f2 91. Qdb3 Qeg6 92. Qaf1 Qhc8 93. Qfd1 Qce8 94. Qad5 Qhe4 95. c8=Q f1=Q 96. Qcc1 Qff8 97. Qdc5 Qef4 98. Q5c2 Q4f7 99. Qbd4 Qge5 100. Qdb2 Qeg7 101. Qbd4 Qge5 102. Qdb2 Qeg7 1/2-1/2
When run with this input file, your code outputs no GIF and the exception handler gives the following, rather cryptic message:
Traceback (most recent call last):
File "C:\path-to-pgn2gif\pgn2gif-script.py", line 33, in <module>
sys.exit(load_entry_point('pgn2gif==1.2', 'console_scripts', 'pgn2gif')())
File "C:\path-to-python\python3.8\site-packages\pgn2gif-1.2-py3.8.egg\pgn2gif\pgn2gif.py", line 167, in main
creator.create_gif(pgn, Path(args.out) / f)
File "C:\path-to-python\python3.8\site-packages\pgn2gif-1.2-py3.8.egg\pgn2gif\pgn2gif.py", line 127, in create_gif
game.next()
File "C:\path-to-python\python3.8\site-packages\pgn2gif-1.2-py3.8.egg\pgn2gif\chess.py", line 228, in next
origin = self._find_non_pawn(move, dest, pt)
File "C:\path-to-python\python3.8\site-packages\pgn2gif-1.2-py3.8.egg\pgn2gif\chess.py", line 147, in _find_non_pawn
return next(
StopIteration
By shortening the file using trial-and error, I determined that the crash happens at Black's move 54. If Qgf8
and all following text is removed, a GIF is generated. However, unlike the output of all online PGN players and converters I tried, it does not end with a black queen in column g
(there should have been one at G8
). Turns out, your program moved the G8
queen in move 42, "42. .. Qh7
". Either queen (G8
or H1
) could move there, and it was not specified. This ambiguity is likely a mistake on Lichess' part, and I am not blaming you for handling it wrong. However, it is annoying that your PGN parser behaved differently from all others tested. The game can be fixed by rewriting Move 42 to 42. Qa2 Qhh7
to remove the ambiguity.
For reference, here is the chessboard state after White's move 42 (just before the parsing "mistake") and White's move 54 (just before the crash), respectively:
a b c d e f g h | a b c d e f g h
8 Q q k | 8 q k
7 p p P | 7 p P q q
6 p | 6 P
5 p P | 5 p P P
4 p P | 4 p p P
2 P | 3 p
2 Q P P P | 2 Q Q p P
1 K Q q q | 1 K Q
Also, FEN of the above positions for import into a viewer:
2Q3qk/1p1p1p2/3p4/1pP5/5pP1/4P3/Q1P1P1P1/KQ3q1q b - - 1 42
6qk/1p2Pq1q/2P5/1pP1P3/3p1pP1/5p2/Q1Qp2P1/K1Q5 b - - 5 54
So, how could you improve the user experence? In either of two ways:
- Use a PGN parser that behaves the same as others, such as the Lichess.org Analysis Board Import feature. Thus, your program will behave as expected from the users of Lichess.org and other parsers: the set of accepted PGN files will be the same for you and them, and they might offer hints on error locations in case the file cannot be accepted. You could possibly import someone's open-source pre-converter that completely de-ambiguises the PGN, so that e.g.
1. e4 Nf6
becomes 1. e2e4 Ng8f6
(if such software exists).
- Add error reporting that aids in identifying the ambiguous move, so that the user can fix the PGN file.
Such error reporting could look like this:
Ambiguous white move 42 "Qa2": Multiple queens can move to A2; resolved as A8→A2
Ambiguous black move 42 "Qh7": Multiple queens can move to H7; resolved as G8→H7
Invalid black move 54 "Qgh7": No queen in column g
Please retry with a valid PGN file. Exiting...
Note that in Move 42, White's ambiguous move was resolved as expected while Black's wasn't.