lichess-org / lila

♞ lichess.org: the forever free, adless and open source chess server ♞
https://lichess.org
GNU Affero General Public License v3.0
15.63k stars 2.28k forks source link

Import amends result for threefold or fifty moves #10520

Closed dlbbld closed 2 years ago

dlbbld commented 2 years ago

Threefold: When importing a game that ends with a threefold repetition and result of 1/2-1/2, the import changes the result to "Threefold repetition • Draw", which is incorrect. One cannot know if the game ended for a threefold claim or mutual draw agreement. Therefore, the result should be only "Draw" as per the PGN. In fact, in most situations with a drawish position, the players draw per mutual agreement without involving a threefold claim.

Example: The following game ends with a threefold repetition and result of 1/2-1/2. After the import, the result is "Threefold repetition • Draw" instead of "Draw".

[Event "Qatar Masters"]
[Site "Doha QAT"]
[Date "2015.12.26"]
[EventDate "2015.12.20"]
[Round "6.4"]
[Result "1/2-1/2"]
[White "Dariusz Swiercz"]
[Black "Sergey Karjakin"]
[ECO "E00"]
[WhiteElo "2646"]
[BlackElo "2766"]
[PlyCount "91"]

1. d4 Nf6 2. c4 e6 3. g3 Bb4+ 4. Bd2 Be7 5. Bg2 d5 6. Nf3 O-O
7. O-O c6 8. Qc2 Nbd7 9. Rd1 b6 10. b3 Ba6 11. a4 c5 12. a5
dxc4 13. bxc4 Qc8 14. Nc3 Bxc4 15. Bg5 b5 16. Ne5 cxd4 17. Nc6
Bc5 18. Bxf6 Nxf6 19. Nxb5 Bxb5 20. Qxc5 Bxc6 21. Bxc6 Qc7
22. Rxd4 Rad8 23. Rc4 Nd7 24. Bxd7 Qxc5 25. Rxc5 Rxd7 26. Rac1
f5 27. f4 Kf7 28. Kf2 Kf6 29. Rc6 Rb8 30. R1c5 Rb4 31. Re5 Re7
32. Re3 Ra4 33. a6 Rd4 34. Kf3 h5 35. h3 Ra4 36. h4 Ra5
37. Rd3 Ra4 38. Re3 Ra5 39. Rd3 Ra4 40. Rd8 Ra3+ 41. Kf2 g6
42. Rf8+ Kg7 43. Rfc8 Kf6 44. Rf8+ Kg7 45. Rfc8 Kf6 46. Rf8+
1/2-1/2

Fifty-moves: When importing a game that ends with fifty moves without a pawn move and capture and any result, the import changes it to "Fifty moves without progress • Draw", which is incorrect. The result can be any, also 1-0, or 0-1 and even if 1/2-1/2, one cannot know if the game ended for a fifty-move claim or mutual draw agreement. Therefore, the result should be as per the PGN.

Example: The following game ends with fifty moves without a pawn move and capture, but 1-0 because Black flagged. But after the import, the result is "Fifty moves without progress • Draw" instead of "Black resigned • White is victorious". By the way, to say Black resigned when importing 1-0 is incorrect, Black might also have flagged as here (#10519).

[Event "World Blitz Championship"]
[Site "Dubai UAE"]
[Date "2014.06.19"]
[EventDate "2014.06.19"]
[Round "7.1"]
[Result "1-0"]
[White "Magnus Carlsen"]
[Black "Le Quang Liem"]
[ECO "D73"]
[WhiteElo "2881"]
[BlackElo "2712"]

1. d4 Nf6 2. Nf3 g6 3. g3 Bg7 4. Bg2 d5 5. c4 c6 6. cxd5 cxd5
7. Ne5 O-O 8. Nc3 e6 9. O-O Nfd7 10. Nf3 Nf6 11. Bf4 Nc6
12. Rc1 Bd7 13. Qd2 Rc8 14. Ne5 Qe7 15. Rfd1 Rfd8 16. Bg5 Qf8
17. h4 h6 18. Bxf6 Bxf6 19. f4 h5 20. e3 Be8 21. Bf3 Ne7
22. Kf2 Nf5 23. Ne2 Qd6 24. Qa5 Qb6 25. Qxb6 axb6 26. Rxc8
Rxc8 27. Rc1 Ra8 28. a3 Nd6 29. Nc3 Kf8 30. e4 dxe4 31. Nxe4
Bxe5 32. dxe5 Nxe4+ 33. Bxe4 Bc6 34. Ke3 Ke7 35. Bd3 Ra5
36. Rc3 Rc5 37. Rb3 b5 38. Rc3 Rxc3 39. bxc3 Kd7 40. Kd4 b6
41. Ke3 Kc7 42. Kd2 Bd7 43. Ke3 Kc6 44. Kd4 Kc7 45. Be2 Bc6
46. g4 hxg4 47. Bxg4 Kd7 48. Be2 Kc7 49. h5 gxh5 50. Bxh5 Be8
51. f5 Kd7 52. f6 Kc7 53. Bf3 Bc6 54. Be2 Be8 55. Bd1 Bd7
56. Bb3 Be8 57. Ke4 Kd8 58. Kf4 Bd7 59. Bd1 Bc6 60. Be2 Bd7
61. Bd3 Bc6 62. Ke3 Kc7 63. Kd2 Be8 64. Be4 Bc6 65. Bc2 Be8
66. Kd3 Kc6 67. Kd4 Kc7 68. Ke4 Bc6+ 69. Kf4 Kd8 70. Bb3 Bd7
71. Kg5 Ke8 72. Kh6 Kf8 73. Bc2 Bc6 74. Kh7 Bd5 75. Bd3 Bc6
76. Be2 Be4+ 77. Kh8 Bc6 78. Bf1 Bd7 79. Bg2 Be8 80. Bb7 Bd7
81. Ba6 Bc6 82. Bc8 Be4 83. Bd7 Bd3 84. Bc6 Bc4 85. Kh7 Bd3+
86. Kh6 Kg8 87. Kg5 Bc4 88. Kf4 Kh7 89. Kg5 Kg8 90. Bd7 Kh7
91. Be8 Kg8 92. Kf4 Kf8 93. Bc6 Kg8 94. Ke4 Kh7 95. Kd4 Bf1
96. Be8 Kg6 97. Ke3 Kf5 98. Kd4 Kg6 99. Ke4 Bc4 100. Kf4 Bf1
101. Bc6 Kh6 102. Bb7 Bc4 103. Ba6 1-0

It is possibly related to #8681 and #8793.

dlbbld commented 2 years ago

I hope the print screen for the fifty-moves example is clear: Printscreen import fifty-moves

lenguyenthanh commented 2 years ago

I think the issue is in this: https://github.com/lichess-org/lila/blob/master/modules/importer/src/main/ImporterForm.scala#L113

game.situation.status match {
            case Some(situationStatus) => dbGame.finish(situationStatus, game.situation.winner).game
            case None =>
              parsed.tags.resultColor
                .map {
                  case Some(color)                        => TagResult(status, color.some)
                  case None if status == Status.Outoftime => TagResult(status, none)
                  case None                               => TagResult(Status.Draw, none)
                }
                .filter(_.status > Status.Started)
                .fold(dbGame) { res =>
                  dbGame.finish(res.status, res.winner).game
                }
          }
        }

We prioritize our game logic over the result from the pgn. The solution is always use the result from pgn. If there is none then use our logic to decide the result of the game. What do you think?

benediktwerner commented 2 years ago

Sounds reasonable. Though what about mates with a differing result, e.g. maybe bc the result was later reversed due to cheating? I guess maybe just always going by the PGN would still be fine though.

lenguyenthanh commented 2 years ago

In the case of conflict I agree that we should still always prefer PGN.

lenguyenthanh commented 2 years ago

this can be closed now because of #10665

dlbbld commented 2 years ago

Even if checkmate or stalemate, the result can still be "*", for the players might overlook it... (or forget to set the result in the PGN).

I don't see that the PGN specification requires the game result to match with checkmate or stalemate on the board.

Therefore, I think always taking the PGN result is correct, allowing even the most bizarre case of having "*" in the result and checkmate or stalemate on the board.

lenguyenthanh commented 2 years ago

I think the fix for this issue has been deployed. Can you verify it pls @dlbbld? thanks!

dlbbld commented 2 years ago

Thanks, but it does not work. Already imported games are not recreated, so for this reason, the result does not change. But for fresh imports, the first case (draw) does not work, only the second (win).

Swiercz vs Karjakin does not work: When importing, the import creates no new entry, it links to the previously imported game, so the result is still "Threefold repetition • Draw" instead of "Draw".

It creates a new import entry when changing a tag value before importing, but the result is still "Threefold repetition • Draw" instead of "Draw".

Carlsen vs Quang Liêm works partly: When importing, the import creates no new entry, it links to the previously imported game, so the result is still "Fifty moves without progress • Draw" instead of "Black resigned • White is victorious".

It creates a new import entry when changing a tag value before importing, and the result is "Black resigned • White is victorious", as expected.

lenguyenthanh commented 2 years ago

The fix is only apply for new import. So if you paste the same pgn again the result will not be changed. I don't know if we should do anything about it.

The text Threefold repetition • Draw seems to be generated in the fly. If you download the annotated pgn, you'll see that there is no tag for that.

dlbbld commented 2 years ago

To say Threefold repetition • Draw is wrong because the PGN only says it's a draw. It does not specify the reason. The reason can be any of mutual agreement, claim for threefold, arbiter decision or who knows what.

dlbbld commented 2 years ago

To enforce the previous. In the last World Championships, for example, between Carlsen and Nepomniachtchi, one could observe that. When they repeat in a drawish position about half the time, they agree to a draw, without one player claiming the draw for threefold. And at this point, there is often also a threefold on the board.

So threefold on the board does not mean the game ended with a threefold repetition claim; half of the time, there is mutual agreement.

dlbbld commented 2 years ago

When importing the drawn game example (PGN result is 1/2-1/2), by changing tag values, a new import is created, it still prints Threefold repetition • Draw for the result.

The agreement here is to print the result as per the PGN, which is Draw. If there is a threefold repetition or not with the last move has no relevance, and must not be printed. It is misleading and unnecessary information.