+# Improvements
+
+Find a way to generalize getCastleMoves and getPotentialPawnMoves,
+to limit code duplication.
+
# New variants
Landing pieces from empty board:
https://www.chessvariants.com/diffsetup.dir/unachess.html
Cannibal Chess with forced captures.
-Knightrelay: implement "official" version as Knightrelay v1
-
-Antiking: implement v1 (deterministic) https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html
-
S-chess https://en.wikipedia.org/wiki/Seirawan_chess
Generator variant, called "Matrix" ?
// What are the king moves from square x,y ?
getPotentialKingMoves(sq) {
// Initialize with normal moves
- const moves = this.getSlideNJumpMoves(
+ let moves = this.getSlideNJumpMoves(
sq,
V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
"oneStep"
);
- return moves.concat(this.getCastleMoves(sq));
+ if (V.HasCastle) moves = moves.concat(this.getCastleMoves(sq));
+ return moves;
}
getCastleMoves([x, y]) {
"In the shadow": "In the shadow",
"Get strong at self-mate": "Get strong at self-mate",
"Give three checks": "Give three checks",
- "Keep antiking in check": "Keep antiking in check",
+ "Keep antiking in check (v1)": "Keep antiking in check (v1)",
+ "Keep antiking in check (v2)": "Keep antiking in check (v2)",
"Kings cross the 8x8 board": "Kings cross the 8x8 board",
"Kings cross the 11x11 board": "Kings cross the 11x11 board",
"Laws of attraction": "Laws of attraction",
"In the shadow": "En la sombra",
"Get strong at self-mate": "Progreso en mates asistidos",
"Give three checks": "Dar tres jaques",
- "Keep antiking in check": "Mantener el antirey en jaque",
+ "Keep antiking in check (v1)": "Mantener el antirey en jaque (v1)",
+ "Keep antiking in check (v2)": "Mantener el antirey en jaque (v2)",
"Kings cross the 8x8 board": "Los reyes cruzan el 8x8 tablero",
"Kings cross the 11x11 board": "Los reyes cruzan el 11x11 tablero",
"Laws of attraction": "Las leyes de las atracciones",
"In the shadow": "Dans l'ombre",
"Get strong at self-mate": "Progressez en mats aidés",
"Give three checks": "Donnez trois échecs",
- "Keep antiking in check": "Gardez l'antiroi en échec",
+ "Keep antiking in check (v1)": "Gardez l'antiroi en échec (v1)",
+ "Keep antiking in check (v2)": "Gardez l'antiroi en échec (v2)",
"Kings cross the 8x8 board": "Les rois traversent l'échiquier 8x8",
"Kings cross the 11x11 board": "Les rois traversent l'échiquier 11x11",
"Laws of attraction": "Les lois de l'attraction",
--- /dev/null
+p.boxed.
+ You have a king and an antiking. King cannot be let in check, but antiking
+ must always stay under check. Antiking captures his own kind.
+
+p.
+ A new piece is introduced: the antiking, noted by the letter 'A'.
+ This piece must always remain under (orthodox) check: it is
+ considered in (anti-)check when not attacked by any enemy piece. In such a
+ situation, the antiking must move immediately to an attacked square.
+
+p.
+ The antiking is a royal figure, and thus cannot be captured.
+ It captures only the pieces of his color.
+ Antikings don't give check, and kings do not attack antikings.
+
+figure.diagram-container
+ .diagram
+ | fen:2prbkqA/2p1nnbr/2pppppp/8/8/PPPPPP2/RBNN1P2/aQKBRP2:
+ figcaption Initial setup: antikings stand in the corners.
+
+h3 Unusual moves
+
+ul
+ li.
+ Pawns are Berolina Pawns, which move diagonally forward one square
+ without capturing, or move one square straight forward to capture.
+ li.
+ If a King or Anti-King has not yet moved, it may make as its first
+ move a Knight's leap to an empty square.
+
+h3 End of the game
+
+p There are three ways to win:
+ol
+ li Checkmate opponent king
+ li Anti-checkmate opponent antiking
+ li Give a double check, as on the following diagram
+
+figure.diagram-container
+ .diagram
+ | fen:2pr3A/2pb1qbr/2p1pkQp/2pnp1n1/1PPN4/PPB1PPN1/1K2RP2/a2BRP2:
+ figcaption After Qb1xg6#
+
+h3 More information
+
+p
+ a(href="https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html")
+ | Antiking chess
+ | on chessvariants.com.
+
+p Inventor: Peter Aronson (2002)
--- /dev/null
+p.boxed.
+ Tienes un rey y un "antirey". El rey no puede estar en jaque al final de un
+ turno, pero el antirey siempre debe estar en jaque. Este último captura las
+ piezas de su color.
+
+p.
+ Se presenta una nueva pieza: el antirey, denotado por la letra 'A'.
+ Esta pieza debe estar siempre en jaque (ortodoxo): se
+ considera en (anti-)jaque cuando no es atacada por ninguna pieza enemiga.
+ En este caso, el antirey debe unirse inmediatamente a una casilla atacada.
+
+p.
+ El antirey es una pieza real, por lo que no puede ser capturado.
+ Ella captura solo las piezas de su color.
+ Los antireyes no dan jaque, y los reyes no atacan a los antireyes.
+
+figure.diagram-container
+ .diagram
+ | fen:2prbkqA/2p1nnbr/2pppppp/8/8/PPPPPP2/RBNN1P2/aQKBRP2:
+ figcaption Posición inicial: los antireyes están en las esquinas.
+
+h3 Jugadas inusuales
+
+ul
+ li.
+ Los peones son peones Berolina, que se mueven diagonalmente una
+ casilla y captura avanzando verticalmente.
+ li.
+ Si un rey o anti-rey aún no se ha movido, puede realizar
+ un salto de caballo a una casilla vacía.
+
+h3 Fin de la partida
+
+p Hay tres maneras de ganar:
+ol
+ li Mater el rey contrario
+ li "Anti-mater" el antirey contrario
+ li Dar un doble jaque, como en el siguiente diagrama
+
+figure.diagram-container
+ .diagram
+ | fen:2pr3A/2pb1qbr/2p1pkQp/2pnp1n1/1PPN4/PPB1PPN1/1K2RP2/a2BRP2:
+ figcaption Después de Qb1xg6#
+
+h3 Más información
+
+p
+ | La
+ a(href="https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html")
+ | variante Antiking
+ | en chessvariants.com.
+
+p Inventor: Peter Aronson (2002)
--- /dev/null
+p.boxed.
+ Vous disposez d'un roi et d'un "antiroi". Le roi ne peut pas se retrouver
+ en échec à la fin d'un tour, mais l'antiroi doit lui toujours être en échec.
+ Ce dernier capture les pièces de sa couleur.
+
+p.
+ Une nouvelle pièce fait son apparition : l'antiroi, noté par la lettre 'A'.
+ Cette pièce doit toujour rester en échec (orthodoxe) :
+ elle est considérée en (anti-)échec lorsqu'elle n'est attaquée
+ par aucune pièce ennemie. Dans ce cas, l'antiroi doit immédiatement
+ rejoindre une case attaquée.
+
+p.
+ L'antiroi est une pièce royale, elle ne peut donc pas être capturée.
+ Elle capture seulement les pièces de sa couleur.
+ Les antirois ne donnent pas échec, et les rois n'attaquent pas les antirois.
+
+
+figure.diagram-container
+ .diagram
+ | fen:2prbkqA/2p1nnbr/2pppppp/8/8/PPPPPP2/RBNN1P2/aQKBRP2:
+ figcaption Position initiale : les antirois sont dans les coins.
+
+h3 Coups inhabituels
+
+ul
+ li.
+ Les pions sont des pions Berolina, qui se déplacent en diagonale d'une
+ case et capturent en avançant verticalement.
+ li.
+ Si un roi ou antiroi n'a pas encore bougé, il peut effectuer
+ un saut de cavalier vers une case vide.
+
+h3 Fin de partie
+
+p Il y a trois façons de gagner :
+ol
+ li Mater le roi adverse
+ li "Anti-mater" l'anti-roi adverse
+ li Donner un échec double, comme sur le diagramme suivant
+
+figure.diagram-container
+ .diagram
+ | fen:2pr3A/2pb1qbr/2p1pkQp/2pnp1n1/1PPN4/PPB1PPN1/1K2RP2/a2BRP2:
+ figcaption Après Qb1xg6#
+
+h3 Plus d'information
+
+p
+ | La
+ a(href="https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html")
+ | variante Antiking
+ | sur chessvariants.com.
+
+p Inventeur : Peter Aronson (2002)
must always stay under check. Antiking captures his own kind.
p.
- A new piece is introduced: the antiking, noted by the letter 'A' in diagrams
- and PGNs. This piece must always remain under (orthodox) check: it is
+ A new piece is introduced: the antiking, noted by the letter 'A'.
+ This piece must always remain under (orthodox) check: it is
considered in (anti-)check when not attacked by any enemy piece. In such a
situation, the antiking must move immediately to an attacked square.
p.
The antiking is a royal figure, and thus cannot be captured.
- It captures only the pieces of his color (to help checkmating the opponent's
- antiking, but this also complicates standard checkmate).
+ It captures only the pieces of his color.
+ Antikings don't give check, and kings do not attack antikings.
figure.diagram-container
.diagram
| fen:rnbqkbnr/pppppppp/3A4/8/8/3a4/PPPPPPPP/RNBQKBNR c5,d5,e5:
figcaption Marked squares are not allowed antiking moves.
-ul
- li.
- Although antiking captures his color, it doesn't check his king - it
- doesn't check the opponent's king either.
- li.
- Since it would allow a basic tactic (keep antiking touching opponent's
- king), kings do not attack antikings.
-
h3 End of the game
-p There are two ways to win:
+p There are three ways to win:
ol
- li Checkmate opponent king
- li Anti-checkmate opponent antiking
-p.
- ...Or do both at the same time, as on the following diagram after 3.Qxf7#
- (the black antiking was on g3).
+ li Checkmate the opponent king
+ li "Anti-checkmate" the opponent antiking
+ li Give a double check, as on the following diagram
figure.diagram-container
.diagram
piezas de su color.
p.
- Se presenta una nueva pieza: el antirey, denotado por la letra 'A' en los
- diagramas y PGNs. Esta pieza debe estar siempre en jaque (ortodoxo): se
+ Se presenta una nueva pieza: el antirey, denotado por la letra 'A'.
+ Esta pieza debe estar siempre en jaque (ortodoxo): se
considera en (anti-)jaque cuando no es atacada por ninguna pieza enemiga.
En este caso, el antirey debe unirse inmediatamente a una casilla atacada.
p.
El antirey es una pieza real, por lo que no puede ser capturado.
- Ella captura solo las piezas de su color (esto ayuda a mate el anti-rey del
- oponente, pero complica el mate ortodoxo).
+ Ella captura solo las piezas de su color.
+ Los antireyes no dan jaque, y los reyes no atacan a los antireyes.
figure.diagram-container
.diagram
| fen:rnbqkbnr/pppppppp/3A4/8/8/3a4/PPPPPPPP/RNBQKBNR c5,d5,e5:
figcaption Las casillas mostradas no son legales jugadas de antirey.
-ul
- li.
- Aunque el antirey captura las piezas de su color, no da jaque a su rey,
- ni tampoco al rey contrario.
- li.
- Los reyes no atacan a los antireyes (de color opuesto). De hecho, esto
- permitiría aplicar un método simple para nunca estar en "anti-jaque":
- permanecer pegado al rey contrario.
-
h3 Fin de la partida
-p Hay dos maneras de ganar:
+p Hay tres maneras de ganar:
ol
li Mater el rey contrario
li "Anti-mater" el antirey contrario
-p.
- ...O haga ambas cosas al mismo tiempo, como se muestra en el siguiente
- diagrama después de 3.Qxf7# (el antirey negro estaba en g3).
+ li Dar un doble jaque, como en el siguiente diagrama
figure.diagram-container
.diagram
Ce dernier capture les pièces de sa couleur.
p.
- Une nouvelle pièce fait son apparition : l'antiroi, noté par la lettre 'A'
- sur les diagrammes et PGNs. Cette pièce doit toujour rester en échec
- (orthodoxe) : elle est considérée en (anti-)échec lorsqu'elle n'est attaquée
- par aucune pièce ennemie. Dans ce cas, l'antiroi doit immédiatement
- rejoindre une case attaquée.
+ Une nouvelle pièce fait son apparition : l'antiroi, noté par la lettre 'A'.
+ Cette pièce doit toujour rester en échec (orthodoxe) : elle est considérée
+ en (anti-)échec lorsqu'elle n'est attaquée par aucune pièce ennemie.
+ Dans ce cas, l'antiroi doit immédiatement rejoindre une case attaquée.
p.
L'antiroi est une pièce royale, elle ne peut donc pas être capturée.
- Elle capture seulement les pièces de sa couleur (cela aide à mater
- l'anti-roi adverse, mais complique le mat orthodoxe).
+ Elle capture seulement les pièces de sa couleur.
+ Les antirois ne donnent pas échec, et les rois n'attaquent pas les antirois.
figure.diagram-container
.diagram
| fen:rnbqkbnr/pppppppp/3A4/8/8/3a4/PPPPPPPP/RNBQKBNR c5,d5,e5:
figcaption Les cases indiquées ne sont pas des coups d'anti-roi légaux.
-ul
- li.
- Bien que l'antiroi capture les pièces de son camp, il ne met pas
- en échec son roi - ni d'ailleurs le roi adverse.
- li.
- Les rois n'attaquent pas les antirois (de couleur opposée).
- En effet ceci permettrait d'appliquer une méthode simple pour ne jamais
- être en "anti-échec" : rester collé au roi adverse.
-
h3 Fin de partie
-p Il y a deux façons de gagner :
+p Il y a trois façons de gagner :
ol
li Mater le roi adverse
li "Anti-mater" l'anti-roi adverse
-p.
- ...Ou faire les deux en même temps, comme sur le diagramme suivant après
- 3.Qxf7# (l'antiroi noir était en g3).
+ li Donner un échec double, comme sur le diagramme suivant
figure.diagram-container
.diagram
--- /dev/null
+import { ChessRules } from "@/base_rules";
+import { ArrayFun } from "@/utils/array";
+import { randInt } from "@/utils/alea";
+
+export const VariantRules = class Antiking1Rules extends ChessRules {
+ static get HasEnpassant() {
+ return false;
+ }
+
+ static get HasCastle() {
+ return false;
+ }
+
+ static get ANTIKING() {
+ return "a";
+ }
+
+ static get PIECES() {
+ return ChessRules.PIECES.concat([V.ANTIKING]);
+ }
+
+ getPpath(b) {
+ return b[1] == "a" ? "Antiking/" + b : b;
+ }
+
+ setOtherVariables(fen) {
+ super.setOtherVariables(fen);
+ this.antikingPos = { w: [-1, -1], b: [-1, -1] };
+ const rows = V.ParseFen(fen).position.split("/");
+ for (let i = 0; i < rows.length; i++) {
+ let k = 0;
+ for (let j = 0; j < rows[i].length; j++) {
+ switch (rows[i].charAt(j)) {
+ case "a":
+ this.antikingPos["b"] = [i, k];
+ break;
+ case "A":
+ this.antikingPos["w"] = [i, k];
+ break;
+ default: {
+ const num = parseInt(rows[i].charAt(j));
+ if (!isNaN(num)) k += num - 1;
+ }
+ }
+ k++;
+ }
+ }
+ }
+
+ // (Anti)King flags at 1 (true) if they can knight-jump
+ setFlags(fenflags) {
+ this.kingFlags = {
+ // King then antiking
+ w: [...Array(2).fill(false)],
+ b: [...Array(2).fill(false)]
+ };
+ for (let c of ["w", "b"]) {
+ for (let i = 0; i < 2; i++)
+ this.kingFlags[c][i] = fenflags.charAt((c == "w" ? 0 : 2) + i) == "1";
+ }
+ }
+
+ aggregateFlags() {
+ return this.kingFlags;
+ }
+
+ disaggregateFlags(flags) {
+ this.kingFlags = flags;
+ }
+
+ getFlagsFen() {
+ // Return kings flags
+ let flags = "";
+ for (let c of ["w", "b"]) {
+ for (let i = 0; i < 2; i++) flags += this.kingFlags[c][i] ? "1" : "0";
+ }
+ return flags;
+ }
+
+ canTake([x1, y1], [x2, y2]) {
+ const piece1 = this.getPiece(x1, y1);
+ const piece2 = this.getPiece(x2, y2);
+ const color1 = this.getColor(x1, y1);
+ const color2 = this.getColor(x2, y2);
+ return (
+ piece2 != "a" &&
+ ((piece1 != "a" && color1 != color2) ||
+ (piece1 == "a" && color1 == color2))
+ );
+ }
+
+ getPotentialMovesFrom([x, y]) {
+ let moves = [];
+ let addKnightJumps = false;
+ const piece = this.getPiece(x, y);
+ const color = this.getColor(x, y);
+ if (piece == V.ANTIKING) {
+ moves = this.getPotentialAntikingMoves([x, y]);
+ addKnightJumps = this.kingFlags[color][1];
+ } else {
+ moves = super.getPotentialMovesFrom([x, y]);
+ if (piece == V.KING) addKnightJumps = this.kingFlags[color][0];
+ }
+ if (addKnightJumps) {
+ // Add potential knight jump to (anti)kings
+ const knightJumps = super.getPotentialKnightMoves([x, y]);
+ // Remove captures (TODO: could be done more efficiently...)
+ moves = moves.concat(knightJumps.filter(m => m.vanish.length == 1));
+ }
+ return moves;
+ }
+
+ getPotentialPawnMoves([x, y]) {
+ const color = this.turn;
+ let moves = [];
+ const [sizeX, sizeY] = [V.size.x, V.size.y];
+ const shiftX = color == "w" ? -1 : 1;
+ const startRank = color == "w" ? sizeX - 2 : 1;
+ const lastRank = color == "w" ? 0 : sizeX - 1;
+ const finalPieces =
+ x + shiftX == lastRank ? [V.ROOK, V.KNIGHT, V.BISHOP, V.QUEEN] : [V.PAWN];
+
+ // One square diagonally
+ for (let shiftY of [-1, 1]) {
+ if (this.board[x + shiftX][y + shiftY] == V.EMPTY) {
+ for (let piece of finalPieces) {
+ moves.push(
+ this.getBasicMove([x, y], [x + shiftX, y + shiftY], {
+ c: color,
+ p: piece
+ })
+ );
+ }
+ }
+ }
+ // Capture
+ if (
+ this.board[x + shiftX][y] != V.EMPTY &&
+ this.canTake([x, y], [x + shiftX, y])
+ ) {
+ for (let piece of finalPieces)
+ moves.push(
+ this.getBasicMove([x, y], [x + shiftX, y], { c: color, p: piece })
+ );
+ }
+
+ return moves;
+ }
+
+ getPotentialAntikingMoves(sq) {
+ // The antiking moves like a king (only captured colors differ)
+ return this.getSlideNJumpMoves(
+ sq,
+ V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
+ "oneStep"
+ );
+ }
+
+ isAttacked(sq, color) {
+ return (
+ super.isAttacked(sq, color) ||
+ this.isAttackedByAntiking(sq, color)
+ );
+ }
+
+ isAttackedByPawn([x, y], color) {
+ let pawnShift = (color == "w" ? 1 : -1);
+ if (x + pawnShift >= 0 && x + pawnShift < V.size.x) {
+ if (
+ this.getPiece(x + pawnShift, y) == V.PAWN &&
+ this.getColor(x + pawnShift, y) == color
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ isAttackedByKing([x, y], color) {
+ // Antiking is not attacked by king:
+ if (this.getPiece(x, y) == V.ANTIKING) return false;
+ return this.isAttackedBySlideNJump(
+ [x, y],
+ color,
+ V.KING,
+ V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
+ "oneStep"
+ );
+ }
+
+ isAttackedByAntiking([x, y], color) {
+ // (Anti)King is not attacked by antiking
+ if ([V.KING, V.ANTIKING].includes(this.getPiece(x, y))) return false;
+ return this.isAttackedBySlideNJump(
+ [x, y],
+ color,
+ V.ANTIKING,
+ V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
+ "oneStep"
+ );
+ }
+
+ underCheck(color) {
+ const oppCol = V.GetOppCol(color);
+ let res =
+ this.isAttacked(this.kingPos[color], oppCol) ||
+ !this.isAttacked(this.antikingPos[color], oppCol);
+ return res;
+ }
+
+ getCheckSquares(color) {
+ let res = [];
+ const oppCol = V.GetOppCol(color);
+ if (this.isAttacked(this.kingPos[color], oppCol))
+ res.push(JSON.parse(JSON.stringify(this.kingPos[color])));
+ if (!this.isAttacked(this.antikingPos[color], oppCol))
+ res.push(JSON.parse(JSON.stringify(this.antikingPos[color])));
+ return res;
+ }
+
+ postPlay(move) {
+ super.postPlay(move);
+ const piece = move.vanish[0].p;
+ const c = move.vanish[0].c;
+ // Update antiking position, and kings flags
+ if (piece == V.ANTIKING) {
+ this.antikingPos[c][0] = move.appear[0].x;
+ this.antikingPos[c][1] = move.appear[0].y;
+ this.kingFlags[c][1] = false;
+ } else if (piece == V.KING) this.kingFlags[c][0] = false;
+ }
+
+ postUndo(move) {
+ super.postUndo(move);
+ const c = move.vanish[0].c;
+ if (move.vanish[0].p == V.ANTIKING)
+ this.antikingPos[c] = [move.start.x, move.start.y];
+ }
+
+ getCurrentScore() {
+ if (this.atLeastOneMove())
+ return "*";
+
+ const color = this.turn;
+ const oppCol = V.GetOppCol(color);
+ if (
+ !this.isAttacked(this.kingPos[color], oppCol) &&
+ this.isAttacked(this.antikingPos[color], oppCol)
+ ) {
+ return "1/2";
+ }
+ return color == "w" ? "0-1" : "1-0";
+ }
+
+ static get VALUES() {
+ return Object.assign(
+ { a: 1000 },
+ ChessRules.VALUES
+ );
+ }
+
+ static GenRandInitFen() {
+ // Always deterministic setup
+ return "2prbkqA/2p1nnbr/2pppppp/8/8/PPPPPP2/RBNN1P2/aQKBRP2 w 0 1111";
+ }
+
+ static get SEARCH_DEPTH() {
+ return 2;
+ }
+};
import { ArrayFun } from "@/utils/array";
import { randInt } from "@/utils/alea";
-export const VariantRules = class AntikingRules extends ChessRules {
+export const VariantRules = class Antiking2Rules extends ChessRules {
static get ANTIKING() {
return "a";
}
const color2 = this.getColor(x2, y2);
return (
piece2 != "a" &&
- ((piece1 != "a" && color1 != color2) ||
- (piece1 == "a" && color1 == color2))
+ (
+ (piece1 != "a" && color1 != color2) ||
+ (piece1 == "a" && color1 == color2)
+ )
);
}
}
getPotentialAntikingMoves(sq) {
+ // The antiking moves like a king (only captured colors differ)
return this.getSlideNJumpMoves(
sq,
V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
isAttackedByKing([x, y], color) {
// Antiking is not attacked by king:
if (this.getPiece(x, y) == V.ANTIKING) return false;
- return this.isAttackedBySlideNJump(
- [x, y],
- color,
- V.KING,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
+ return super.isAttackedByKing([x, y], color);
}
isAttackedByAntiking([x, y], color) {
}
getCheckSquares(color) {
- let res = super.getCheckSquares(color);
- if (!this.isAttacked(this.antikingPos[color], V.GetOppCol(color)))
+ let res = [];
+ const oppCol = V.GetOppCol(color);
+ if (this.isAttacked(this.kingPos[color], oppCol))
+ res.push(JSON.parse(JSON.stringify(this.kingPos[color])));
+ if (!this.isAttacked(this.antikingPos[color], oppCol))
res.push(JSON.parse(JSON.stringify(this.antikingPos[color])));
return res;
}
return false;
}
+ static get HasCastle() {
+ return false;
+ }
+
static get HasEnpassant() {
return false;
}
return super.getPotentialQueenMoves(sq);
}
- getPotentialKingMoves(sq) {
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
// isAttacked() is OK because the immobilizer doesn't take
isAttackedByPawn([x, y], color) {
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));
- }
-
// No "under check" verifications:
getCastleMoves([x, y]) {
const c = this.getColor(x, y);
return moves;
}
- getPotentialKingMoves(sq) {
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
filterValid(moves) {
const filteredMoves = super.filterValid(moves);
// If at least one full move made, everything is allowed:
return false;
}
+ static get HasCastle() {
+ return false;
+ }
+
static get HasEnpassant() {
return false;
}
return mv;
}
- // What are the king moves from square x,y ?
- getPotentialKingMoves(sq) {
- // No castling:
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
filterValid(moves) {
return moves;
}
return false;
}
+ static get HasCastle() {
+ return false;
+ }
+
static get HasEnpassant() {
return false;
}
return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT]);
}
- // What are the king moves from square x,y ?
- getPotentialKingMoves(sq) {
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
filterValid(moves) {
if (moves.length == 0) return [];
const color = this.turn;
return false;
}
+ static get HasCastle() {
+ return false;
+ }
+
static get HasEnpassant() {
return false;
}
);
}
- getPotentialKingMoves(sq) {
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
isAttackedByBishop(sq, color) {
return this.isAttackedBySlideNJump(
sq,
return false;
}
+ static get HasCastle() {
+ return false;
+ }
+
getPotentialPawnMoves([x, y]) {
let moves = super.getPotentialPawnMoves([x, y]);
return moves;
}
- getPotentialKingMoves(sq) {
- // No castle:
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
- }
-
// Trim all non-capturing moves (not the most efficient, but easy)
static KeepCaptures(moves) {
return moves.filter(m => m.vanish.length == 2);
return false;
}
- static get HasEnpassant() {
+ static get HasCastle() {
return false;
}
- getPotentialKingMoves(sq) {
- // No castle
- return this.getSlideNJumpMoves(
- sq,
- V.steps[V.ROOK].concat(V.steps[V.BISHOP]),
- "oneStep"
- );
+ static get HasEnpassant() {
+ return false;
}
static GenRandInitFen(randomness) {
('Alice', 'Both sides of the mirror'),
('Allmate1', 'Mate any piece (v1)'),
('Allmate2', 'Mate any piece (v2)'),
- ('Antiking', 'Keep antiking in check'),
+ ('Antiking1', 'Keep antiking in check (v1)'),
+ ('Antiking2', 'Keep antiking in check (v2)'),
('Antimatter', 'Dangerous collisions'),
('Arena', 'Middle battle'),
('Atomic', 'Explosive captures'),