From: Benjamin Auder Date: Tue, 31 Mar 2026 15:39:00 +0000 (+0200) Subject: On the way to 8-pieces implementation X-Git-Url: https://git.auder.net/css/doc/html/scripts/img/rpsls.js?a=commitdiff_plain;h=HEAD;p=xogo.git On the way to 8-pieces implementation --- diff --git a/base_rules.js b/base_rules.js index 8613c4b..83a3c7b 100644 --- a/base_rules.js +++ b/base_rules.js @@ -80,7 +80,7 @@ export default class ChessRules { } // Arguments x, y are useful for Eightpieces (maybe others?) - get pawnPromotions(x, y) { + pawnPromotions(x, y) { return ['q', 'r', 'n', 'b']; } @@ -639,8 +639,7 @@ export default class ChessRules { this[arrName][i][j].style.height = pieceWidth + "px"; let [ip, jp] = this.getPixelPosition(i, j, r); // Translate coordinates to use chessboard as reference: - this[arrName][i][j].style.transform = - `translate(${ip - r.x}px,${jp - r.y}px)`; + this[arrName][i][j].style.translate = `${ip - r.x}px ${jp - r.y}px`; chessboard.appendChild(this[arrName][i][j]); }; const conditionalReset = (arrName) => { @@ -809,8 +808,8 @@ export default class ChessRules { this.g_pieces[i][j].style.height = pieceWidth + "px"; const [ip, jp] = this.getPixelPosition(i, j, newR); // Translate coordinates to use chessboard as reference: - this.g_pieces[i][j].style.transform = - `translate(${ip - newX}px,${jp - newY}px)`; + this.g_pieces[i][j].style.translate = + `${ip - newX}px ${jp - newY}px`; } } } @@ -1667,7 +1666,7 @@ export default class ChessRules { finalPieces = [this.getPieceType(x2, y2)]; } else - finalPieces = this.pawnPromotions; + finalPieces = this.pawnPromotions(x2, y2); m.appear[0].p = finalPieces[0]; if (initPiece == "!") //cannibal king-pawn m.appear[0].p = C.CannibalKingCode[finalPieces[0]]; @@ -1692,10 +1691,12 @@ export default class ChessRules { m.appear[0].x == m.start.x && m.appear[0].y == m.start.y ) { - m.appear[0].p = this.pawnPromotions[0]; - for (let i=1; i { movingPiece.style.transitionDuration = duration + "s"; // movingPiece is child of container: no need to adjust coordinates - movingPiece.style.transform = `translate(${arr[0]}px, ${arr[1]}px)`; + movingPiece.style.translate = `${arr[0]}px ${arr[1]}px`; setTimeout(cb, duration * 1000); }, 50); }; diff --git a/variants.js b/variants.js index 10cf42a..6519dcc 100644 --- a/variants.js +++ b/variants.js @@ -48,7 +48,7 @@ const variants = [ {name: 'Doublearmy', desc: '64 pieces on the board', disp: 'Double Army'}, {name: 'Doublemove', desc: 'Double moves'}, {name: 'Dynamo', desc: 'Push and pull'}, -// {name: 'Eightpieces', desc: 'Each piece is unique', disp: '8 Pieces'}, + {name: 'Eightpieces', desc: 'Each piece is unique', disp: '8 Pieces'}, // {name: 'Emergo', desc: 'Stacking Checkers variant'}, // {name: 'Empire', desc: 'Empire versus Kingdom'}, // {name: 'Enpassant', desc: 'Capture en passant', disp: 'En-passant'}, diff --git a/variants/Apocalypse/class.js b/variants/Apocalypse/class.js index 3b735b1..681873f 100644 --- a/variants/Apocalypse/class.js +++ b/variants/Apocalypse/class.js @@ -17,7 +17,7 @@ export default class ApocalypseRules extends ChessRules { return true; } - get pawnPromotions() { + pawnPromotions() { return ['n', 'p']; } diff --git a/variants/Avalanche/class.js b/variants/Avalanche/class.js index 8a4981f..dffc846 100644 --- a/variants/Avalanche/class.js +++ b/variants/Avalanche/class.js @@ -58,7 +58,7 @@ export default class AvalancheRules extends ChessRules { return null; } let moves = []; - this.pawnPromotions.forEach(pr => { + this.pawnPromotions().forEach(pr => { moves.push( new Move({ vanish: [new PiPo({x: coords.x, y: coords.y, c: this.turn, p: 'p'})], diff --git a/variants/Balaklava/class.js b/variants/Balaklava/class.js index 1ee2dd7..06ce365 100644 --- a/variants/Balaklava/class.js +++ b/variants/Balaklava/class.js @@ -3,7 +3,7 @@ import {FenUtil} from "/utils/setupPieces.js"; export default class BalaklavaRules extends ChessRules { - get pawnPromotions() { + pawnPromotions() { return ['r', 'm', 'b', 'q']; } diff --git a/variants/Capablanca/class.js b/variants/Capablanca/class.js index 5b1c80e..60416ca 100644 --- a/variants/Capablanca/class.js +++ b/variants/Capablanca/class.js @@ -3,7 +3,7 @@ import {FenUtil} from "/utils/setupPieces.js"; export default class CapablancaRules extends ChessRules { - get pawnPromotions() { + pawnPromotions() { return ['q', 'e', 's', 'r', 'n', 'b']; } diff --git a/variants/Chakart/class.js b/variants/Chakart/class.js index 3454d8f..006193c 100644 --- a/variants/Chakart/class.js +++ b/variants/Chakart/class.js @@ -25,7 +25,7 @@ export default class ChakartRules extends ChessRules { }; } - get pawnPromotions() { + pawnPromotions() { return ['q', 'r', 'n', 'b', 'k']; } @@ -404,7 +404,7 @@ export default class ChakartRules extends ChessRules { this.reserve = { w: {}, b: {} }; // Randomly select a piece in pawnPromotions if (!move.toadette) - move.toadette = Random.sample(this.pawnPromotions); + move.toadette = Random.sample( this.pawnPromotions() ); this.reserve[color][move.toadette] = 1; this.re_drawReserve([color]); } diff --git a/variants/Cwda/class.js b/variants/Cwda/class.js index db79917..32f0322 100644 --- a/variants/Cwda/class.js +++ b/variants/Cwda/class.js @@ -275,7 +275,7 @@ export default class CwdaRules extends ChessRules { ); } - get pawnPromotions() { + pawnPromotions() { // Can promote in anything from the two current armies let promotions = []; for (let army of ["army1", "army2"]) { diff --git a/variants/Discoduel/class.js b/variants/Discoduel/class.js index ec96a43..26f02ea 100644 --- a/variants/Discoduel/class.js +++ b/variants/Discoduel/class.js @@ -7,7 +7,7 @@ export default class DiscoduelRules extends ChessRules { return {}; //nothing would make sense } - get pawnPromotions() { + pawnPromotions() { return ['p']; } diff --git a/variants/Dobutsu/class.js b/variants/Dobutsu/class.js index d8ceafa..cca2920 100644 --- a/variants/Dobutsu/class.js +++ b/variants/Dobutsu/class.js @@ -68,7 +68,7 @@ export default class DobutsuRules extends ChessRules { super(o); } - get pawnPromotions() { + pawnPromotions() { return ['h']; } diff --git a/variants/Dynamo/class.js b/variants/Dynamo/class.js index 5098bbb..1e4592c 100644 --- a/variants/Dynamo/class.js +++ b/variants/Dynamo/class.js @@ -65,7 +65,7 @@ export default class DynamoRules extends ChessRules { while (this.onBoard(i, j) && this.board[i][j] == "") { if (i == lastRank && piece == 'p') { // Promotion by push or pull (if suicide) - this.pawnPromotions.forEach(p => { + this.pawnPromotions().forEach(p => { let move = super.getBasicMove([x, y], [i, j], { c: color, p: p }); moves.push(move); }); diff --git a/variants/Eightpieces/class.js b/variants/Eightpieces/class.js index fa14438..0627b64 100644 --- a/variants/Eightpieces/class.js +++ b/variants/Eightpieces/class.js @@ -1,4 +1,5 @@ import {FenUtil} from "/utils/setupPieces.js"; +import ChessRules from "/base_rules.js"; import PiPo from "/utils/PiPo.js"; import Move from "/utils/Move.js"; @@ -13,7 +14,7 @@ export default class EightpiecesRules extends ChessRules { }; } - get pawnPromotions(x, y) { + pawnPromotions(x, y) { const base_pieces = ['q', 'r', 'n', 'b', 'j', 's']; let lancers = []; if (y > 0) @@ -27,18 +28,18 @@ export default class EightpiecesRules extends ChessRules { if (y < this.size.y) lancers.push('f'); } - else { //x == this.size.x (8) + else { //x == this.size.x-1 (7) lancers.push('c'); if (y > 0) lancers.push('o'); if (y < this.size.y) lancers.push('d'); } - return ['q', 'r', 'n', 'b', 'j', 's', 'l']; + return base_pieces.concat(lancers); } genRandInitBaseFen() { - const s = FenUtil.setupPieces( + let s = FenUtil.setupPieces( ['j', 'l', 's', 'q', 'k', 'b', 'n', 'r'], { randomness: this.options["randomness"], @@ -48,21 +49,26 @@ export default class EightpiecesRules extends ChessRules { flags: ['r', 'j'] } ); + const random = (this.options["randomness"] > 0); + const fen = s.b.join("").replace('l', random ? 'g' : 'f') + + "/pppppppp/8/8/8/8/PPPPPPPP/" + + s.w.join("").replace('l', random > 0 ? 'c' : 'd').toUpperCase(); return { - fen: s.b.join("") + "/pppppppp/8/8/8/8/PPPPPPPP/" + - s.w.join("").toUpperCase(), + fen: fen, o: {flags: s.flags} }; } setOtherVariables(fenParsed) { super.setOtherVariables(fenParsed); - // TODO: state variables (sentry pushes, lancers?) + //this.pushFrom = + //this.afterPush = } + // TODO: FEN utils pushFrom et afterPush + pieces(color, x, y) { - const base_pieces = super.pieces(color, x, y); - return { + return Object.assign({ 'j': { "class": "jailer", moves: [ @@ -71,6 +77,7 @@ export default class EightpiecesRules extends ChessRules { }, 's': { "class": "sentry", + indirectAttack: true, both: [ {steps: [[1, 1], [1, -1], [-1, 1], [-1, -1]]} ] @@ -123,14 +130,14 @@ export default class EightpiecesRules extends ChessRules { {steps: [[-1, -1]]} ] }, - }; + }, super.pieces(color, x, y)); } isImmobilized([x, y]) { const color = this.getColor(x, y); - const oppCol = C.getOppTurn(color); + const oppCol = C.GetOppTurn(color); const stepSpec = this.getStepSpec(color, x, y, 'j'); - for (let step of stepSpec.both[0].steps) { + for (let step of stepSpec.moves[0].steps) { let [i, j] = this.increment([x, y], step); if ( this.onBoard(i, j) && @@ -143,9 +150,18 @@ export default class EightpiecesRules extends ChessRules { return false; } + getPotentialMovesFrom([x, y], color) { + if (!this.pushFrom) + return super.getPotentialMovesFrom([x, y], color); + if (x != this.pushFrom.x || y != this.pushFrom.y) + return []; + // After sentry "attack": move enemy as if it was ours + return []; //TODO + } + getSentryPushes(x, y) { // TODO: return all squares piece on x, y can be pushed to - // Simple + return [{x: x+1, y: y-1}]; } // Post-process sentry pushes (if any) @@ -171,56 +187,18 @@ export default class EightpiecesRules extends ChessRules { return finalMoves; } -//idée exception globle dans base_rules.js d'une pièce marquée comme "indirect attack" ?! - // TODO:::::: under sentry attack?! - // Is piece (or square) at given position attacked by "oppCol(s)" ? - underAttack([x, y], oppCols) { - super.underAttack([x, y], oppCols) - // An empty square is considered as king, - // since it's used only in getCastleMoves (TODO?) - const king = this.board[x][y] == "" || this.isKing(x, y); - return ( - ( - (!this.options["zen"] || king) && - this.findCapturesOn( - [x, y], - { - byCol: oppCols, - one: true - } - ) - ) - || - ( - (!!this.options["zen"] && !king) && - this.findDestSquares( - [x, y], - { - attackOnly: true, - one: true - }, - ([i1, j1], [i2, j2]) => oppCols.includes(this.getColor(i2, j2)) - ) - ) - ); - } - - - // TODO::: sentry subturn ??? - // 'color' arg because some variants (e.g. Refusal) check opponent moves + // Lazy sentry attacks check: after push move filterValid(moves, color) { - color = color || this.turn; - const oppCols = this.getOppCols(color); - let kingPos = this.searchKingPos(color); - return moves.filter(m => { - this.playOnBoard(m); - const res = this.trackKingWrap(m, kingPos, (kp) => { - return !this.underCheck(kp, oppCols); - }); - this.undoOnBoard(m); - return res; + let sentryAttack = []; + moves = moves.filter(m => { + if (m.appear.length == 0) { + sentryAttack.push(m); + return false; + } + return true; }); + return super.filterValid(moves, color).concat(sentryAttack); } }; diff --git a/variants/Giveaway/class.js b/variants/Giveaway/class.js index 45f6a34..ed05d23 100644 --- a/variants/Giveaway/class.js +++ b/variants/Giveaway/class.js @@ -30,7 +30,7 @@ export default class GiveawayRules extends ChessRules { return this.options["mode"] == "losers"; } - get pawnPromotions() { + pawnPromotions() { let res = ['q', 'r', 'n', 'b']; if (this.options["mode"] == "suicide") res.push('k'); diff --git a/variants/Suction/class.js b/variants/Suction/class.js index ff307d4..08254fd 100644 --- a/variants/Suction/class.js +++ b/variants/Suction/class.js @@ -21,7 +21,7 @@ export default class SuctionRules extends ChessRules { }; } - get pawnPromotions() { + pawnPromotions() { return ['p']; //no promotions }