- // Search valid moves on sideBoard
- let saveBoard = this.board;
- this.board = sideBoard || this.getSideBoard(mirrorSide);
- let moves = super.getPotentialMovesFrom([x,y])
- .filter(m => {
- // Filter out king moves which result in under-check position on
- // current board (before mirror traversing)
- let aprioriValid = true;
- if (m.appear[0].p == V.KING)
- {
- this.play(m);
- if (this.underCheck(color))
- aprioriValid = false;
- this.undo(m);
- }
- return aprioriValid;
- });
- this.board = saveBoard;
+ // Finally filter impossible moves
+ const res = moves.filter(m => {
+ if (m.appear.length == 2) {
+ //castle
+ // appear[i] must be an empty square on the other board
+ for (let psq of m.appear) {
+ if (this.getSquareOccupation(psq.x, psq.y, 3 - mirrorSide) != V.EMPTY)
+ return false;
+ }
+ } else if (this.board[m.end.x][m.end.y] != V.EMPTY) {
+ // Attempt to capture
+ const piece = this.getPiece(m.end.x, m.end.y);
+ if (
+ (mirrorSide == 1 && codes.includes(piece)) ||
+ (mirrorSide == 2 && pieces.includes(piece))
+ ) {
+ return false;
+ }
+ }
+ // If the move is computed on board1, m.appear change for Alice pieces.
+ if (mirrorSide == 1) {
+ m.appear.forEach(psq => {
+ // forEach: castling taken into account
+ psq.p = V.ALICE_CODES[psq.p]; //goto board2
+ });
+ }
+ else {
+ // Move on board2: mark vanishing pieces as Alice
+ m.vanish.forEach(psq => {
+ psq.p = V.ALICE_CODES[psq.p];
+ });
+ }
+ // Fix en-passant captures
+ if (
+ m.vanish[0].p == V.PAWN &&
+ m.vanish.length == 2 &&
+ this.board[m.end.x][m.end.y] == V.EMPTY
+ ) {
+ m.vanish[1].c = V.GetOppCol(this.getColor(x, y));
+ // In the special case of en-passant, if
+ // - board1 takes board2 : vanish[1] --> Alice
+ // - board2 takes board1 : vanish[1] --> normal
+ let van = m.vanish[1];
+ if (mirrorSide == 1 && codes.includes(this.getPiece(van.x, van.y)))
+ van.p = V.ALICE_CODES[van.p];
+ else if (
+ mirrorSide == 2 &&
+ pieces.includes(this.getPiece(van.x, van.y))
+ )
+ van.p = V.ALICE_PIECES[van.p];
+ }
+ return true;
+ });
+ return res;
+ }