-// https://vchess.club/#/game/46
-// Bug 35eme coup blanc Rx(P)e2, d2 et aussi 18eme coup blanc Rd7, Pxe6
-// --> peut-être lié à prise, ou lié à getFen(), ou inMultimove pas changé car concatène à coup précédent...
// TODO: also fix moves played on smartphone, annoying shift...
Shako, also known as UniEed Chess (Jean-Louis
Shogi + Makruk/Thai chess --> see on Pychess
-Interesting:
-Monochrome Chess (Proprietary game,
-Looney Industries; Andrew Looney, 1996).
-Usual men and array but pieces are all of the
-same colour. A man is controlled by the player
-in whose half of the board it stands. Thus after
-e4-e5, the pawn changes sides and reverses
-direction. When you capture (by definition, in
-the opponent’s half) there can be no recapture
-as the piece has changed sides. You may not
-immediately reverse an opponent’s move. The
-king has no royal powers but can castle. The
-men are allocated points and the object is to
-have the most points (in pieces captured) when
-the game ends, which is usually when the
-players agree or when one half of the board is
-empty. Values: King=10, Queen=8, Rook=5,
-Bishop=4, Knight=3, Pawn=1. A related game
-Martian Chess is described in chapter 38.
-(Proprietor’s rule sheet, Variant Chess 39)
-
Chakart :)
https://www.chessvariants.com/crossover.dir/koopachess.html
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) {
+ if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
const moves = this.getPotentialMovesFrom([i, j]);
if (moves.length > 0) {
for (let k = 0; k < moves.length; k++) {
"64 pieces on the board": "64 pieces on the board",
"A pawns cloud": "A pawns cloud",
"A wizard in the corner": "A wizard in the corner",
+ "All of the same color": "All of the same color",
"Ancient rules": "Ancient rules",
"Attract opposite king": "Attract opposite king",
"Balanced sliders & leapers": "Balanced sliders & leapers",
"64 pieces on the board": "64 piezas en el tablero",
"A pawns cloud": "Une nube de peones",
"A wizard in the corner": "Un mago en la esquina",
+ "All of the same color": "Todo el mismo color",
"Ancient rules": "Viejas reglas",
"Attract opposite king": "Atraer al rey contrario",
"Balanced sliders & leapers": "Modos de desplazamiento equilibrados",
"64 pieces on the board": "64 pièces sur l'échiquier",
"A pawns cloud": "Une nuée de pions",
"A wizard in the corner": "Un sorcier dans le coin",
+ "All of the same color": "Tout de la même couleur",
"Ancient rules": "Règles anciennes",
"Attract opposite king": "Attirer le roi adverse",
"Balanced sliders & leapers": "Modes de déplacement équilibrés",
--- /dev/null
+p.boxed
+ | Pieces in the first half of the board are yours. Captures are mandatory.
+
+p.
+ All pieces are of the same color (black on the website), but in fact
+ pieces just have no color: you control all
+ pieces which stand in the half-board in front of you. These pieces can
+ only capture on the other half-board.
+
+p.
+ Since captures are mandatory, pieces could make some round-trips
+ around the board, changing owner at every mid-board crossing.
+ For example on the following diagram, the sequence will be 1.Rxd7 Rxd1
+ 2.Rxd8 and black would win, assuming the final rank is 8th.
+
+figure.diagram-container
+ .diagram.diag12
+ | fen:3b4/3k4/8/8/8/8/3r4/3n4:
+ .diagram.diag22
+ | fen:3b4/3r4/8/8/8/8/8/3n4:
+ figcaption Before and after Rxd7
+
+p Kings have no royal status. There are no en-passant captures.
+
+h3 Source
+
+p
+ | Strongly inspired by
+ a(href="http://www.wunderland.com/WTS/Andy/Games/monochess.html")
+ | Monochrome Chess
+ | , but I wanted a version without points counting.
+
+p Inventor: Andrew Looney (1996)
--- /dev/null
+p.boxed
+ | Las piezas en la primera mitad del tablero de ajedrez son tuyas.
+ | Las capturas son obligatorias.
+
+p.
+ Todas las piezas son del mismo color (negro en este sitio), pero de hecho
+ las piezas simplemente no tienen color: tú controlas todas las piezas
+ ubicado en el medio tablero de ajedrez frente a ti. Estas piezas no pueden
+ capturar que en el otro medio tablero.
+
+p.
+ Como las capturas son obligatorias, las piezas podrían ir y venir
+ alrededor del tablero de ajedrez, cambiando de propietario a
+ cada paso por el centro. Por ejemplo, en el siguiente diagrama,
+ la secuencia sería 1.Rxd7 Rxd1 2.Rxd8 y las negras ganarían, suponiendo
+ que la última fila es la 8va.
+
+figure.diagram-container
+ .diagram.diag12
+ | fen:3b4/3k4/8/8/8/8/3r4/3n4:
+ .diagram.diag22
+ | fen:3b4/3r4/8/8/8/8/8/3n4:
+ figcaption Antes y después de Rxd7
+
+p Los reyes no tienen estatus real. No hay capturas en-passant.
+
+h3 Fuente
+
+p
+ | Fuertemente inspirado por el
+ a(href="http://www.wunderland.com/WTS/Andy/Games/monochess.html")
+ | Ajedrez Monocromo
+ | , pero quería una versión sin puntos.
+
+p Inventor: Andrew Looney (1996)
--- /dev/null
+p.boxed
+ | Les pièces dans la première moitié de l'échiquier sont à vous.
+ | Les captures sont obligatoires.
+
+p.
+ Toutes les pièces sont de la même couleur (noire sur ce site), mais en fait
+ les pièces n'ont juste pas de couleur : vous contrôlez toutes les pièces
+ situées dans le demi-échiquier devant vous. Ces pièces ne peuvent capturer
+ que dans l'autre demi-échiquier.
+
+p.
+ Puisque les captures sont obligatoires, les pièces pourraient effectuer
+ quelques aller-retours autour de l'échiquier, chaneant de propriétaire à
+ chaque passage au centre. Par exemple sur le diagramme suivant, la
+ séquence serait 1.Rxd7 Rxd1 2.Rxd8 et les noirs gagneraient, en supposant
+ que la dernière rangée est la 8eme.
+
+figure.diagram-container
+ .diagram.diag12
+ | fen:3b4/3k4/8/8/8/8/3r4/3n4:
+ .diagram.diag22
+ | fen:3b4/3r4/8/8/8/8/8/3n4:
+ figcaption Avant et après Rxd7
+
+p Les rois n'ont pas de statut royal. Il n'y pas de prises en passant.
+
+h3 Source
+
+p
+ | Fortement inspiré par les
+ a(href="http://www.wunderland.com/WTS/Andy/Games/monochess.html")
+ | Échecs Monochromes
+ | , mais je voulais une version sans comptage de points.
+
+p Inventeur : Andrew Looney (1996)
--- /dev/null
+import { ChessRules } from "@/base_rules";
+
+export class MonochromeRules extends ChessRules {
+ static get HasEnpassant() {
+ // Pawns would be on the same side
+ return false;
+ }
+
+ static IsGoodPosition(position) {
+ if (position.length == 0) return false;
+ const rows = position.split("/");
+ if (rows.length != V.size.x) return false;
+ for (let row of rows) {
+ let sumElts = 0;
+ for (let i = 0; i < row.length; i++) {
+ if (V.PIECES.includes(row[i])) sumElts++;
+ else {
+ const num = parseInt(row[i]);
+ if (isNaN(num)) return false;
+ sumElts += num;
+ }
+ }
+ if (sumElts != V.size.y) return false;
+ }
+ return true;
+ }
+
+ canIplay(side, [x, y]) {
+ const xBounds = side == 'w' ? [4,7] : [0,3];
+ return this.turn == side && x >= xBounds[0] && x <= xBounds[1];
+ }
+
+ canTake([x1, y1], [x2, y2]) {
+ // Capture in other half-board
+ return ((x1 <= 3 && x2 >= 4) || (x1 >= 4 && x2 <= 3));
+ }
+
+ // Trim all non-capturing moves
+ static KeepCaptures(moves) {
+ return moves.filter(m => m.vanish.length == 2 && m.appear.length == 1);
+ }
+
+ getAllPotentialMoves() {
+ const xBounds = this.turn == 'w' ? [4,7] : [0,3];
+ let potentialMoves = [];
+ for (let i = xBounds[0]; i <= xBounds[1]; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (this.board[i][j] != V.EMPTY) {
+ Array.prototype.push.apply(
+ potentialMoves,
+ this.getPotentialMovesFrom([i, j])
+ );
+ }
+ }
+ }
+ if (potentialMoves.some(m => m.vanish.length == 2 && m.appear.length == 1))
+ return V.KeepCaptures(potentialMoves);
+ return potentialMoves;
+ }
+
+ atLeastOneMove() {
+ const xBounds = this.turn == 'w' ? [4,7] : [0,3];
+ for (let i = xBounds[0]; i <= xBounds[1]; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (
+ this.board[i][j] != V.EMPTY &&
+ this.getPotentialMovesFrom([i, j]).length > 0
+ ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // Stop at the first capture found (if any)
+ atLeastOneCapture() {
+ const xBounds = this.turn == 'w' ? [4,7] : [0,3];
+ for (let i = xBounds[0]; i <= xBounds[1]; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (
+ this.board[i][j] != V.EMPTY &&
+ this.getPotentialMovesFrom([i, j]).some(m =>
+ // Warning: discard castle moves
+ m.vanish.length == 2 && m.appear.length == 1)
+ ) {
+ 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;
+ }
+
+ isAttacked() {
+ return false;
+ }
+
+ getCheckSquares() {
+ return [];
+ }
+
+ getCurrentScore() {
+ // Is there anything in my half board?
+ const color = V.GetOppCol(this.turn);
+ const xBounds = color == 'w' ? [4,7] : [0,3];
+ let nothingHere = true;
+ outerLoop: for (let i = xBounds[0]; i <= xBounds[1]; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (this.board[i][j] != V.EMPTY) {
+ nothingHere = false;
+ break outerLoop;
+ }
+ }
+ }
+ if (nothingHere) return color == 'w' ? "0-1" : "1-0";
+ if (this.atLeastOneMove()) return '*';
+ return "1/2";
+ }
+
+ static GenRandInitFen(randomness) {
+ // Remove the en-passant part of the FEN
+ const fen = ChessRules.GenRandInitFen(randomness).slice(0, -2);
+ const firstSpace = fen.indexOf(' ');
+ return (
+ fen.substr(0, firstSpace).replace(/[A-Z]/g, (c) => c.toLowerCase()) +
+ fen.substr(firstSpace)
+ );
+ }
+
+ static get SEARCH_DEPTH() {
+ return 4;
+ }
+
+ evalPosition() {
+ let evaluation = 0;
+ for (let i = 0; i < 8; i++) {
+ for (let j = 0; j < V.size.y; j++) {
+ if (this.board[i][j] != V.EMPTY) {
+ const sign = (i <= 3 ? -1 : 1);
+ // I don't think taking pieces' values into account would help
+ evaluation += sign; //* V.VALUES[this.getPiece(i, j)];
+ }
+ }
+ }
+ return evaluation;
+ }
+};
('Losers', 'Get strong at self-mate'),
('Magnetic', 'Laws of attraction'),
('Maxima', 'Occupy the enemy palace'),
+ ('Monochrome', 'All of the same color'),
('Monster', 'White move twice'),
('Omega', 'A wizard in the corner'),
('Orda', 'Mongolian Horde'),