oakmac / chessboardjs

JavaScript chessboard
https://chessboardjs.com
MIT License
2k stars 406 forks source link

choose promotion in onDrag function #211

Closed jimmyyzr closed 3 years ago

jimmyyzr commented 3 years ago

I have a popup window to let the user choose a promotion, however, the rest of the code inonDrag wouldn't wait until the click happen, and onSnapEnd is triggered right after, when the move has not be set up, which causes bad behavior. Below is part of my code in onDrag:

  var move;

  if (target[1] === '8') {
    var promotion;
    $('#promotion-box').show();
    $('.promo-img').click(function() {
      promotion = $(this).attr('id');
      promotion = promotion.charAt(promotion.length - 1);
      console.log('promo var type: ' + typeof promotion);
      console.log('Promotion: ' + promotion);

      $('#promotion-box').hide();
    });

    move = game.move({
      from: source,
      to: target,
      promotion: promotion
    });
  }
  else {
    move = game.move({
      from: source,
      to: target,
    });
  }

Any suggestion on how should I fix this?I think I need to stop the onDrag function when the user hasn't choose the promotion.

oakmac commented 3 years ago

This is a timing / callback bug. You will need to set the board position after the user selects their promotion piece. For a moment in time, the chess.js game state will not match the state on the chessboard.js board.

jimmyyzr commented 3 years ago

Sorry I am a little confused. Could you elaborate a little bit? What do you mean by "set the board position"? I think game.move has to happen in onDrag

jimmyyzr commented 3 years ago

Could you please send a response at your convenience?

oakmac commented 3 years ago

The order of operations should look like this:

  1. User picks up a pawn from the 7th rank
  2. User drops the pawn on the 8th rank
  3. Set the Chessboard to have a pawn on the 8th rank (NOTE: this is not legal in the game of chess, but allowed by the Chessboard component)
  4. Show your pawn promotion interface (this will likely happen via the onDrop event from Chessboard)
  5. User selects a piece from the pawn promotion interface
  6. Set the chess game (ie: chess.js library) that the pawn move was made, including the promotion information (ie: game.move())
  7. Update the Chessboard with promoted piece replacing the pawn on the 8th rank

For a moment in time before the user selects a piece from the pawn promotion interface, the board will show a pawn on the 8th rank.

jimmyyzr commented 3 years ago

Thanks for your response! I understand the process you described, but I think the current problem is that onDrop wouldn't wait for the user to make the choice (since my promotion window is asynchronous), and onSnapEnd will be called immediately without knowinig the user's decision.