+ if (
+ m.end.x == oppLastRank &&
+ ['c', 'd', 'e', 'f', 'g'].includes(m.appear[0].p)
+ ) {
+ // Move to first rank, which is last rank for opponent's pawn.
+ // => Show promotion choices.
+ // Find our piece in union (not a pawn)
+ const up = this.getUnionPieces(m.appear[0].c, m.appear[0].p);
+ // merge with all potential promotion pieces + push (loop)
+ for (let promotionPiece of [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]) {
+ let args = [up[c], promotionPiece];
+ if (c == 'b') args = args.reverse();
+ const cp = this.getUnionCode(args[0], args[1]);
+ let cpMove = JSON.parse(JSON.stringify(m));
+ cpMove.appear[0].c = cp.c;
+ cpMove.appear[0].p = cp.p;
+ moves.push(cpMove);
+ }
+ }
+ else {
+ if (
+ m.vanish.length > 0 &&
+ m.vanish[0].p == V.PAWN &&
+ m.start.y != m.end.y &&
+ this.board[m.end.x][m.end.y] == V.EMPTY
+ ) {
+ if (!!lm)
+ // No en-passant inside a chaining
+ return;
+ // Fix en-passant capture: union type, maybe released piece too
+ const cs = [m.end.x + (c == 'w' ? 1 : -1), m.end.y];
+ const color = this.board[cs[0]][cs[1]].charAt(0);
+ const code = this.board[cs[0]][cs[1]].charAt(1);
+ if (code == V.PAWN) {
+ // Simple en-passant capture (usual: just form union)
+ m.appear[0].c = 'w';
+ m.appear[0].p = 'a';
+ }
+ else {
+ // An union pawn + something juste moved two squares
+ const up = this.getUnionPieces(color, code);
+ m.released = up[c];
+ let args = [V.PAWN, up[oppCol]];
+ if (c == 'b') args = args.reverse();
+ const cp = this.getUnionCode(args[0], args[1]);
+ m.appear[0].c = cp.c;
+ m.appear[0].p = cp.p;
+ }
+ }
+ moves.push(m);
+ }