lichess-org / api

Lichess API documentation and examples
https://lichess.org/api
GNU Affero General Public License v3.0
428 stars 142 forks source link

gameState following move with draw offer shows prior board position #194

Closed MarkZH closed 2 years ago

MarkZH commented 2 years ago

Referenced lichess-bot issue: https://github.com/ShailChoksi/lichess-bot/issues/502

When a bot posts a move using the API with a draw offer, the next gameState that is received is the position prior to the move. An example from the game https://lichess.org/WzU3jHmv at move 47.

The gameState message to the bot to start the bot thinking (the ... indicates prior moves):

{'type': 'gameState', 'moves': '... a3a5 g2f2 a5c5', 'wtime': 25230, 'btime': 39380, 'winc': 3000, 'binc': 3000, 'status': 'started'}

The bot's move:

https://lichess.org:443 "POST /api/bot/game/WzU3jHmv/move/d5h1?offeringDraw=true HTTP/1.1" 200 11

The next gameState from lichess:

{'type': 'gameState', 'moves': '... a3a5 g2f2 a5c5', 'wtime': 22440, 'btime': 39380, 'winc': 3000, 'binc': 3000, 'status': 'started', 'wdraw': True}

The draw offer has been added (wdraw: True), but the bot's move (d5h1) has not. This game state shows it is the bot's turn to move, which causes the bot to begin thinking about the board position it has already played. This results in the bot trying to send a move from the previous board position out of turn.

https://lichess.org:443 "POST /api/bot/game/WzU3jHmv/move/d5h1?offeringDraw=true HTTP/1.1" 400 26
Giving up api_post(...) after 1 tries (requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://lichess.org/api/bot/game/WzU3jHmv/move/d5h1?offeringDraw=true)
ornicar commented 2 years ago

Thanks for well written bug report.

I tried finding a workaround on lila side and it's quite difficult, because a move and a draw offer are 2 distinct events that trigger different messages, and they can happen independently. Indeed on the UI it's possible to move, then offer a draw - or offer a draw then move.

Therefore when a bot moves with a draw offer, it first receives the game with the draw flag, then the game with the move appended.

It's possible to receive multiple gameState messages with the same move list, because that message is triggered by other events than moving, such as draw and takeback negotiation events.

So I think it's better to update the clients to avoid recomputing positions from an unchanged move list.