jhlywa / chess.js

A TypeScript chess library for chess move generation/validation, piece placement/movement, and check/checkmate/draw detection
BSD 2-Clause "Simplified" License
3.69k stars 892 forks source link

Promotion #49

Closed bendathierrycom closed 10 years ago

bendathierrycom commented 10 years ago

Hello jhlywa,

Could we have an example in your package (in "master" or in your jquery "widget") in which you can choose the piece you want to take when you are promoting a pawn.

It could be very good for people whom don't practise javascript every day.

Thanks for that tool, it is a good one :+1:

Thierry

imor commented 10 years ago

I think it is already documented in the move() section. You can use it as below-

//promote to queen. Other pieces are 'r' for rook, 'k' for knight and 'b' for bishop
chess.move({ from: 'a7', to: 'a8', promotion:'q' });

If you passing a string maybe this would work but I haven't tested it so -

chess.move('a7a8q');
bendathierrycom commented 10 years ago

Thanks imor,

Yes, I have seen that, but in a context where you don't know which move is played, you can set a default piece to promote like it is done in examples of "chessboard.js" library, or you can set a piece at a time.

If you want to set a promoted piece at runtime and let the user make a choice, then it is not enough. You cannot use these method to set the promotion piece just because it is called for each move you will make, with or without promotion, and it is not that I want to have.

I am trying to test if the move is a promotion one, but it is not really working at the moment. Do you have a good way to do that?

Best regards, Thierry

bendathierrycom commented 10 years ago

Ok, I have finally used a workaround to use the simple way suggested by imor (and the documented parts of the code).

I am storing the desired promotion piece inside the DOM (from a JQuery Dialog). The default is Queen, and the user is free to change it, the only thing to do is to click on a button, and chooses what he wants.

It resides here: http://www.jeu-echecs83.fr/chessproblems/probleme5 (or any other problems you could find on my website).

Thanks for the tip, it is a great javascript lib, definitively :)

L0rdH4x0r commented 8 years ago

//promote to queen. Other pieces are 'r' for rook, 'k' for knight and 'b' for bishop chess.move({ from: 'a7', to: 'a8', promotion:'q' });

Actually its n for the knight! I found the bug in enginegame.js on ai promote as well...

Nikola-Obreshkov commented 6 years ago

There should be a function is_promotion(from, to) in chess.js and to return true if the move is valid and is promotion move. After that this issue can be solve like this:

//a modal window lets the user to choose a promotion piece
if ( chess.is_promotion(from, to) ) {
      choose_piece({
           onchosen: function(piece) {
                 chess.move({ from: from, to: to, promotion: piece.code });
            }
      }
});
L0rdH4x0r commented 6 years ago

You are absolutely right. Actually I'm doing this in a hackish way, where I check if the move exists in chess.moves({ verbose: true });. The dialog you mentioned should be handled with a Promise/await pattern. Unfortunately this is ES6, but webpack could compile the module down to a compatible state machine. You are welcome to implement this feature in a separate branch, which could be merged into the master branch later on. This would definitely improve the handling for everyone.

justingolden21 commented 3 years ago

//promote to queen. Other pieces are 'r' for rook, 'k' for knight and 'b' for bishop chess.move({ from: 'a7', to: 'a8', promotion:'q' });

Actually its n for the knight! I found the bug in enginegame.js on ai promote as well...

That's not a bug... 'N' is standard for knight in chess, 'K' is king. Even though you obviously don't promote to a king, it would be stupid to change the entire standard just for pawn promotion.

varunpvp commented 3 years ago

Maybe, this will be helpful.

function isPromoting(fen, move) {
  const chess = new Chess(fen);

  const piece = chess.get(move.from);

  if (piece?.type !== "p") {
    return false;
  }

  if (piece.color !== chess.turn()) {
    return false;
  }

  if (!["1", "8"].some((it) => move.to.endsWith(it))) {
    return false;
  }

  return chess
    .moves({ square: move.from, verbose: true })
    .map((it) => it.to)
    .includes(move.to);
}