From f3e90e30b6e7ff416afe288bc9dd865e5daf9860 Mon Sep 17 00:00:00 2001 From: Benjamin Auder Date: Thu, 30 Jun 2022 19:13:19 +0200 Subject: [PATCH] Fix Antiking --- base_rules.js | 11 ++-- pieces/Antiking/black_antiking.svg | 98 ++++++++++++++++++++++++++++++ pieces/Antiking/white_antiking.svg | 98 ++++++++++++++++++++++++++++++ pieces/Berolina/CREDITS | 1 + pieces/Berolina/black_pawn.svg | 25 ++++++++ pieces/Berolina/white_pawn.svg | 25 ++++++++ variants.js | 3 +- variants/AbstractAntiking.js | 69 --------------------- variants/Alapo/class.js | 4 +- variants/Alice/class.js | 4 +- variants/Allmate/class.js | 2 +- variants/Ambiguous/class.js | 5 +- variants/Antiking1/class.js | 34 +++-------- variants/Antiking1/rules.html | 2 +- variants/Antiking1/style.css | 8 +++ variants/Antiking2/class.js | 27 +++++--- variants/Antiking2/rules.html | 2 +- variants/Antiking2/style.css | 1 + variants/Chakart/class.js | 4 +- variants/Giveaway/class.js | 8 +-- variants/Madrasi/class.js | 22 +++---- variants/Suction/class.js | 4 +- variants/_Antiking/class.js | 81 ++++++++++++++++++++++++ variants/_Antiking/rules.html | 1 + variants/_Antiking/style.css | 8 +++ 25 files changed, 408 insertions(+), 139 deletions(-) create mode 100644 pieces/Antiking/black_antiking.svg create mode 100644 pieces/Antiking/white_antiking.svg create mode 100644 pieces/Berolina/CREDITS create mode 100644 pieces/Berolina/black_pawn.svg create mode 100644 pieces/Berolina/white_pawn.svg delete mode 100644 variants/AbstractAntiking.js mode change 100644 => 120000 variants/Antiking1/rules.html create mode 100644 variants/Antiking1/style.css mode change 100644 => 120000 variants/Antiking2/rules.html create mode 120000 variants/Antiking2/style.css create mode 100644 variants/_Antiking/class.js create mode 100644 variants/_Antiking/rules.html create mode 100644 variants/_Antiking/style.css diff --git a/base_rules.js b/base_rules.js index e3a34fb..b98c724 100644 --- a/base_rules.js +++ b/base_rules.js @@ -2162,10 +2162,11 @@ export default class ChessRules { ); } + // Argument is (very generally) an array of squares (= arrays) underCheck(square_s, oppCol) { if (this.options["taking"] || this.options["dark"]) return false; - if (!Array.isArray(square_s)) + if (!Array.isArray(square_s[0])) square_s = [square_s]; return square_s.some(sq => this.underAttack(sq, oppCol)); } @@ -2196,19 +2197,21 @@ export default class ChessRules { let newKingPP = null, sqIdx = 0, res = true; //a priori valid - const oldKingPP = m.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color); + const oldKingPP = + m.vanish.find(v => this.isKing(0, 0, v.p) && v.c == color); if (oldKingPP) { // Search king in appear array: newKingPP = m.appear.find(a => this.isKing(0, 0, a.p) && a.c == color); if (newKingPP) { - sqIdx = kingPos.findIndex(kp => kp[0] == oldKingPP.x && kp[1] == oldKingPP[.y); + sqIdx = kingPos.findIndex(kp => + kp[0] == oldKingPP.x && kp[1] == oldKingPP.y); kingPos[sqIdx] = [newKingPP.x, newKingPP.y]; } else res = false; //king vanished } - res &&= !this.underCheck(square_s, oppCol); + res &&= !this.underCheck(kingPos, oppCol); if (oldKingPP && newKingPP) kingPos[sqIdx] = [oldKingPP.x, oldKingPP.y]; this.undoOnBoard(m); diff --git a/pieces/Antiking/black_antiking.svg b/pieces/Antiking/black_antiking.svg new file mode 100644 index 0000000..27fc9b3 --- /dev/null +++ b/pieces/Antiking/black_antiking.svg @@ -0,0 +1,98 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/pieces/Antiking/white_antiking.svg b/pieces/Antiking/white_antiking.svg new file mode 100644 index 0000000..cb86a77 --- /dev/null +++ b/pieces/Antiking/white_antiking.svg @@ -0,0 +1,98 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/pieces/Berolina/CREDITS b/pieces/Berolina/CREDITS new file mode 100644 index 0000000..5067a58 --- /dev/null +++ b/pieces/Berolina/CREDITS @@ -0,0 +1 @@ +https://greenchess.net/info.php?item=downloads diff --git a/pieces/Berolina/black_pawn.svg b/pieces/Berolina/black_pawn.svg new file mode 100644 index 0000000..7b2df98 --- /dev/null +++ b/pieces/Berolina/black_pawn.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/pieces/Berolina/white_pawn.svg b/pieces/Berolina/white_pawn.svg new file mode 100644 index 0000000..e25862f --- /dev/null +++ b/pieces/Berolina/white_pawn.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + diff --git a/variants.js b/variants.js index 18d5891..3705c59 100644 --- a/variants.js +++ b/variants.js @@ -5,7 +5,8 @@ const variants = [ {name: 'Align4', desc: 'Align four pawns'}, {name: 'Allmate', desc: 'Mate any piece'}, {name: 'Ambiguous', desc: "Play opponent's pieces"}, -// {name: 'Antiking1', desc: 'Keep antiking in check', disp: 'Anti-King'}, + {name: 'Antiking1', desc: 'Keep antiking in check', disp: 'Anti-King I'}, + {name: 'Antiking2', desc: 'Keep antiking in check', disp: 'Anti-King II'}, // {name: 'Antimatter', desc: 'Dangerous collisions'}, // {name: 'Apocalypse', desc: 'The end of the world'}, // {name: 'Arena', desc: 'Middle battle'}, diff --git a/variants/AbstractAntiking.js b/variants/AbstractAntiking.js deleted file mode 100644 index 7846add..0000000 --- a/variants/AbstractAntiking.js +++ /dev/null @@ -1,69 +0,0 @@ -import ChessRules from "/base_rules.js"; - -export class AbstractAntikingRules extends ChessRules { - - static get Options() { - return { - styles: [ - "atomic", - "balance", - "cannibal", - "capture", - "crazyhouse", - "doublemove", - "madrasi", - "progressive", - "recycle", - "rifle", - "teleport", - "zen" - ] - }; - } - - pieces(color, x, y) { - "a": { - // Move like a king, no attacks - "class": "antiking", - moves: super.pieces(color, x, y)['k'].moves, - attack: [] - } - } - - isKing(x, y, p) { - if (!p) - p = this.getPiece(x, y); - return ['k', 'a'].includes(p); - } - - 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) - ) - ); - } - - underCheck(squares, color) { - const oppCol = C.GetOppCol(color); - let res = false; - squares.forEach(sq => { - switch (this.getPiece(sq[0], sq[1])) { - case 'k': - res ||= super.underAttack(sq, oppCol); - break; - case 'a': - res ||= !super.underAttack(sq, oppCol); - break; - } - }); - return res; - } - -}; diff --git a/variants/Alapo/class.js b/variants/Alapo/class.js index 881671f..4836413 100644 --- a/variants/Alapo/class.js +++ b/variants/Alapo/class.js @@ -1,6 +1,6 @@ import ChessRules from "/base_rules.js"; -import { ArrayFun } from "/utils/array.js"; -import { Random } from "/utils/alea.js"; +import {ArrayFun} from "/utils/array.js"; +import {Random} from "/utils/alea.js"; export default class AlapoRules extends ChessRules { diff --git a/variants/Alice/class.js b/variants/Alice/class.js index e755b56..e6d37b2 100644 --- a/variants/Alice/class.js +++ b/variants/Alice/class.js @@ -1,5 +1,5 @@ import ChessRules from "/base_rules.js"; -import { ArrayFun } from "/utils/array.js"; +import {ArrayFun} from "/utils/array.js"; export default class AliceRules extends ChessRules { @@ -105,7 +105,7 @@ export default class AliceRules extends ChessRules { filterValid(moves) { const color = this.turn; const oppCol = C.GetOppCol(color); - const kingPos = this.searchKingPos(color); + const kingPos = this.searchKingPos(color)[0]; const kingPiece = this.getPiece(kingPos[0], kingPos[1]); return super.filterValid(moves).filter(m => { // A move must also be legal on the board it is played: diff --git a/variants/Allmate/class.js b/variants/Allmate/class.js index 8d31649..5b237c0 100644 --- a/variants/Allmate/class.js +++ b/variants/Allmate/class.js @@ -82,7 +82,7 @@ export default class AllmateRules extends ChessRules { return true; } - underCheck([x, y], oppCol) { + underCheck() { return false; //not relevant here } diff --git a/variants/Ambiguous/class.js b/variants/Ambiguous/class.js index 58458b6..db24d0e 100644 --- a/variants/Ambiguous/class.js +++ b/variants/Ambiguous/class.js @@ -149,15 +149,14 @@ export default class AmbiguousRules extends ChessRules { getCurrentScore() { // This function is only called at subTurn 1 const color = C.GetOppCol(this.turn); - const kingPos = this.searchKingPos(color); - if (kingPos[0] < 0) + if (this.searchKingPos(color).length == 0) return (color == 'w' ? "0-1" : "1-0"); return "*"; } postPlay(move) { const color = this.turn; - if (this.subTurn == 2 || this.searchKingPos(color)[0] < 0) { + if (this.subTurn == 2 || this.searchKingPos(color).length == 0) { this.turn = C.GetOppCol(color); this.movesCount++; } diff --git a/variants/Antiking1/class.js b/variants/Antiking1/class.js index f8406b7..9b8af78 100644 --- a/variants/Antiking1/class.js +++ b/variants/Antiking1/class.js @@ -1,30 +1,14 @@ import ChessRules from "/base_rules.js"; -import AbstractAntikingRules from "/variants/AbstractAntiking.js"; +import AbstractAntikingRules from "/variants/_Antiking/class.js"; -export class Antiking1Rules extends AbstractAntikingRules { - - static get Options() { - return { - styles: [ - "atomic", - "balance", - "cannibal", - "capture", - "crazyhouse", - "doublemove", - "madrasi", - "progressive", - "recycle", - "rifle", - "teleport", - "zen" - ] - }; - } +export default class Antiking1Rules extends AbstractAntikingRules { get hasCastle() { return false; } + get hasEnpassant() { + return false; + } pieces(color, x, y) { const pawnShift = (color == "w" ? -1 : 1); @@ -53,11 +37,11 @@ export class Antiking1Rules extends AbstractAntikingRules { } // (Anti)King flags at 1 (true) if they can knight-jump - setFlags(fenflags) { + setFlags(fenFlags) { this.kingFlags = { w: {}, b: {} }; for (let i=0; i m.vanish.length == 1)); + moves = moves.concat(knightMoves.filter(m => m.vanish.length == 1)); } return moves; } diff --git a/variants/Antiking1/rules.html b/variants/Antiking1/rules.html deleted file mode 100644 index fee723a..0000000 --- a/variants/Antiking1/rules.html +++ /dev/null @@ -1 +0,0 @@ -https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html diff --git a/variants/Antiking1/rules.html b/variants/Antiking1/rules.html new file mode 120000 index 0000000..68d15a4 --- /dev/null +++ b/variants/Antiking1/rules.html @@ -0,0 +1 @@ +../_Antiking/rules.html \ No newline at end of file diff --git a/variants/Antiking1/style.css b/variants/Antiking1/style.css new file mode 100644 index 0000000..a6ffda1 --- /dev/null +++ b/variants/Antiking1/style.css @@ -0,0 +1,8 @@ +@import url("/variants/_Antiking/style.css"); + +piece.black.pawn { + background-image: url('/pieces/Berolina/black_pawn.svg'); +} +piece.white.pawn { + background-image: url('/pieces/Berolina/white_pawn.svg'); +} diff --git a/variants/Antiking2/class.js b/variants/Antiking2/class.js index 0e6a3e5..ee1030a 100644 --- a/variants/Antiking2/class.js +++ b/variants/Antiking2/class.js @@ -1,15 +1,12 @@ import ChessRules from "/base_rules.js"; -import AbstractAntikingRules from "/variants/AbstractAntiking.js"; -import { Random } from "/utils/alea.js"; +import AbstractAntikingRules from "/variants/_Antiking/class.js"; +import {Random} from "/utils/alea.js"; -export class Antiking2Rules extends AbstractAntikingRules { - - static get Aliases() { - return Object.assign({'A': AbstractAntikingRules}, ChessRules.Aliases); - } +export default class Antiking2Rules extends AbstractAntikingRules { static get Options() { return { + select: C.Options.select, styles: A.Options.styles.concat("cylinder") }; } @@ -25,9 +22,19 @@ export class Antiking2Rules extends AbstractAntikingRules { else akPos[1] = akPos[0]; } - const whiteLine = (akPos[0] > 0 ? akPos[0] : "") + 'A' + (akPos < this.size.y - 1 ? ...); - const blackLine = ... - return baseFen.replace(...) + const antikingLine = (color) => { + const [idx, symbol] = (color == 'w' ? [0, 'a'] : [1, 'A']); + return ( + (akPos[idx] > 0 ? akPos[idx] : "") + symbol + + (akPos[idx] < this.size.y - 1 + ? C.FenEmptySquares(this.size.y - 1 - akPos[idx]) + : "") + ); + }; + return ( + baseFen.replace("p/8", "p/" + antikingLine('b')) + .replace("8/P", antikingLine('w') + "/P") + ); } }; diff --git a/variants/Antiking2/rules.html b/variants/Antiking2/rules.html deleted file mode 100644 index fee723a..0000000 --- a/variants/Antiking2/rules.html +++ /dev/null @@ -1 +0,0 @@ -https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html diff --git a/variants/Antiking2/rules.html b/variants/Antiking2/rules.html new file mode 120000 index 0000000..68d15a4 --- /dev/null +++ b/variants/Antiking2/rules.html @@ -0,0 +1 @@ +../_Antiking/rules.html \ No newline at end of file diff --git a/variants/Antiking2/style.css b/variants/Antiking2/style.css new file mode 120000 index 0000000..aee569a --- /dev/null +++ b/variants/Antiking2/style.css @@ -0,0 +1 @@ +../_Antiking/style.css \ No newline at end of file diff --git a/variants/Chakart/class.js b/variants/Chakart/class.js index 9a1cc6d..02dd16e 100644 --- a/variants/Chakart/class.js +++ b/variants/Chakart/class.js @@ -1,7 +1,7 @@ import ChessRules from "/base_rules.js"; import GiveawayRules from "/variants/Giveaway/class.js"; -import { ArrayFun } from "/utils/array.js"; -import { Random } from "/utils/alea.js"; +import {ArrayFun} from "/utils/array.js"; +import {Random} from "/utils/alea.js"; import PiPo from "/utils/PiPo.js"; import Move from "/utils/Move.js"; diff --git a/variants/Giveaway/class.js b/variants/Giveaway/class.js index 71f70be..69addf2 100644 --- a/variants/Giveaway/class.js +++ b/variants/Giveaway/class.js @@ -1,6 +1,6 @@ import ChessRules from "/base_rules.js"; -import { ArrayFun } from "/utils/array.js"; -import { Random } from "/utils/alea.js"; +import {ArrayFun} from "/utils/array.js"; +import {Random} from "/utils/alea.js"; export default class GiveawayRules extends ChessRules { @@ -84,10 +84,10 @@ export default class GiveawayRules extends ChessRules { super(o); } - underCheck([x, y], oppCol) { + underCheck(square, oppCol) { if (this.options["mode"] == "suicide") return false; - return super.underCheck([x, y], oppCol); + return super.underCheck(square, oppCol); } getCurrentScore() { diff --git a/variants/Madrasi/class.js b/variants/Madrasi/class.js index bbec80a..ac5ccff 100644 --- a/variants/Madrasi/class.js +++ b/variants/Madrasi/class.js @@ -22,18 +22,16 @@ export default class MadrasiRules extends ChessRules { super(o); } - underCheck([x, y], color) { - if (this.options["rexincl"]) { - // If Rex Inclusive, kings do not check each other: - // we just replace it very temporarily. - const [ox, oy] = this.searchKingPos(color); - const saveOppKing = this.board[ox][oy]; - this.board[ox][oy] = C.GetOppCol(color) + "q"; //arbitrary - const res = super.underCheck([x, y], color); - this.board[ox][oy] = saveOppKing; - return res; - } - return super.underCheck([x, y], color); + canTake([x1, y1], [x2, y2]) { + return ( + ( + !this.options["rexincl"] || + this.getPiece(x1, y1) != 'k' || + this.getPiece(x2, y2) != 'k' + ) + && + super.canTake([x1, y1], [x2, y2]) + ); } }; diff --git a/variants/Suction/class.js b/variants/Suction/class.js index a66855d..cf5ae16 100644 --- a/variants/Suction/class.js +++ b/variants/Suction/class.js @@ -107,8 +107,8 @@ export default class SuctionRules extends ChessRules { getCurrentScore() { const color = this.turn; const kingPos = super.searchKingPos(color); - if (color == "w" && kingPos[0] == 0) return "0-1"; - if (color == "b" && kingPos[0] == this.size.x - 1) return "1-0"; + if (color == "w" && kingPos[0][0] == 0) return "0-1"; + if (color == "b" && kingPos[0][0] == this.size.x - 1) return "1-0"; // King is not on the opposite edge: game not over return "*"; } diff --git a/variants/_Antiking/class.js b/variants/_Antiking/class.js new file mode 100644 index 0000000..e92edab --- /dev/null +++ b/variants/_Antiking/class.js @@ -0,0 +1,81 @@ +import ChessRules from "/base_rules.js"; + +export default class AbstractAntikingRules extends ChessRules { + + static get Aliases() { + return Object.assign({'A': AbstractAntikingRules}, ChessRules.Aliases); + } + + static get Options() { + return { + styles: [ + "atomic", + "balance", + "cannibal", + "capture", + "crazyhouse", + "doublemove", + "madrasi", + "progressive", + "recycle", + "rifle", + "teleport", + "zen" + ] + }; + } + + pieces(color, x, y) { + return Object.assign( + { + 'a': { + // Move like a king, no attacks + "class": "antiking", + moves: super.pieces(color, x, y)['k'].moves, + attack: [] + } + }, + super.pieces(color, x, y) + ); + } + + isKing(x, y, p) { + if (!p) + p = this.getPiece(x, y); + return ['k', 'a'].includes(p); + } + + // NOTE: canTake includes (wrong) captures of antiking, + // to not go to low-level using findDestSquares() + canTake([x1, y1], [x2, y2]) { + const piece1 = this.getPiece(x1, y1); + const color1 = this.getColor(x1, y1); + const color2 = this.getColor(x2, y2); + return ( + (piece1 != 'a' && color1 != color2) || + (piece1 == 'a' && color1 == color2) + ); + } + + // Remove captures of antiking (see above) + getPotentialMovesFrom([x, y]) { + return super.getPotentialMovesFrom([x, y]).filter(m => + m.vanish.length == 1 || m.vanish[1].p != 'a'); + } + + underCheck(squares, color) { + let res = false; + squares.forEach(sq => { + switch (this.getPiece(sq[0], sq[1])) { + case 'k': + res ||= super.underAttack(sq, color); + break; + case 'a': + res ||= !super.underAttack(sq, color); + break; + } + }); + return res; + } + +}; diff --git a/variants/_Antiking/rules.html b/variants/_Antiking/rules.html new file mode 100644 index 0000000..fee723a --- /dev/null +++ b/variants/_Antiking/rules.html @@ -0,0 +1 @@ +https://www.chessvariants.com/diffobjective.dir/anti-king-chess.html diff --git a/variants/_Antiking/style.css b/variants/_Antiking/style.css new file mode 100644 index 0000000..3dfe37e --- /dev/null +++ b/variants/_Antiking/style.css @@ -0,0 +1,8 @@ +@import url("/base_pieces.css"); + +piece.black.antiking { + background-image: url('/pieces/Antiking/black_antiking.svg'); +} +piece.white.antiking { + background-image: url('/pieces/Antiking/white_antiking.svg'); +} -- 2.44.0