+ // Free to play any move:
+ const moves = super.getPotentialMovesFrom([x, y])
+ // Structure to avoid adding moves twice (can be action & move)
+ let hashMoves = {};
+ moves.forEach(m => { hashMoves[getMoveHash(m)] = true; });
+ const getMoveHash = (m) => {
+ return V.CoordsToSquare(m.start) + V.CoordsToSquare(m.end);
+ };
+ const addMoves = (dir, nbSteps) => {
+ const newMoves =
+ this.getMovesInDirection([x, y], [-dir[0], -dir[1]], nbSteps)
+ .filter(m => !movesHash[getMoveHash(m)]);
+ newMoves.forEach(m => { hashMoves[getMoveHash(m)] = true; });
+ Array.prototype.push.apply(moves, newMoves);
+ };
+ const pawnShift = (color == 'w' ? -1 : 1);
+ const pawnStartRank = (color == 'w' ? 6 : 1);
+ // [x, y] is pushed by 'color'
+ for (let step of V.steps[V.KNIGHT]) {
+ const [i, j] = [x + step[0], y + step[1]];
+ if (V.OnBoard(i, j) && this.board[i][j] != V.EMPTY) {
+ // Only can move away from a knight (can pull but must move first)
+ Array.prototype.push.apply(
+ moves,
+ this.getMovesInDirection([x, y], [-step[0], -step[1]], 1)
+ .filter(m => !movesHash[getMoveHash(m)])
+ );
+ }
+ }
+ for (let step in V.steps[V.ROOK].concat(V.steps[V.BISHOP])) {
+ let [i, j] = [x + step[0], y + step[1]];
+ while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
+ i += step[0];
+ j += step[1];
+ }
+ if (
+ V.OnBoard(i, j) &&
+ this.board[i][j] != V.EMPTY &&
+ this.getColor(i, j) == color
+ ) {
+ const deltaX = Math.abs(i - x);
+ const deltaY = Math.abs(j - y);
+ // Can a priori go both ways, except with pawns
+ switch (this.getPiece(i, j)) {
+ case V.PAWN:
+ if (deltaX <= 2 && deltaY <= 1) {
+ const pColor = this.getColor(x, y);
+ if (pColor == color && deltaY == 0) {
+ // Pushed forward
+ const maxSteps = (i == pawnStartRank && deltaX == 1 ? 2 : 1);
+ addMoves(step, maxSteps);
+ }
+ else if (pColor != color && deltaY == 1 && deltaX == 1)
+ // Pushed diagonally
+ addMoves(step, 1);
+ }
+ break;
+ case V.ROOK:
+ if (deltaX == 0 || deltaY == 0) addMoves(step);
+ break;
+ case V.KNIGHT:
+ if (deltaX + deltaY == 3 && (deltaX == 1 || deltaY == 1))
+ addMoves(step, 1);
+ break;
+ case V.BISHOP:
+ if (deltaX == deltaY) addMoves(step);
+ break;
+ case V.QUEEN:
+ if (deltaX == 0 || deltaY == 0 || deltaX == deltaY)
+ addMoves(step);
+ break;
+ case V.KING:
+ if (deltaX <= 1 && deltaY <= 1) addMoves(step, 1);
+ break;
+ }
+ }
+ }
+ return moves;