import { ChessRules, PiPo, Move } from "@/base_rules";
-export const VariantRules = class BenedictRules extends ChessRules {
+export class BenedictRules extends ChessRules {
+
static get HasEnpassant() {
return false;
}
- // TODO(?): some duplicated code in 2 next functions
- getSlideNJumpMoves([x, y], steps, oneStep) {
- let moves = [];
- outerLoop: for (let loop = 0; loop < steps.length; loop++) {
- const step = steps[loop];
- let i = x + step[0];
- let j = y + step[1];
- while (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY) {
- moves.push(this.getBasicMove([x, y], [i, j]));
- if (oneStep) continue outerLoop;
- i += step[0];
- j += step[1];
- }
- // No capture check: handled elsewhere (next method)
- }
- return moves;
+ static get PawnSpecs() {
+ return Object.assign(
+ {},
+ ChessRules.PawnSpecs,
+ { canCapture: false }
+ );
+ }
+
+ canTake() {
+ return false;
}
// Find possible captures from a square
return squares;
}
- getPotentialPawnMoves([x, y]) {
- const color = this.getColor(x, y);
- let moves = [];
- const sizeY = V.size.y;
- const shift = color == "w" ? -1 : 1;
- const startRank = color == "w" ? sizeY - 2 : 1;
- const firstRank = color == "w" ? sizeY - 1 : 0;
- const lastRank = color == "w" ? 0 : sizeY - 1;
-
- if (x + shift != lastRank) {
- // Normal moves
- if (this.board[x + shift][y] == V.EMPTY) {
- moves.push(this.getBasicMove([x, y], [x + shift, y]));
- if (
- [startRank, firstRank].includes(x) &&
- this.board[x + 2 * shift][y] == V.EMPTY
- ) {
- // Two squares jump
- moves.push(this.getBasicMove([x, y], [x + 2 * shift, y]));
- }
- }
- }
- else {
- // Promotion
- let promotionPieces = [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN];
- promotionPieces.forEach(p => {
- // Normal move
- if (this.board[x + shift][y] == V.EMPTY)
- moves.push(
- this.getBasicMove([x, y], [x + shift, y], { c: color, p: p })
- );
- });
- }
-
- // No en passant here
-
- return moves;
- }
-
- getPotentialRookMoves(sq) {
- return this.getSlideNJumpMoves(sq, V.steps[V.ROOK]);
- }
-
- getPotentialKnightMoves(sq) {
- return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep");
- }
-
- getPotentialBishopMoves(sq) {
- return this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]);
- }
-
- getPotentialQueenMoves(sq) {
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP])
- );
- }
-
- getPotentialKingMoves(sq) {
- // Initialize with normal (non-capturing) moves
- let noCaptures = this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- return noCaptures.concat(this.getCastleMoves(sq));
- }
-
// TODO: appear/vanish description of a move is too verbose for Benedict.
// => Would need a new "flipped" array, to be passed in Game.vue...
getPotentialMovesFrom([x, y]) {
let newAppear = [];
let newVanish = [];
V.PlayOnBoard(this.board, m);
- // If castling, m.appear has 2 elements:
- m.appear.forEach(a => {
- const flipped = this.findCaptures([a.x, a.y]);
- flipped.forEach(sq => {
- const piece = this.getPiece(sq[0],sq[1]);
- const pipoA = new PiPo({
- x:sq[0],
- y:sq[1],
- c:color,
- p:piece
- });
- const pipoV = new PiPo({
- x:sq[0],
- y:sq[1],
- c:oppCol,
- p:piece
+ // If castling, m.appear has 2 elements.
+ // In this case, consider the attacks of moving units only.
+ // (Sometimes the king or rook doesn't move).
+ for (let i = 0; i < m.appear.length; i++) {
+ const a = m.appear[i];
+ if (m.vanish[i].x != a.x || m.vanish[i].y != a.y) {
+ const flipped = this.findCaptures([a.x, a.y]);
+ flipped.forEach(sq => {
+ const piece = this.getPiece(sq[0],sq[1]);
+ const pipoA = new PiPo({
+ x:sq[0],
+ y:sq[1],
+ c:color,
+ p:piece
+ });
+ const pipoV = new PiPo({
+ x:sq[0],
+ y:sq[1],
+ c:oppCol,
+ p:piece
+ });
+ newAppear.push(pipoA);
+ newVanish.push(pipoV);
});
- newAppear.push(pipoA);
- newVanish.push(pipoV);
- });
- });
+ }
+ }
Array.prototype.push.apply(m.appear, newAppear);
Array.prototype.push.apply(m.vanish, newVanish);
V.UndoOnBoard(this.board, m);
return moves;
}
+ // Since it's used just for the king, and there are no captures:
+ isAttacked(sq, color) {
+ return false;
+ }
+
// No notion of check here:
getCheckSquares() {
return [];
// Stop at the first move found
atLeastOneMove() {
const color = this.turn;
- const oppCol = V.GetOppCol(color);
for (let i = 0; i < V.size.x; i++) {
for (let j = 0; j < V.size.y; j++) {
- if (this.board[i][j] != V.EMPTY && this.getColor(i, j) != oppCol) {
- const moves = this.getPotentialMovesFrom([i, j]);
- if (moves.length > 0)
- return true;
+ if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
+ if (this.getPotentialMovesFrom([i, j]).length > 0) return true;
}
}
}
const kp = this.kingPos[color];
if (this.getColor(kp[0], kp[1]) != color)
return color == "w" ? "0-1" : "1-0";
- if (this.atLeastOneMove())
- return "*";
+ if (this.atLeastOneMove()) return "*";
// Stalemate:
return "1/2";
}
+
+ getNotation(move) {
+ // Just remove flips:
+ const basicMove = {
+ appear: [move.appear[0]],
+ vanish: [move.vanish[0]],
+ start: move.start,
+ end: move.end
+ };
+ return super.getNotation(basicMove);
+ }
+
};