Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Temporarily duplicated pieces due to racing updates to currentPosition. #233

Open
LMMilewski opened this issue Jul 25, 2022 · 2 comments
Open

Comments

@LMMilewski
Copy link

LMMilewski commented Jul 25, 2022

Consider the "Play Random Computer" example from https://www.chessboardjs.com/examples#5001

First, the following bug can be easily reproduced locally by exaggerating the effect with the following changes:

  • reduce the makeRandomMove delay to 1 (window.setTimeout(makeRandomMove, 1)
  • increase the move speed to 1000 (in the board config, set moveSpeed: 1000)

As a result of the above, you'll see duplicated pieces (for the duration of the animation) whenever the computer makes a move.

This happens because of these racing currentPosition reads/writes:

  • The player makes a move (drops the piece) which calls onDrop and schedules the "snap" animation to run after config.snapSpeed (30ms by default). That is, after 30ms, Chessboard will drawPositionInstant() with currentPosition. Usually currentPosition is whatever was on the board when the player dropped the piece and everything is correct in that case.
  • However, in the example above (or whenever one attempts to implement a computer opponent), when the player drops a piece, onDrop is called which: calculates the new move (can be faster than 30ms), calls board.position() (potentially queued with setTimeout), and starts an animation for the computer move. Note that board.position() updates the currentPosition immediately.

As a result, if board.position() is called in the 30ms snapSpeed time window after player's move, the player gets to see two versions of the piece moved by the computer:

  • one because of the animation moving the piece (this is expected)
  • one because when snap animation finishes, it sees the new position that happens only after the computer move but the snap animation callback intended to only draw the position that happened after the player's move (i.e. before the computer gets to move their piece).

I attached a screenshot. I played 1.d4 and the computer from your example replied 2...,g4 and now the black g-pawn is duplicated: one is on g4 and the other one is moving from g2 to g4).
duplicates

As mentioned at the start of this post, you can easily reproduce it locally by changing makeRandomMove delay to 1 and config.moveSpeed to 1000 in your example at
https://www.chessboardjs.com/examples#5001

One workaround is to set config.snapSpeed to 0 and disallowing dragging pieces while computer move is being animated.

@JuliaHorokhovatska
Copy link

I have the same problem

@JuliaHorokhovatska
Copy link

I added delay whenever the computer makes a move, it is fix duplicated pieces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants