import { ChessRules } from "@/base_rules";
-export const VariantRules = class WormholeRules extends ChessRules {
+export class WormholeRules extends ChessRules {
+
static get HasFlags() {
return false;
}
return b;
}
+ static IsGoodPosition(position) {
+ if (position.length == 0) return false;
+ const rows = position.split("/");
+ if (rows.length != V.size.x) return false;
+ let kings = { "k": 0, "K": 0 };
+ for (let row of rows) {
+ let sumElts = 0;
+ for (let i = 0; i < row.length; i++) {
+ if (['K','k'].includes(row[i])) kings[row[i]]++;
+ if (['x'].concat(V.PIECES).includes(row[i].toLowerCase())) sumElts++;
+ else {
+ const num = parseInt(row[i], 10);
+ if (isNaN(num)) return false;
+ sumElts += num;
+ }
+ }
+ if (sumElts != V.size.y) return false;
+ }
+ if (Object.values(kings).some(v => v != 1)) return false;
+ return true;
+ }
+
getSquareAfter(square, movement) {
let shift1, shift2;
if (Array.isArray(movement[0])) {
}
}
// Captures
- const finalPieces = x + shiftX == lastRank
- ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
- : [V.PAWN];
for (let shiftY of [-1, 1]) {
const sq = this.getSquareAfter([x,y], [shiftX,shiftY]);
if (
- sq &&
+ !!sq &&
this.board[sq[0]][sq[1]] != V.EMPTY &&
this.canTake([x, y], [sq[0], sq[1]])
) {
+ const finalPieces = sq[0] == lastRank
+ ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN]
+ : [V.PAWN];
for (let piece of finalPieces) {
moves.push(
this.getBasicMove([x, y], [sq[0], sq[1]], {
return this.getJumpMoves(sq, V.steps[V.KING]);
}
- isAttackedByJump([x, y], colors, piece, steps) {
+ isAttackedByJump([x, y], color, piece, steps) {
for (let step of steps) {
const sq = this.getSquareAfter([x,y], step);
if (
sq &&
- this.getPiece(sq[0], sq[1]) === piece &&
- colors.includes(this.getColor(sq[0], sq[1]))
+ this.getPiece(sq[0], sq[1]) == piece &&
+ this.getColor(sq[0], sq[1]) == color
) {
return true;
}
return false;
}
- isAttackedByPawn([x, y], colors) {
- for (let c of colors) {
- const pawnShift = c == "w" ? 1 : -1;
- for (let i of [-1, 1]) {
- const sq = this.getSquareAfter([x,y], [pawnShift,i]);
- if (
- sq &&
- this.getPiece(sq[0], sq[1]) == V.PAWN &&
- this.getColor(sq[0], sq[1]) == c
- ) {
- return true;
- }
+ isAttackedByPawn([x, y], color) {
+ const pawnShift = (color == "w" ? 1 : -1);
+ for (let i of [-1, 1]) {
+ const sq = this.getSquareAfter([x,y], [pawnShift,i]);
+ if (
+ sq &&
+ this.getPiece(sq[0], sq[1]) == V.PAWN &&
+ this.getColor(sq[0], sq[1]) == color
+ ) {
+ return true;
}
}
return false;
}
- isAttackedByRook(sq, colors) {
- return this.isAttackedByJump(sq, colors, V.ROOK, V.steps[V.ROOK]);
+ isAttackedByRook(sq, color) {
+ return this.isAttackedByJump(sq, color, V.ROOK, V.steps[V.ROOK]);
}
- isAttackedByKnight(sq, colors) {
+ isAttackedByKnight(sq, color) {
// NOTE: knight attack is not symmetric in this variant:
// steps order need to be reversed.
return this.isAttackedByJump(
sq,
- colors,
+ color,
V.KNIGHT,
V.steps[V.KNIGHT].map(s => s.reverse())
);
}
- isAttackedByBishop(sq, colors) {
- return this.isAttackedByJump(sq, colors, V.BISHOP, V.steps[V.BISHOP]);
+ isAttackedByBishop(sq, color) {
+ return this.isAttackedByJump(sq, color, V.BISHOP, V.steps[V.BISHOP]);
}
- isAttackedByQueen(sq, colors) {
+ isAttackedByQueen(sq, color) {
return this.isAttackedByJump(
sq,
- colors,
+ color,
V.QUEEN,
V.steps[V.ROOK].concat(V.steps[V.BISHOP])
);
}
- isAttackedByKing(sq, colors) {
- return this.isAttackedByJump(sq, colors, V.KING, V.steps[V.KING]);
+ isAttackedByKing(sq, color) {
+ return this.isAttackedByJump(sq, color, V.KING, V.steps[V.KING]);
}
+ // NOTE: altering move in getBasicMove doesn't work and wouldn't be logical.
+ // This is a side-effect on board generated by the move.
static PlayOnBoard(board, move) {
board[move.vanish[0].x][move.vanish[0].y] = V.HOLE;
for (let psq of move.appear) board[psq.x][psq.y] = psq.c + psq.p;
}
getCurrentScore() {
- if (this.atLeastOneMove())
- return "*";
+ if (this.atLeastOneMove()) return "*";
// No valid move: I lose
return this.turn == "w" ? "0-1" : "1-0";
}
+ static get SEARCH_DEPTH() {
+ return 2;
+ }
+
evalPosition() {
let evaluation = 0;
for (let i = 0; i < V.size.x; i++) {
const piece = this.getPiece(move.start.x, move.start.y);
// Indicate start square + dest square, because holes distort the board
let notation =
- piece.toUpperCase() +
+ (piece != V.PAWN ? piece.toUpperCase() : "") +
V.CoordsToSquare(move.start) +
(move.vanish.length > move.appear.length ? "x" : "") +
V.CoordsToSquare(move.end);
notation += "=" + move.appear[0].p.toUpperCase();
return notation;
}
+
};