From: Benjamin Auder Date: Tue, 21 Jun 2022 14:30:44 +0000 (+0200) Subject: Add Alapo (unfinished). Reorganise pieces folder X-Git-Url: https://git.auder.net/DESCRIPTION?a=commitdiff_plain;h=f55a0a6753a62257c7caa62ae49c8a5673769065;p=xogo.git Add Alapo (unfinished). Reorganise pieces folder --- diff --git a/TODO b/TODO index d879b34..73b76b0 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ +Debug Alapo +Add links to complete variants rules (Ambiguous...) + add variants : -Ambiguous -Refusal Dark Racing Kings ? Checkered-Teleport ? Otage, Emergo, Pacosako : fonction "buildPiece(arg1, arg2)" returns HTML element with 2 SVG or SVG + number diff --git a/base_rules.js b/base_rules.js index 1b22ae5..c19ee64 100644 --- a/base_rules.js +++ b/base_rules.js @@ -569,15 +569,16 @@ export default class ChessRules { // Compare window ratio width / height to aspectRatio: const windowRatio = window.innerWidth / window.innerHeight; let cbWidth, cbHeight; - if (windowRatio <= this.size.ratio) { + const vRatio = this.size.ratio || 1; + if (windowRatio <= vRatio) { // Limiting dimension is width: cbWidth = Math.min(window.innerWidth, 767); - cbHeight = cbWidth / this.size.ratio; + cbHeight = cbWidth / vRatio; } else { // Limiting dimension is height: cbHeight = Math.min(window.innerHeight, 767); - cbWidth = cbHeight * this.size.ratio; + cbWidth = cbHeight * vRatio; } if (this.hasReserve) { const sqSize = cbWidth / this.size.y; @@ -585,7 +586,7 @@ export default class ChessRules { // Cannot use getReserveSquareSize() here, but sqSize is an upper bound. if ((window.innerHeight - cbHeight) / 2 < sqSize + 5) { cbHeight = window.innerHeight - 2 * (sqSize + 5); - cbWidth = cbHeight * this.size.ratio; + cbWidth = cbHeight * vRatio; } } chessboard.style.width = cbWidth + "px"; @@ -610,7 +611,7 @@ export default class ChessRules { const flipped = (this.playerColor == 'b'); let board = ` `; for (let i=0; i < this.size.x; i++) { for (let j=0; j < this.size.y; j++) { @@ -798,13 +799,14 @@ export default class ChessRules { const multFact = (mode == "up" ? 1.05 : 0.95); let [newWidth, newHeight] = [multFact * r.width, multFact * r.height]; // Stay in window: + const vRatio = this.size.ratio || 1; if (newWidth > window.innerWidth) { newWidth = window.innerWidth; - newHeight = newWidth / this.size.ratio; + newHeight = newWidth / vRatio; } if (newHeight > window.innerHeight) { newHeight = window.innerHeight; - newWidth = newHeight * this.size.ratio; + newWidth = newHeight * vRatio; } chessboard.style.width = newWidth + "px"; chessboard.style.height = newHeight + "px"; @@ -1051,7 +1053,7 @@ export default class ChessRules { return { x: 8, y: 8, - ratio: 1 //for rectangular board = y / x + ratio: 1 //for rectangular board = y / x (optional, 1 = default) }; } @@ -2210,9 +2212,9 @@ export default class ChessRules { this.afterPlay(move); //user method } - getMaxDistance(rwidth) { + getMaxDistance(r) { // Works for all rectangular boards: - return Math.sqrt(rwidth ** 2 + (rwidth / this.size.ratio) ** 2); + return Math.sqrt(r.width ** 2 + r.height ** 2); } getDomPiece(x, y) { @@ -2237,7 +2239,7 @@ export default class ChessRules { movingPiece.style.width = pieceWidth + "px"; movingPiece.style.height = pieceWidth + "px"; } - const maxDist = this.getMaxDistance(r.width); + const maxDist = this.getMaxDistance(r); const pieces = this.pieces(); if (move.drag) { const startCode = this.getPiece(move.start.x, move.start.y); diff --git a/pieces/Alapo/black_CIRCLE.svg b/pieces/Alapo/black_CIRCLE.svg new file mode 100644 index 0000000..7948061 --- /dev/null +++ b/pieces/Alapo/black_CIRCLE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_SQUARE.svg b/pieces/Alapo/black_SQUARE.svg new file mode 100644 index 0000000..fdd9921 --- /dev/null +++ b/pieces/Alapo/black_SQUARE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_TRIANGLE.svg b/pieces/Alapo/black_TRIANGLE.svg new file mode 100644 index 0000000..939ba3a --- /dev/null +++ b/pieces/Alapo/black_TRIANGLE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_TRIANGLE_inv.svg b/pieces/Alapo/black_TRIANGLE_inv.svg new file mode 100644 index 0000000..fb3c955 --- /dev/null +++ b/pieces/Alapo/black_TRIANGLE_inv.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_circle.svg b/pieces/Alapo/black_circle.svg new file mode 100644 index 0000000..8cd85d9 --- /dev/null +++ b/pieces/Alapo/black_circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_square.svg b/pieces/Alapo/black_square.svg new file mode 100644 index 0000000..3e86c70 --- /dev/null +++ b/pieces/Alapo/black_square.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_triangle.svg b/pieces/Alapo/black_triangle.svg new file mode 100644 index 0000000..8c531b5 --- /dev/null +++ b/pieces/Alapo/black_triangle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/black_triangle_inv.svg b/pieces/Alapo/black_triangle_inv.svg new file mode 100644 index 0000000..e9afcea --- /dev/null +++ b/pieces/Alapo/black_triangle_inv.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_CIRCLE.svg b/pieces/Alapo/white_CIRCLE.svg new file mode 100644 index 0000000..af99afa --- /dev/null +++ b/pieces/Alapo/white_CIRCLE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_SQUARE.svg b/pieces/Alapo/white_SQUARE.svg new file mode 100644 index 0000000..716a8e5 --- /dev/null +++ b/pieces/Alapo/white_SQUARE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_TRIANGLE.svg b/pieces/Alapo/white_TRIANGLE.svg new file mode 100644 index 0000000..411ec2f --- /dev/null +++ b/pieces/Alapo/white_TRIANGLE.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_TRIANGLE_inv.svg b/pieces/Alapo/white_TRIANGLE_inv.svg new file mode 100644 index 0000000..61733b1 --- /dev/null +++ b/pieces/Alapo/white_TRIANGLE_inv.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_circle.svg b/pieces/Alapo/white_circle.svg new file mode 100644 index 0000000..f5f19cf --- /dev/null +++ b/pieces/Alapo/white_circle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_square.svg b/pieces/Alapo/white_square.svg new file mode 100644 index 0000000..9c7e4e7 --- /dev/null +++ b/pieces/Alapo/white_square.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_triangle.svg b/pieces/Alapo/white_triangle.svg new file mode 100644 index 0000000..abad0f9 --- /dev/null +++ b/pieces/Alapo/white_triangle.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/Alapo/white_triangle_inv.svg b/pieces/Alapo/white_triangle_inv.svg new file mode 100644 index 0000000..4791916 --- /dev/null +++ b/pieces/Alapo/white_triangle_inv.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/pieces/ambiguous_target.svg b/pieces/Ambiguous/target.svg similarity index 100% rename from pieces/ambiguous_target.svg rename to pieces/Ambiguous/target.svg diff --git a/pieces/chakart_banana.svg b/pieces/Chakart/banana.svg similarity index 100% rename from pieces/chakart_banana.svg rename to pieces/Chakart/banana.svg diff --git a/pieces/chakart_bomb.svg b/pieces/Chakart/bomb.svg similarity index 100% rename from pieces/chakart_bomb.svg rename to pieces/Chakart/bomb.svg diff --git a/pieces/chakart_egg.svg b/pieces/Chakart/egg.svg similarity index 100% rename from pieces/chakart_egg.svg rename to pieces/Chakart/egg.svg diff --git a/pieces/chakart_mushroom.svg b/pieces/Chakart/mushroom.svg similarity index 100% rename from pieces/chakart_mushroom.svg rename to pieces/Chakart/mushroom.svg diff --git a/pieces/chakart_mystery_black.svg b/pieces/Chakart/mystery_black.svg similarity index 100% rename from pieces/chakart_mystery_black.svg rename to pieces/Chakart/mystery_black.svg diff --git a/pieces/chakart_mystery_white.svg b/pieces/Chakart/mystery_white.svg similarity index 100% rename from pieces/chakart_mystery_white.svg rename to pieces/Chakart/mystery_white.svg diff --git a/pieces/chakart_shell.svg b/pieces/Chakart/shell.svg similarity index 100% rename from pieces/chakart_shell.svg rename to pieces/Chakart/shell.svg diff --git a/variants.js b/variants.js index c9af9e4..90e9244 100644 --- a/variants.js +++ b/variants.js @@ -1,7 +1,7 @@ const variants = [ // TODO: https://mancala.fandom.com/wiki/William_Daniel_Troyka Cleopatra chess {name: 'Absorption', desc: 'Absorb powers'}, -// {name: 'Alapo', desc: 'Geometric Chess'}, + {name: 'Alapo', desc: 'Geometric Chess'}, // {name: 'Alice', desc: 'Both sides of the mirror'}, // {name: 'Align4', desc: 'Align four pawns'}, // {name: 'Allmate', desc: 'Mate any piece'}, diff --git a/variants/Alapo/class.js b/variants/Alapo/class.js new file mode 100644 index 0000000..eb0e73f --- /dev/null +++ b/variants/Alapo/class.js @@ -0,0 +1,156 @@ +import ChessRules from "/base_rules.js"; +import { ArrayFun } from "/utils/array.js"; +import { Random } from "/utils/alea.js"; + +export default class AlapoRules extends ChessRules { + + get hasFlags() { + return false; + } + get hasEnpassant() { + return false; + } + + getSvgChessboard() { + let board = super.getSvgChessboard().slice(0, -6); + // Add lines to delimitate goals + board += ` + + + `; + return board; + } + + genRandInitFen(seed) { + if (this.options["randomness"] == 0) + return "rbqqbr/tcssct/6/6/TCSSCT/RBQQBR w 0"; + + Random.setSeed(seed); + + const piece2pawn = { + r: 't', + q: 's', + b: 'c' + }; + + let pieces = { w: new Array(6), b: new Array(6) }; + // Shuffle pieces on first (and last rank if randomness == 2) + for (let c of ["w", "b"]) { + if (c == 'b' && this.options["randomness"] == 1) { + pieces['b'] = pieces['w']; + break; + } + + let positions = ArrayFun.range(6); + + // Get random squares for bishops + let randIndex = 2 * Random.randInt(3); + const bishop1Pos = positions[randIndex]; + let randIndex_tmp = 2 * Random.randInt(3) + 1; + const bishop2Pos = positions[randIndex_tmp]; + positions.splice(Math.max(randIndex, randIndex_tmp), 1); + positions.splice(Math.min(randIndex, randIndex_tmp), 1); + + // Get random square for queens + randIndex = Random.randInt(4); + const queen1Pos = positions[randIndex]; + positions.splice(randIndex, 1); + randIndex = Random.randInt(3); + const queen2Pos = positions[randIndex]; + positions.splice(randIndex, 1); + + // Rooks positions are now fixed, + const rook1Pos = positions[0]; + const rook2Pos = positions[1]; + + pieces[c][rook1Pos] = "r"; + pieces[c][bishop1Pos] = "b"; + pieces[c][queen1Pos] = "q"; + pieces[c][queen2Pos] = "q"; + pieces[c][bishop2Pos] = "b"; + pieces[c][rook2Pos] = "r"; + } + + return ( + pieces["b"].join("") + "/" + + pieces["b"].map(p => piece2pawn[p]).join("") + + "/6/6/" + + pieces["w"].map(p => piece2pawn[p].toUpperCase()).join("") + "/" + + pieces["w"].join("").toUpperCase() + + " w 0" + ); + } + + pieces(color, x, y) { + return { + 'r': super.pieces(color, x, y)['r'], + 'q': super.pieces(color, x, y)['q'], + 'b': { + // Triangle is rotated from opponent viewpoint + "class": "bishop" + (this.playerColor != color ? "_inv" : ""), + moves: [ { steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]] } ] + }, + 's': { //"square" + "class": "babyrook", + moves: [ + { + steps: [[0, 1], [0, -1], [1, 0], [-1, 0]], + range: 1 + } + ] + }, + 'c': { //"circle" + "class": "babyqueen", + moves: [ + { + steps: [ + [0, 1], [0, -1], [1, 0], [-1, 0], + [1, 1], [1, -1], [-1, 1], [-1, -1] + ], + range: 1 + } + ] + }, + 't': { //"triangle" + "class": "babybishop" + (this.playerColor != color ? "_inv" : ""), + moves: [ + { + steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]], + range: 1 + } + ] + } + }; + } + + get size() { + return { + x: 6, + y: 6 + }; + } + + filterValid(moves) { + return moves; + } + + getCurrentScore() { + // Try both colors (to detect potential suicides) + let won = {}; + for (let c of ['w', 'b']) { + const oppCol = C.GetOppCol(c); + const goal = (c == 'w' ? 0 : 5); + won[c] = this.board[goal].some((b,j) => { + return ( + this.getColor(goal, j) == c && + this.findCapturesOn( + [goal, j], {one: true, oppCol: oppCol}).length == 0 + ); + }); + } + if (won['w'] && won['b']) + return "?"; //no idea who won, not relevant anyway :) + return (won['w'] ? "1-0" : (won['b'] ? "0-1" : "*")); + } + +}; diff --git a/variants/Alapo/rules.html b/variants/Alapo/rules.html new file mode 100644 index 0000000..252699c --- /dev/null +++ b/variants/Alapo/rules.html @@ -0,0 +1,7 @@ +

Pieces move like rook, bishop and queen. Small ones by one square only.

+ +

Goal: bring a piece safely on the last rank.

+ + + chessvariants page. + diff --git a/variants/Alapo/style.css b/variants/Alapo/style.css new file mode 100644 index 0000000..942f9f4 --- /dev/null +++ b/variants/Alapo/style.css @@ -0,0 +1,49 @@ +piece.black.rook { + background-image: url('/pieces/Alapo/black_SQUARE.svg'); +} +piece.black.bishop { + background-image: url('/pieces/Alapo/black_TRIANGLE.svg'); +} +piece.black.bishop_inv { + background-image: url('/pieces/Alapo/black_TRIANGLE_inv.svg'); +} +piece.black.queen { + background-image: url('/pieces/Alapo/black_CIRCLE.svg'); +} +piece.black.babyrook { + background-image: url('/pieces/Alapo/black_square.svg'); +} +piece.black.babybishop { + background-image: url('/pieces/Alapo/black_triangle.svg'); +} +piece.black.babybishop { + background-image: url('/pieces/Alapo/black_triangle_inv.svg'); +} +piece.black.babyqueen { + background-image: url('/pieces/Alapo/black_circle.svg'); +} + +piece.white.rook { + background-image: url('/pieces/Alapo/white_SQUARE.svg'); +} +piece.white.bishop { + background-image: url('/pieces/Alapo/white_TRIANGLE.svg'); +} +piece.white.bishop { + background-image: url('/pieces/Alapo/white_TRIANGLE_inv.svg'); +} +piece.white.queen { + background-image: url('/pieces/Alapo/white_CIRCLE.svg'); +} +piece.white.babyrook { + background-image: url('/pieces/Alapo/white_square.svg'); +} +piece.white.babybishop { + background-image: url('/pieces/Alapo/white_triangle.svg'); +} +piece.white.babybishop { + background-image: url('/pieces/Alapo/white_triangle_inv.svg'); +} +piece.white.babyqueen { + background-image: url('/pieces/Alapo/white_circle.svg'); +} diff --git a/variants/Ambiguous/CREDITS b/variants/Ambiguous/CREDITS new file mode 100644 index 0000000..68ab598 --- /dev/null +++ b/variants/Ambiguous/CREDITS @@ -0,0 +1,3 @@ +Images: + +https://freesvg.org/black-target diff --git a/variants/Ambiguous/style.css b/variants/Ambiguous/style.css index e31d810..db300f7 100644 --- a/variants/Ambiguous/style.css +++ b/variants/Ambiguous/style.css @@ -1,7 +1,7 @@ @import url("/base_pieces.css"); piece.target { - background-image: url('/pieces/ambiguous_target.svg'); + background-image: url('/pieces/Ambiguous/target.svg'); } piece.white.target-pawn { diff --git a/variants/Chakart/style.css b/variants/Chakart/style.css index b3687ce..91ad633 100644 --- a/variants/Chakart/style.css +++ b/variants/Chakart/style.css @@ -1,19 +1,19 @@ @import url("/base_pieces.css"); piece.egg { - background-image: url('/pieces/chakart_egg.svg'); + background-image: url('/pieces/Chakart/egg.svg'); } piece.mushroom { - background-image: url('/pieces/chakart_mushroom.svg'); + background-image: url('/pieces/Chakart/mushroom.svg'); } piece.banana { - background-image: url('/pieces/chakart_banana.svg'); + background-image: url('/pieces/Chakart/banana.svg'); } piece.bomb { - background-image: url('/pieces/chakart_bomb.svg'); + background-image: url('/pieces/Chakart/bomb.svg'); } piece.white.invisible { @@ -29,14 +29,14 @@ piece.immobilized { } piece.remote-capture { - background-image: url('/pieces/chakart_shell.svg'); + background-image: url('/pieces/Chakart/shell.svg'); } piece.mystery.white { - background-image: url('/pieces/chakart_mystery_white.svg'); + background-image: url('/pieces/Chakart/mystery_white.svg'); } piece.mystery.black { - background-image: url('/pieces/chakart_mystery_black.svg'); + background-image: url('/pieces/Chakart/mystery_black.svg'); } div.bonus-text {