+ // Expand potential moves if guarded by friendly pieces.
+ // NOTE: pawns cannot be promoted through a relaying move
+ const piece = this.getPiece(x,y);
+ const color = this.turn;
+ const lastRank = (color == 'w' ? 0 : 7);
+ const sq = [x, y];
+ const oneStep = (piece == V.PAWN);
+ let guardedBy = {};
+ if (piece != V.ROOK && super.isAttackedByRook(sq, color))
+ guardedBy[V.ROOK] = true;
+ if (piece != V.KNIGHT && super.isAttackedByKnight(sq, color))
+ guardedBy[V.KNIGHT] = true;
+ if (piece != V.BISHOP && super.isAttackedByBishop(sq, color))
+ guardedBy[V.BISHOP] = true;
+ if (piece != V.QUEEN && super.isAttackedByQueen(sq, color))
+ guardedBy[V.QUEEN] = true;
+ if (piece != V.KING && super.isAttackedByKing(sq, color))
+ guardedBy[V.KING] = true;
+ Object.keys(guardedBy).forEach(pg => {
+ let steps = null;
+ if ([V.ROOK, V.KNIGHT, V.BISHOP].includes(pg)) steps = V.steps[pg];
+ else steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
+ const extraMoves =
+ super.getSlideNJumpMoves(
+ sq, steps, oneStep || [V.KNIGHT, V.KING].includes(pg))
+ .filter(m => {
+ return (
+ (piece != V.PAWN || m.end.x != lastRank) &&
+ (moves.every(mv => mv.end.x != m.end.x || mv.end.y != m.end.y))
+ );
+ });
+ moves = moves.concat(extraMoves);
+ });
+ return moves;
+ }