+Revise variants code by using more aggregate/disaggregate flags functions?
+
# New variants
8-pieces https://www.youtube.com/watch?v=XZ8K02Da7Ps&list=PLRyjH8DPuzTBiym6lA0r84P8N0HnTtZyN&index=6&t=0s
https://www.chessvariants.com/rules/8-piece-chess "Eightpieces"
Rugby http://www.echecspourtous.com/?page_id=7945
-"Capture" Chess (idea of opperwezen, maybe not new): captures are forced,
-but the goal is still to checkmate (not lose all material).
-
Cannibal Chess with forced captures.
Knightrelay: implement "official" version as Knightrelay v1
play(move) {
// DEBUG:
// if (!this.states) this.states = [];
-// const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
+// const stateFen = this.getBaseFen() + this.getTurnFen();// + this.getFlagsFen();
// this.states.push(stateFen);
if (V.HasFlags) move.flags = JSON.stringify(this.aggregateFlags()); //save flags (for undo)
this.unupdateVariables(move);
// DEBUG:
-// const stateFen = this.getBaseFen() + this.getTurnFen() + this.getFlagsFen();
+// const stateFen = this.getBaseFen() + this.getTurnFen();// + this.getFlagsFen();
// if (stateFen != this.states[this.states.length-1]) debugger;
// this.states.pop();
}
v-model="st.settings.gotonext"
)
fieldset
- label(for="setRandomness") {{ st.tr["Randomness against computer"] }}
+ label(for="setRandomness") {{ st.tr["Randomness"] }}
select#setRandomness(v-model="st.settings.randomness")
option(value="0") {{ st.tr["Deterministic"] }}
option(value="1") {{ st.tr["Symmetric random"] }}
<style lang="sass" scoped>
[type="checkbox"].modal+div .card
- max-width: 767px
+ max-width: 520px
max-height: 100%
#flagContainer
display: inline-block
Problems: "Problems",
"Random?": "Random?",
"Randomness": "Randomness",
- "Randomness against computer": "Randomness against computer",
Refuse: "Refuse",
Register: "Register",
"Registration complete! Please check your emails now": "Registration complete! Please check your emails now",
"Exotic captures": "Exotic captures",
"Explosive captures": "Explosive captures",
"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",
- "Kings cross the board": "Kings cross the board",
+ "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",
"Long jumps over pieces": "Long jumps over pieces",
"Lose all pieces": "Lose all pieces",
+ "Mandatory captures": "Mandatory captures",
"Mate any piece (v1)": "Mate any piece (v1)",
"Mate any piece (v2)": "Mate any piece (v2)",
"Mate the knight": "Mate the knight",
Problems: "Problemas",
"Random?": "Aleatorio?",
"Randomness": "Grado de azar",
- "Randomness against computer": "Grado de azar contra la computadora",
Refuse: "Rechazar",
Register: "Registrarse",
"Registration complete! Please check your emails now": "¡Registro completo! Revise sus correos electrónicos ahora",
"Exotic captures": "Capturas exóticas",
"Explosive captures": "Capturas explosivas",
"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",
- "Kings cross the board": "Los reyes cruzan el tablero",
+ "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",
"Long jumps over pieces": "Saltos largos sobre las piezas",
"Lose all pieces": "Perder todas las piezas",
+ "Mandatory captures": "Capturas obligatorias",
"Mate any piece (v1)": "Matar cualquier pieza (v1)",
"Mate any piece (v2)": "Matar cualquier pieza (v2)",
"Mate the knight": "Matar el caballo",
Problems: "Problèmes",
"Random?": "Aléatoire?",
"Randomness": "Degré d'aléa",
- "Randomness against computer": "Degré d'aléa contre l'ordinateur",
Refuse: "Refuser",
Register: "S'enregistrer",
"Registration complete! Please check your emails now": "Enregistrement terminé ! Allez voir vos emails maintenant",
"Exotic captures": "Captures exotiques",
"Explosive captures": "Captures explosives",
"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",
- "Kings cross the board": "Les rois traversent l'échiquier",
+ "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",
"Long jumps over pieces": "Sauts longs par dessus les pièces",
"Lose all pieces": "Perdez toutes les pièces",
+ "Mandatory captures": "Captures obligatoires",
"Mate any piece (v1)": "Matez n'importe quelle pièce (v1)",
"Mate any piece (v2)": "Matez n'importe quelle pièce (v2)",
"Mate the knight": "Matez le cavalier",
--- /dev/null
+p.boxed
+ | Captures are mandatory. Win by checkmating.
+
+p.
+ Everything is the same as in orthodox rules, except that when possible,
+ captures are forced.
+ The goal is still to checkmate, and stalemate is a draw.
+
+p.
+ Some opening traps can be mentioned, like on the following diagram:
+ Qxd7+ will be forced, losing the queen.
+
+figure.diagram-container
+ .diagram
+ | fen:rnbqkbnr/pppp1pp1/7p/4P3/8/8/PPP1PPPP/RNBQKBNR:
+ figcaption After 1.d4?? e5 2.dxe5 h6.
+
+h3 More information
+
+p.
+ This idea was suggested recently (2020) by Vincent Rothuis.
+ It's simple so probably not new, but I never saw it before.
--- /dev/null
+p.boxed
+ Las capturas son obligatorias. Gana por jaque mate.
+
+p.
+ Todo va como el ajedrez ortodoxo, pero cuando es posible
+ las capturas son forzadas.
+ El objetivo aún es de matar, y el empate es tablas.
+
+p.
+ Se pueden mencionar algunas trampas de apertura,
+ como en el siguiente diagrama: Qxd7 será forzado, perdiendo a la dama.
+
+figure.diagram-container
+ .diagrama
+ | fen:rnbqkbnr/pppp1pp1/7p/4P3/8/8/PPP1PPPP/RNBQKBNR:
+ figcaption Después de 1.d4?? e5 2.dxe5 h6.
+
+h3 Más información
+
+p.
+ Esta idea fue sugerida recientemente (2020) por Vincent Rothuis.
+ Es simple, así que probablemente no sea nuevo, pero nunca
+ previamente encontrado.
--- /dev/null
+p.boxed
+ | Les captures sont obligatoires. Gagnez par échec et mat.
+
+p.
+ Tout se déroule comme aux échecs orthodoxes, mais quand elles sont possibles
+ les captures sont forcées.
+ L'objectif est toujours de mater, et le pat fait nulle.
+
+p.
+ Quelques pièges d'ouvertures peuvent être mentionnés,
+ comme sur le diagramme suivant : Qxd7 sera forcé, perdant la dame.
+
+figure.diagram-container
+ .diagram
+ | fen:rnbqkbnr/pppp1pp1/7p/4P3/8/8/PPP1PPPP/RNBQKBNR:
+ figcaption Après 1.d4?? e5 2.dxe5 h6.
+
+h3 Plus d'information
+
+p.
+ Cette idée a été suggérée récemment (2020) par Vincent Rothuis.
+ Elle est simple donc probablement pas nouvelle, mais je ne l'ai jamais
+ rencontrée auparavant.
p.boxed
- | Win by losing all your pieces. Capture is mandatory.
+ | Win by losing all your pieces except the king. Capture is mandatory.
p.
- The goal is to lose all pieces, or get stalemated like on the following diagram.
- The king has no royal status: it can be taken as any other piece.
- Thus, there is no castle rule, no checks.
-
-p Captures are mandatory, but when several capturing moves are possible you can choose.
+ The goal is to lose all pieces except the king, or get stalemated
+ or checkmated like on the following diagram.
+ All usual chess rules apply, but captures are mandatory.
+ When several captures are possible you can choose: from the
+ diagram position 1.Nf3?? and 1.g4?! allow respectively 1...Qxf3 and 1...Nxg4.
figure.diagram-container
.diagram
- | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
- figcaption White cannot move: 1-0.
-
-h3 Special moves
-
-p.
- Castling is not possible, but en-passant captures are allowed.
- Pawns may promote into king (so you can potentially have several kings on the board).
+ | fen:r1b1kb1r/p2ppp1p/2q2np1/8/7P/7R/PP1PPPP1/RNB1KBN1:
+ figcaption 1.g3 forces 1...Qxc1# checkmate
h3 More information
p
- | This is a popular variant, played in many places on the web.
- | A starting point can be the
- a(href="https://en.wikipedia.org/wiki/Losing_Chess") Wikipedia page
- | .
+ | This variant can be played
+ a(href="https://www.freechess.org/Help/HelpFiles/losers.html") on FICS
+ | . We follow their naming choice.
p.boxed
- | Gana perdiendo todas tus piezas. Capturas obligatorias.
+ | Gana perdiendo todas tus piezas excepto el rey. Capturas obligatorias.
p.
- El objetivo es perder todas sus piezas (peones incluidos), o ser empate
- como en el siguiente diagrama.
- El rey no tiene un estado especial: puede ser capturado.
- No hay noción de jaque, ni de enroque.
-
-p La captura es obligatoria, pero si es posible, puede elegir.
+ El objetivo es perder todas sus piezas excepto el rey, o ser empate
+ o jaque mate como en el siguiente diagrama.
+ Se aplican todas las reglas habituales, pero las capturas son obligatorias.
+ Cuando son posibles varias capturas, puede elegir: desde
+ posición del diagrama 1.Nf3?? y 1.g4?! permiten 1...Qxf3 y 1...Nxg4 respectivamente.
figure.diagram-container
- .diagram
- | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
- figcaption Las blancas no puede moverse: 1-0.
-
-h3 Movimientos especiales
-
-p.
- El enroque no está permitido, pero las capturas al pasar son posibles.
- Un peón puede ser promovido a rey (por lo que potencialmente puede haber
- varios reyes en el tablero).
+ .diagrama
+ | fen:r1b1kb1r/p2ppp1p/2q2np1/8/7P/7R/PP1PPPP1/RNB1KBN1:
+ figcaption 1.g3 fuerza 1...Qxc1# jaque mate
h3 Más información
p
- | Esta variante es muy popular y se juega en varios lugares en Internet.
- | la
- a(href="https://en.wikipedia.org/wiki/Losing_Chess") página Wikipedia
- | contiene varias referencias.
+ | Podemos jugar esta variante
+ a(href="https://www.freechess.org/Help/HelpFiles/losers.html") en FICS
+ | . Seguimos su elección de nombre.
p.boxed
- | Gagnez en perdant toutes vos pièces. Captures obligatoires.
+ | Gagnez en perdant toutes vos pièces sauf le roi. Captures obligatoires.
p.
- L'objectif est de perdre toutes ses pièces (pions inclus), ou d'être pat
- comme sur le diagramme suivant.
- Le roi n'a pas de statut particulier : il peut être capturé.
- Il n'y a pas de notion d'échec, et pas de roque.
-
-p Les captures sont obligatoires, mais si plusieurs sont possibles vous pouvez choisir.
+ L'objectif est de perdre toutes ses pièces sauf le roi, ou d'être pat
+ ou mat comme sur le diagramme suivant.
+ Toutes les règles habituelles s'appliquent, mais les capturees sont obligatoires.
+ Quand plusieurs captures sont possibles vous pouvez choisir : depuis la
+ position du diagramme 1.Nf3?? et 1.g4?! permettent respectivement 1...Qxf3 et 1...Nxg4.
figure.diagram-container
.diagram
- | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
- figcaption Les blancs ne peuvent pas bouger : 1-0.
-
-h3 Coups spéciaux
-
-p.
- Le roque n'est pas permis, mais les prises en passant sont possibles.
- Un pion peut se promouvoir en roi (donc il peut potentiellement y avoir
- plusieurs rois sur l'échiquier).
+ | fen:r1b1kb1r/p2ppp1p/2q2np1/8/7P/7R/PP1PPPP1/RNB1KBN1:
+ figcaption 1.g3 force 1...Qxc1# échec et mat
h3 Plus d'information
p
- | Cette variante est très populaire, et est jouée en divers endroits sur internet.
- | La
- a(href="https://en.wikipedia.org/wiki/Losing_Chess") page Wikipedia
- | est un point de départ possible.
+ | On peut jouer à cette variante
+ a(href="https://www.freechess.org/Help/HelpFiles/losers.html") sur FICS
+ | . Nous suivons leur choix de nom.
--- /dev/null
+p.boxed
+ | Bring your king to the other side of the board.
+ | Giving check is not allowed.
+
+p.
+ To win your king must arrive on the 8th rank.
+ He can never be in check (thus there is no checkmate).
+ Stalemate would be a draw, but it seldom occur in this variant.
+
+p.
+ The basic strategy is to erect barriers on the way of the opponent king,
+ with rooks and queen for example, while your king advance next to it.
+
+figure.diagram-container
+ .diagram
+ | fen:8/8/8/8/8/8/krbnNBRK/qrbnNBRQ:
+ figcaption Initial position.
+
+p.
+ Note: the initial position is always the same.
+ See the "Royalrace" variant for a randomized version.
+
+h3 More information
+
+p
+ a(href="https://www.chessvariants.com/diffobjective.dir/racing.html")
+ | Racing Kings variant
+ | on chessvariants.com.
+
+p Inventor: Vernon R. Parton (1961)
--- /dev/null
+p.boxed
+ | Lleva a tu rey al otro lado del tablero.
+ | Las jaques no están permitidas.
+
+p.
+ Para ganar tu rey debes alcanzar en la 8ma fila.
+ Él nunca puede estar en jaque (por lo que no hay jaque mate).
+ El empate significaría tablas, pero rara vez ocurre en esta variante.
+
+p.
+ La estrategia básica es erigir barreras en el camino del rey contrario,
+ con torres y la dama, por ejemplo, mientras tu rey avanza al lado.
+
+figure.diagram-container
+ .diagram
+ | fen:8/8/8/8/8/8/krbnNBRK/qrbnNBRQ:
+ figcaption Position initiale.
+
+p.
+ Nota: la posición inicial es siempre la misma.
+ Para una versión aleatoria, vea la variante "Royalrace".
+
+h3 Más información
+
+p
+ | La
+ a(href="https://www.chessvariants.com/diffobjective.dir/racing.html")
+ | variante Racing Kings
+ | en chessvariants.com.
+
+p Inventor: Vernon R. Parton (1961)
--- /dev/null
+p.boxed
+ | Amenez votre roi de l'autre côté de l'échiquier.
+ | Les échecs ne sont pas autorisés.
+
+p.
+ Pour gagner votre roi doit parvenir sur la 8eme rangée.
+ Il ne peut jamais être en échec (il n'y a donc pas de mat).
+ Le pat signifierait match nul, mais il arrive très rarement dans cette variante.
+
+p.
+ La stratégie de base consiste à ériger des barrières sur le chemin du roi adverse,
+ avec des tours et la dame par exemple, tandis que votre roi avance à côté.
+
+figure.diagram-container
+ .diagram
+ | fen:8/8/8/8/8/8/krbnNBRK/qrbnNBRQ:
+ figcaption Position initiale.
+
+p.
+ Note : la position de départ est toujours la même.
+ Pour une version aléatoire, voir la variante "Royalrace".
+
+h3 Plus d'information
+
+p
+ | La
+ a(href="https://www.chessvariants.com/diffobjective.dir/racing.html")
+ | variante Racing Kings
+ | sur chessvariants.com.
+
+p Inventeur : Vernon R. Parton (1961)
| Strongly inspired by the Racing Kings variant invented by Vernon R. Parton (1961),
| playable for example
a(href="https://lichess.org/variant/racingKings") on lichess
- | .
+ | , and also here: see "Racingkings" variant :-)
| Fuertemente inspirado por la variante Racing Kings inventado por Vernon
| R. Parton (1961), jugable entre otros
a(href="https://lichess.org/variant/racingKings") en lichess
- | .
+ | , y también aquí: ver la variante "Racingkings" :-)
| Fortement inspiré par la variante Racing Kings inventée par Vernon R. Parton (1961),
| jouable entre autres
a(href="https://lichess.org/variant/racingKings") sur lichess
- | .
+ | , et également ici : voir la variante "Racingkings" :-)
--- /dev/null
+p.boxed
+ | Win by losing all your pieces. Capture is mandatory.
+
+p.
+ The goal is to lose all pieces, or get stalemated like on the following diagram.
+ The king has no royal status: it can be taken as any other piece.
+ Thus, there is no castle rule, no checks.
+
+p Captures are mandatory, but when several capturing moves are possible you can choose.
+
+figure.diagram-container
+ .diagram
+ | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
+ figcaption White cannot move: 1-0.
+
+h3 Special moves
+
+p.
+ Castling is not possible, but en-passant captures are allowed.
+ Pawns may promote into king (so you can potentially have several kings on the board).
+
+h3 More information
+
+p
+ | This is a popular variant, played in many places on the web.
+ | A starting point can be the
+ a(href="https://en.wikipedia.org/wiki/Losing_Chess") Wikipedia page
+ | . Note: this variant has several names, we choose here the same as
+ a(href="https://www.freechess.org/Help/HelpFiles/suicide_chess.html") on FICS
+ | .
--- /dev/null
+p.boxed
+ | Gana perdiendo todas tus piezas. Capturas obligatorias.
+
+p.
+ El objetivo es perder todas sus piezas (peones incluidos), o ser empate
+ como en el siguiente diagrama.
+ El rey no tiene un estado especial: puede ser capturado.
+ No hay noción de jaque, ni de enroque.
+
+p La captura es obligatoria, pero si es posible, puede elegir.
+
+figure.diagram-container
+ .diagram
+ | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
+ figcaption Las blancas no puede moverse: 1-0.
+
+h3 Movimientos especiales
+
+p.
+ El enroque no está permitido, pero las capturas al pasar son posibles.
+ Un peón puede ser promovido a rey (por lo que potencialmente puede haber
+ varios reyes en el tablero).
+
+h3 Más información
+
+p
+ | Esta variante es muy popular y se juega en varios lugares en Internet.
+ | la
+ a(href="https://en.wikipedia.org/wiki/Losing_Chess") página Wikipedia
+ | contiene varias referencias.
+ | Nota: esta variante tiene varios nombres, elegimos aquí lo mismo que
+ a(href="https://www.freechess.org/Help/HelpFiles/suicide_chess.html") en FICS
+ | .
--- /dev/null
+p.boxed
+ | Gagnez en perdant toutes vos pièces. Captures obligatoires.
+
+p.
+ L'objectif est de perdre toutes ses pièces (pions inclus), ou d'être pat
+ comme sur le diagramme suivant.
+ Le roi n'a pas de statut particulier : il peut être capturé.
+ Il n'y a pas de notion d'échec, et pas de roque.
+
+p Les captures sont obligatoires, mais si plusieurs sont possibles vous pouvez choisir.
+
+figure.diagram-container
+ .diagram
+ | fen:6nB/6P1/8/4p3/2p1P3/2P5/8/8:
+ figcaption Les blancs ne peuvent pas bouger : 1-0.
+
+h3 Coups spéciaux
+
+p.
+ Le roque n'est pas permis, mais les prises en passant sont possibles.
+ Un pion peut se promouvoir en roi (donc il peut potentiellement y avoir
+ plusieurs rois sur l'échiquier).
+
+h3 Plus d'information
+
+p
+ | Cette variante est très populaire, et est jouée en divers endroits sur internet.
+ | La
+ a(href="https://en.wikipedia.org/wiki/Losing_Chess") page Wikipedia
+ | est un point de départ possible.
+ | Note : cette variante a plusieurs noms, nous choisisson ici le même que
+ a(href="https://www.freechess.org/Help/HelpFiles/suicide_chess.html") sur FICS
+ | .
},
// Retrieve all local games (running, completed, imported...)
- // light: do not retrieve moves or clocks (TODO: this is the only usage)
- getAll: function(light, callback) {
+ getAll: function(callback) {
dbOperation((err,db) => {
let objectStore = db.transaction("games").objectStore("games");
let games = [];
// if there is still another cursor to go, keep running this code
if (cursor) {
let g = cursor.value;
- if (light) {
- g.movesCount = g.moves.length;
- delete g.moves;
- delete g.clocks;
- delete g.initime;
- }
+ // Do not retrieve moves or clocks (unused in list mode)
+ g.movesCount = g.moves.length;
+ delete g.moves;
+ delete g.clocks;
+ delete g.initime;
games.push(g);
cursor.continue();
} else callback(games);
// Finally filter impossible moves
const res = moves.filter(m => {
if (m.appear.length == 2) {
- //castle
- // appear[i] must be an empty square on the other board
+ // Castle: appear[i] must be an empty square on the other board
for (let psq of m.appear) {
if (this.getSquareOccupation(psq.x, psq.y, 3 - mirrorSide) != V.EMPTY)
return false;
--- /dev/null
+import { ChessRules } from "@/base_rules";
+import { ArrayFun } from "@/utils/array";
+import { randInt } from "@/utils/alea";
+
+export const VariantRules = class LosersRules extends ChessRules {
+ // Trim all non-capturing moves
+ static KeepCaptures(moves) {
+ return moves.filter(m => m.vanish.length == 2);
+ }
+
+ // Stop at the first capture found (if any)
+ atLeastOneCapture() {
+ 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 &&
+ this.getPotentialMovesFrom([i, j]).some(m =>
+ // Warning: duscard castle moves
+ m.vanish.length == 2 && m.appear.length == 1)
+ ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ getPossibleMovesFrom(sq) {
+ let moves = this.filterValid(this.getPotentialMovesFrom(sq));
+ const captureMoves = V.KeepCaptures(moves);
+ if (captureMoves.length > 0) return captureMoves;
+ if (this.atLeastOneCapture()) return [];
+ return moves;
+ }
+
+ getAllValidMoves() {
+ const moves = super.getAllValidMoves();
+ if (moves.some(m => m.vanish.length == 2)) return V.KeepCaptures(moves);
+ return moves;
+ }
+
+ static get SEARCH_DEPTH() {
+ return 4;
+ }
+};
static ParseFen(fen) {
const fenParts = fen.split(" ");
return Object.assign(ChessRules.ParseFen(fen), {
- sentrypath: fenParts[5]
+ sentrypush: fenParts[5]
});
}
getFen() {
- return super.getFen() + " " + this.getSentrypathFen();
+ return super.getFen() + " " + this.getSentrypushFen();
}
getFenForRepeat() {
- return super.getFenForRepeat() + "_" + this.getSentrypathFen();
+ return super.getFenForRepeat() + "_" + this.getSentrypushFen();
}
- getSentrypathFen() {
- const L = this.sentryPath.length;
- if (!this.sentryPath[L-1]) return "-";
+ getSentrypushFen() {
+ const L = this.sentryPush.length;
+ if (!this.sentryPush[L-1]) return "-";
let res = "";
- this.sentryPath[L-1].forEach(coords =>
+ this.sentryPush[L-1].forEach(coords =>
res += V.CoordsToSquare(coords) + ",");
return res.slice(0, -1);
}
this.subTurn = 1;
// Stack pieces' forbidden squares after a sentry move at each turn
const parsedFen = V.ParseFen(fen);
- if (parsedFen.sentrypath == "-") this.sentryPath = [null];
+ if (parsedFen.sentrypush == "-") this.sentryPush = [null];
else {
- this.sentryPath = [
- parsedFen.sentrypath.split(",").map(sq => {
+ this.sentryPush = [
+ parsedFen.sentrypush.split(",").map(sq => {
return V.SquareToCoords(sq);
})
];
}
static GenRandInitFen(randomness) {
- // TODO: special conditions
+ // TODO: special conditions for 960
return "jsfqkbnr/pppppppp/8/8/8/8/PPPPPPPP/JSDQKBNR w 0 1111 - -";
}
}
}
+ // Is piece on square (x,y) immobilized?
+ isImmobilized([x, y]) {
+ const color = this.getColor(x, y);
+ const oppCol = V.GetOppCol(color);
+ for (let step of V.steps[V.ROOK]) {
+ const [i, j] = [x + step[0], y + step[1]];
+ if (
+ V.OnBoard(i, j) &&
+ this.board[i][j] != V.EMPTY &&
+ this.getColor(i, j) == oppCol
+ ) {
+ const oppPiece = this.getPiece(i, j);
+ if (oppPiece == V.JAILER) return [i, j];
+ }
+ }
+ return null;
+ }
+
+ getPotentialMovesFrom_aux([x, y]) {
+ switch (this.getPiece(x, y)) {
+ case V.JAILER:
+ return this.getPotentialJailerMoves([x, y]);
+ case V.SENTRY:
+ return this.getPotentialSentryMoves([x, y]);
+ case V.LANCER
+ return this.getPotentialLancerMoves([x, y]);
+ default:
+ return super.getPotentialMovesFrom([x, y]);
+ }
+ }
+
getPotentialMovesFrom([x,y]) {
- // if subturn == 1, normal situation, allow moves except walking back on sentryPath,
- // if last element isn't null in sentryPath array
- // if subTurn == 2, allow only the end of the path (occupied by a piece) to move
- //
- // TODO: special pass move: take jailer with king, only if king immobilized
- // Move(appear:[], vanish:[], start == king and end = jailer (for animation))
- //
- // TODO: post-processing if sentryPath forbid some moves.
- // + add all lancer possible orientations
- // (except if just after a push: allow all movements from init square then)
- // Test if last sentryPath ends at our position: if yes, OK
+ if (this.subTurn == 1) {
+ if (!!this.isImmobilized([x, y])) return [];
+ return this.getPotentialMovesFrom_aux([x, y]);
+ }
+ // subTurn == 2: only the piece pushed by the sentry is allowed to move,
+ // as if the sentry didn't exist
+ if (x != this.sentryPos.x && y != this.sentryPos.y) return [];
+ return this.getPotentialMovesFrom_aux([x,y]);
+ }
+
+ getAllValidMoves() {
+ let moves = super.getAllValidMoves().filter(m =>
+ // Remove jailer captures
+ m.vanish[0].p != V.JAILER || m.vanish.length == 1;
+ );
+ const L = this.sentryPush.length;
+ if (!!this.sentryPush[L-1] && this.subTurn == 1) {
+ // Delete moves walking back on sentry push path
+ moves = moves.filter(m => {
+ if (
+ m.vanish[0].p != V.PAWN &&
+ this.sentryPush[L-1].some(sq => sq.x == m.end.x && sq.y == m.end.y)
+ ) {
+ return false;
+ }
+ return true;
+ });
+ }
+ return moves;
+ }
+
+ filterValid(moves) {
+ // Disable check tests when subTurn == 2, because the move isn't finished
+ if (this.subTurn == 2) return moves;
+ return super.filterValid(moves);
+ }
+
+ getPotentialLancerMoves([x, y]) {
+ // TODO: add all lancer possible orientations same as pawn promotions,
+ // except if just after a push: allow all movements from init square then
+ return [];
+ }
+
+ getPotentialSentryMoves([x, y]) {
+ // The sentry moves a priori like a bishop:
+ let moves = super.getPotentialBishopMoves([x, y]);
+ // ...but captures are replaced by special move
+ // "appear = [], vanish = init square" to let the pushed piece move then.
+ // TODO
+ }
+
+ getPotentialJailerMoves([x, y]) {
+ // Captures are removed afterward:
+ return super.getPotentialRookMoves([x, y]);
+ }
+
+ getPotentialKingMoves([x, y]) {
+ let moves = super.getPotentialKingMoves([x, y]);
+ // Augment with pass move is the king is immobilized:
+ const jsq = this.isImmobilized([x, y]);
+ if (!!jsq) {
+ moves.push(new Move({
+ appear: [],
+ vanish: [],
+ start: { x: x, y: y },
+ end: { x: jsq[0], y: jsq[1] }
+ });
+ }
+ return moves;
}
// Adapted: castle with jailer possible
// A piece is pushed:
// TODO: push array of squares between start and end of move, included
// (except if it's a pawn)
- this.sentryPath.push([]); //TODO
+ this.sentryPush.push([]); //TODO
this.subTurn = 1;
} else {
- if (move.appear.length == 0 && move.vanish.length == 0) {
+ if (move.appear.length == 0 && move.vanish.length == 1) {
// Special sentry move: subTurn <- 2, and then move pushed piece
this.subTurn = 2;
}
ChessRules.VALUES
);
}
+
+ getNotation(move) {
+ // Special case "king takes jailer" is a pass move
+ if (move.appear.length == 0 && move.vanish.length == 0) return "pass";
+ return super.getNotation(move);
+ }
};
return true; //always at least one possible move
}
- underCheck() {
- return false; //there is no check
+ filterValid(moves) {
+ return moves; //there is no check
}
getCheckSquares() {
getCurrentScore() {
if (this.atLeastOneMove()) {
- // game not over?
+ // Game not over?
const color = this.turn;
if (
Object.keys(this.material[color]).some(p => {
import { randInt } from "@/utils/alea";
export const VariantRules = class LosersRules extends ChessRules {
- static get HasFlags() {
- return false;
- }
-
- getPotentialPawnMoves([x, y]) {
- let moves = super.getPotentialPawnMoves([x, y]);
-
- // Complete with promotion(s) into king, if possible
- const color = this.turn;
- const shift = color == "w" ? -1 : 1;
- const lastRank = color == "w" ? 0 : V.size.x - 1;
- if (x + shift == lastRank) {
- // Normal move
- if (this.board[x + shift][y] == V.EMPTY)
- moves.push(
- this.getBasicMove([x, y], [x + shift, y], { c: color, p: V.KING })
- );
- // Captures
- if (
- y > 0 &&
- this.canTake([x, y], [x + shift, y - 1]) &&
- this.board[x + shift][y - 1] != V.EMPTY
- ) {
- moves.push(
- this.getBasicMove([x, y], [x + shift, y - 1], { c: color, p: V.KING })
- );
- }
- if (
- y < V.size.y - 1 &&
- this.canTake([x, y], [x + shift, y + 1]) &&
- this.board[x + shift][y + 1] != V.EMPTY
- ) {
- moves.push(
- this.getBasicMove([x, y], [x + shift, y + 1], { c: color, p: V.KING })
- );
- }
- }
-
- 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
+ static KeepCaptures(moves) {
+ return moves.filter(m => m.vanish.length == 2);
}
- // Stop at the first capture found (if any)
+ // Stop at the first capture found (if any)
atLeastOneCapture() {
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) {
- for (let k = 0; k < moves.length; k++) {
- if (
- moves[k].vanish.length == 2 &&
- this.filterValid([moves[k]]).length > 0
- )
- return true;
- }
- }
+ if (
+ this.board[i][j] != V.EMPTY &&
+ this.getColor(i, j) != oppCol &&
+ this.getPotentialMovesFrom([i, j]).some(m =>
+ // Warning: duscard castle moves
+ m.vanish.length == 2 && m.appear.length == 1)
+ ) {
+ return true;
}
}
}
return false;
}
- // Trim all non-capturing moves
- static KeepCaptures(moves) {
- return moves.filter(m => {
- return m.vanish.length == 2;
- });
- }
-
getPossibleMovesFrom(sq) {
let moves = this.filterValid(this.getPotentialMovesFrom(sq));
- // This is called from interface: we need to know if a capture is possible
- if (this.atLeastOneCapture()) moves = V.KeepCaptures(moves);
+ const captureMoves = V.KeepCaptures(moves);
+ if (captureMoves.length > 0) return captureMoves;
+ if (this.atLeastOneCapture()) return [];
return moves;
}
getAllValidMoves() {
- let moves = super.getAllValidMoves();
- if (
- moves.some(m => {
- return m.vanish.length == 2;
- })
- )
- moves = V.KeepCaptures(moves);
+ const moves = super.getAllValidMoves();
+ if (moves.some(m => m.vanish.length == 2)) return V.KeepCaptures(moves);
return moves;
}
- underCheck() {
- return false; //No notion of check
- }
-
- getCheckSquares() {
- return [];
- }
-
- // No variables update because no royal king + no castling
- updateVariables() {}
- unupdateVariables() {}
-
getCurrentScore() {
- if (this.atLeastOneMove())
- // game not over
- return "*";
-
- // No valid move: the side who cannot move wins
+ // If only my king remains, I win
+ const color = this.turn;
+ let onlyKing = true;
+ outerLoop: 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) == color &&
+ this.getPiece(i,j) != V.KING
+ ) {
+ onlyKing = false;
+ break outerLoop;
+ }
+ }
+ }
+ if (onlyKing) return color == "w" ? "1-0" : "0-1";
+ if (this.atLeastOneMove()) return "*";
+ // No valid move: the side who cannot move (or is checkmated) wins
return this.turn == "w" ? "1-0" : "0-1";
}
- static get VALUES() {
- // Experimental...
- return {
- p: 1,
- r: 7,
- n: 3,
- b: 3,
- q: 5,
- k: 5
- };
- }
-
static get SEARCH_DEPTH() {
return 4;
}
evalPosition() {
- return -super.evalPosition(); //better with less material
- }
-
- static GenRandInitFen(randomness) {
- if (randomness == 0)
- return "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w 0 -";
-
- let pieces = { w: new Array(8), b: new Array(8) };
- // Shuffle pieces on first and last rank
- for (let c of ["w", "b"]) {
- if (c == 'b' && randomness == 1) {
- pieces['b'] = pieces['w'];
- break;
- }
-
- let positions = ArrayFun.range(8);
-
- // Get random squares for bishops
- let randIndex = 2 * randInt(4);
- let bishop1Pos = positions[randIndex];
- // The second bishop must be on a square of different color
- let randIndex_tmp = 2 * randInt(4) + 1;
- let bishop2Pos = positions[randIndex_tmp];
- // Remove chosen squares
- positions.splice(Math.max(randIndex, randIndex_tmp), 1);
- positions.splice(Math.min(randIndex, randIndex_tmp), 1);
-
- // Get random squares for knights
- randIndex = randInt(6);
- let knight1Pos = positions[randIndex];
- positions.splice(randIndex, 1);
- randIndex = randInt(5);
- let knight2Pos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- // Get random square for queen
- randIndex = randInt(4);
- let queenPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- // Random square for king (no castle)
- randIndex = randInt(3);
- let kingPos = positions[randIndex];
- positions.splice(randIndex, 1);
-
- // Rooks positions are now fixed
- let rook1Pos = positions[0];
- let rook2Pos = positions[1];
-
- // Finally put the shuffled pieces in the board array
- pieces[c][rook1Pos] = "r";
- pieces[c][knight1Pos] = "n";
- pieces[c][bishop1Pos] = "b";
- pieces[c][queenPos] = "q";
- pieces[c][kingPos] = "k";
- pieces[c][bishop2Pos] = "b";
- pieces[c][knight2Pos] = "n";
- pieces[c][rook2Pos] = "r";
- }
- return (
- pieces["b"].join("") +
- "/pppppppp/8/8/8/8/PPPPPPPP/" +
- pieces["w"].join("").toUpperCase() +
- // En-passant allowed, but no flags
- " w 0 -"
- );
+ // Less material is better (more subtle in fact but...)
+ return -super.evalPosition();
}
};
--- /dev/null
+import { ChessRules } from "@/base_rules";
+
+export const VariantRules = class RacingkingsRules extends ChessRules {
+ static get HasFlags() {
+ return false;
+ }
+
+ static get HasEnpassant() {
+ return false;
+ }
+
+ static get CanFlip() {
+ return false;
+ }
+
+ static GenRandInitFen() {
+ return "8/8/8/8/8/8/krbnNBRK/qrbnNBRQ w 0";
+ }
+
+ filterValid(moves) {
+ if (moves.length == 0) return [];
+ const color = this.turn;
+ const oppCol = V.GetOppCol(color);
+ return moves.filter(m => {
+ this.play(m);
+ // Giving check is forbidden as well:
+ const res = !this.underCheck(color) && !this.underCheck(oppCol);
+ this.undo(m);
+ return res;
+ });
+ }
+
+ getCurrentScore() {
+ // If both kings arrived on the last rank, it's a draw
+ if (this.kingPos['w'][0] == 0 && this.kingPos['b'][0] == 0) return "1/2";
+ // If after my move the opponent king is on last rank, I lose.
+ // This is only possible with black.
+ if (this.turn == 'w' && this.kingPos['w'][0] == 0) return "1-0";
+ // Turn has changed:
+ const color = V.GetOppCol(this.turn);
+ if (this.kingPos[color][0] == 0) {
+ // The opposing edge is reached!
+ // If color is white and the black king can arrive on 8th rank
+ // at next move, then it should be a draw:
+ if (color == "w" && this.kingPos['b'][0] == 1) {
+ // Search for a move
+ const oppKingMoves = this.getPotentialKingMoves(this.kingPos['b']);
+ if (oppKingMoves.some(m => m.end.x == 0)) return "*";
+ }
+ return color == "w" ? "1-0" : "0-1";
+ }
+ if (this.atLeastOneMove()) return "*";
+ // Stalemate (will probably never happen)
+ return "1/2";
+ }
+
+ evalPosition() {
+ // Count material:
+ let evaluation = super.evalPosition();
+ // Ponder with king position:
+ return evaluation/5 + this.kingPos["b"][0] - this.kingPos["w"][0];
+ }
+};
static GenRandInitFen(randomness) {
if (randomness == 0)
- return "11/11/11/11/11/11/11/11/11/QRBNP1pnbrq/KRBNP1pnbrk w 0";
+ return "11/11/11/11/11/11/11/11/11/qrbnp1PNBRQ/krbnp1PNBRK w 0";
let pieces = { w: new Array(10), b: new Array(10) };
// Shuffle pieces on first and second rank
const blackFen = pieces["b"].join("");
return (
"11/11/11/11/11/11/11/11/11/" +
- whiteFen.substr(5).split("").reverse().join("") +
+ blackFen.substr(5).split("").reverse().join("") +
"1" +
- blackFen.substr(5).split("").join("") +
+ whiteFen.substr(5).split("").join("") +
"/" +
- whiteFen.substr(0,5) +
+ blackFen.substr(0,5) +
"1" +
- blackFen.substr(0,5).split("").reverse().join("") +
+ whiteFen.substr(0,5).split("").reverse().join("") +
" w 0"
);
}
if (this.kingPos[color][0] == 0)
// The opposing edge is reached!
return color == "w" ? "1-0" : "0-1";
- if (this.atLeastOneMove())
- return "*";
+ if (this.atLeastOneMove()) return "*";
// Stalemate (will probably never happen)
return "1/2";
}
--- /dev/null
+import { ChessRules } from "@/base_rules";
+import { ArrayFun } from "@/utils/array";
+import { randInt } from "@/utils/alea";
+
+export const VariantRules = class SuicideRules extends ChessRules {
+ static get HasFlags() {
+ return false;
+ }
+
+ getPotentialPawnMoves([x, y]) {
+ let moves = super.getPotentialPawnMoves([x, y]);
+
+ // Complete with promotion(s) into king, if possible
+ const color = this.turn;
+ const shift = color == "w" ? -1 : 1;
+ const lastRank = color == "w" ? 0 : V.size.x - 1;
+ if (x + shift == lastRank) {
+ // Normal move
+ if (this.board[x + shift][y] == V.EMPTY)
+ moves.push(
+ this.getBasicMove([x, y], [x + shift, y], { c: color, p: V.KING })
+ );
+ // Captures
+ if (
+ y > 0 &&
+ this.canTake([x, y], [x + shift, y - 1]) &&
+ this.board[x + shift][y - 1] != V.EMPTY
+ ) {
+ moves.push(
+ this.getBasicMove([x, y], [x + shift, y - 1], { c: color, p: V.KING })
+ );
+ }
+ if (
+ y < V.size.y - 1 &&
+ this.canTake([x, y], [x + shift, y + 1]) &&
+ this.board[x + shift][y + 1] != V.EMPTY
+ ) {
+ moves.push(
+ this.getBasicMove([x, y], [x + shift, y + 1], { c: color, p: V.KING })
+ );
+ }
+ }
+
+ 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);
+ }
+
+ // Stop at the first capture found (if any)
+ atLeastOneCapture() {
+ 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 &&
+ this.getPotentialMovesFrom([i, j]).some(m => m.vanish.length == 2)
+ ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ getPossibleMovesFrom(sq) {
+ let moves = this.getPotentialMovesFrom(sq);
+ const captureMoves = V.KeepCaptures(moves);
+ if (captureMoves.length > 0) return captureMoves;
+ if (this.atLeastOneCapture()) return [];
+ return moves;
+ }
+
+ filterValid(moves) {
+ return moves;
+ }
+
+ getAllValidMoves() {
+ const moves = super.getAllValidMoves();
+ if (moves.some(m => m.vanish.length == 2)) return V.KeepCaptures(moves);
+ return moves;
+ }
+
+ atLeastOneMove() {
+ const color = this.turn;
+ for (let i = 0; i < V.size.x; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (
+ this.getColor(i, j) == color &&
+ this.getPotentialMovesFrom([i, j]).length > 0
+ ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ getCheckSquares() {
+ return [];
+ }
+
+ // No variables update because no royal king + no castling
+ updateVariables() {}
+ unupdateVariables() {}
+
+ getCurrentScore() {
+ if (this.atLeastOneMove()) return "*";
+ // No valid move: the side who cannot move wins
+ return this.turn == "w" ? "1-0" : "0-1";
+ }
+
+ static get VALUES() {
+ return {
+ p: 1,
+ r: 7,
+ n: 3,
+ b: 3,
+ q: 5,
+ k: 5
+ };
+ }
+
+ static get SEARCH_DEPTH() {
+ return 4;
+ }
+
+ evalPosition() {
+ // Less material is better:
+ return -super.evalPosition();
+ }
+
+ static GenRandInitFen(randomness) {
+ if (randomness == 0)
+ return "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w 0 -";
+
+ let pieces = { w: new Array(8), b: new Array(8) };
+ // Shuffle pieces on first and last rank
+ for (let c of ["w", "b"]) {
+ if (c == 'b' && randomness == 1) {
+ pieces['b'] = pieces['w'];
+ break;
+ }
+
+ let positions = ArrayFun.range(8);
+
+ // Get random squares for bishops
+ let randIndex = 2 * randInt(4);
+ let bishop1Pos = positions[randIndex];
+ // The second bishop must be on a square of different color
+ let randIndex_tmp = 2 * randInt(4) + 1;
+ let bishop2Pos = positions[randIndex_tmp];
+ // Remove chosen squares
+ positions.splice(Math.max(randIndex, randIndex_tmp), 1);
+ positions.splice(Math.min(randIndex, randIndex_tmp), 1);
+
+ // Get random squares for knights
+ randIndex = randInt(6);
+ let knight1Pos = positions[randIndex];
+ positions.splice(randIndex, 1);
+ randIndex = randInt(5);
+ let knight2Pos = positions[randIndex];
+ positions.splice(randIndex, 1);
+
+ // Get random square for queen
+ randIndex = randInt(4);
+ let queenPos = positions[randIndex];
+ positions.splice(randIndex, 1);
+
+ // Random square for king (no castle)
+ randIndex = randInt(3);
+ let kingPos = positions[randIndex];
+ positions.splice(randIndex, 1);
+
+ // Rooks positions are now fixed
+ let rook1Pos = positions[0];
+ let rook2Pos = positions[1];
+
+ // Finally put the shuffled pieces in the board array
+ pieces[c][rook1Pos] = "r";
+ pieces[c][knight1Pos] = "n";
+ pieces[c][bishop1Pos] = "b";
+ pieces[c][queenPos] = "q";
+ pieces[c][kingPos] = "k";
+ pieces[c][bishop2Pos] = "b";
+ pieces[c][knight2Pos] = "n";
+ pieces[c][rook2Pos] = "r";
+ }
+ return (
+ pieces["b"].join("") +
+ "/pppppppp/8/8/8/8/PPPPPPPP/" +
+ pieces["w"].join("").toUpperCase() +
+ // En-passant allowed, but no flags
+ " w 0 -"
+ );
+ }
+};
getPpath(b) {
// TODO: !!this.checkFlags condition for printDiagram, but clearly not good.
// This is just a temporary fix.
- if (b[1] == 'k' && this.checkFlags && this.checkFlags[b[0]] > 0)
+ if (b[1] == 'k' && !!this.checkFlags && this.checkFlags[b[0]] > 0)
return "Threechecks/" + b[0] + 'k_' + this.checkFlags[b[0]];
return b;
}
vid: parseInt(localStorage.getItem("vid")) || 0,
to: "", //name of challenged player (if any)
cadence: localStorage.getItem("cadence") || "",
- randomness: parseInt(localStorage.getItem("randomness")) || 2,
+ randomness:
+ parseInt(localStorage.getItem("challRandomness")) ||
+ // Default to global randomness if no challenges issued yet:
+ this.st.settings.randomness,
// VariantRules object, stored to not interfere with
// diagrams of targetted challenges:
V: null,
// Remember cadence + vid for quicker further challenges:
localStorage.setItem("cadence", chall.cadence);
localStorage.setItem("vid", chall.vid);
- localStorage.setItem("randomness", chall.randomness);
+ localStorage.setItem("challRandomness", chall.randomness);
document.getElementById("modalNewgame").checked = false;
// Show the challenge if not on current display
if (
};
},
created: function() {
- GameStorage.getAll(true, localGames => {
+ GameStorage.getAll(localGames => {
localGames.forEach(g => g.type = "live");
this.decorate(localGames);
this.liveGames = localGames;
// Called at loading to augment games with myColor + myTurn infos
decorate: function(games) {
games.forEach(g => {
- // If game is over, myColor and myTurn are ignored:
+ g.myColor =
+ (g.type == "corr" && g.players[0].uid == this.st.user.id) ||
+ (g.type == "live" && g.players[0].sid == this.st.user.sid)
+ ? 'w'
+ : 'b';
+ // If game is over, myTurn doesn't exist:
if (g.score == "*") {
- g.myColor =
- (g.type == "corr" && g.players[0].uid == this.st.user.id) ||
- (g.type == "live" && g.players[0].sid == this.st.user.sid)
- ? 'w'
- : 'b';
const rem = g.movesCount % 2;
- if ((rem == 0 && g.myColor == 'w') || (rem == 1 && g.myColor == 'b')) {
+ if ((rem == 0 && g.myColor == 'w') || (rem == 1 && g.myColor == 'b'))
g.myTurn = true;
- }
}
});
},
},
gotoAnalyze: function() {
this.$router.push(
- "/analyse/" + this.gameInfo.vname + "/?fen=" + V.GenRandInitFen(2)
+ "/analyse/" + this.gameInfo.vname +
+ "/?fen=" + V.GenRandInitFen(this.st.settings.randomness)
);
}
}
('Baroque', 'Exotic captures'),
('Benedict', 'Change colors'),
('Berolina', 'Pawns move diagonally'),
+ ('Capture', 'Mandatory captures'),
('Checkered', 'Shared pieces'),
('Chess960', 'Standard rules'),
('Circular', 'Run forward'),
('Hiddenqueen', 'Queen disguised as a pawn'),
('Knightmate', 'Mate the knight'),
('Knightrelay', 'The knight transfers its powers'),
- ('Losers', 'Lose all pieces'),
+ ('Losers', 'Get strong at self-mate'),
('Magnetic', 'Laws of attraction'),
('Marseille', 'Move twice'),
+ ('Racingkings', 'Kings cross the 8x8 board'),
('Rifle', 'Shoot pieces'),
- ('Royalrace', 'Kings cross the board'),
+ ('Royalrace', 'Kings cross the 11x11 board'),
('Recycle', 'Reuse pieces'),
('Shatranj', 'Ancient rules'),
+ ('Suicide', 'Lose all pieces'),
('Suction', 'Attract opposite king'),
('Threechecks', 'Give three checks'),
('Upsidedown', 'Board upside down'),