From: Benjamin Auder <benjamin.auder@somewhere> Date: Sun, 3 Jul 2022 22:20:27 +0000 (+0200) Subject: A few fixes, specify Apocalypse rules, draft Arena X-Git-Url: https://git.auder.net/variants/current/doc/scripts/common.css?a=commitdiff_plain;h=126ffc709b84d4919dc2c1726577e59211198a1b;p=xogo.git A few fixes, specify Apocalypse rules, draft Arena --- diff --git a/base_rules.js b/base_rules.js index 08e9d1b..0b7d6ed 100644 --- a/base_rules.js +++ b/base_rules.js @@ -117,7 +117,7 @@ export default class ChessRules { } // Some variants reveal moves only after both players played - hideMoves() { + get hideMoves() { return false; } @@ -2631,7 +2631,7 @@ export default class ChessRules { return 0; //nb of targets } - launchAnimation(moves, callback) { + launchAnimation(moves, container, callback) { if (this.hideMoves) { moves.forEach(m => this.play(m)); callback(); @@ -2658,10 +2658,17 @@ export default class ChessRules { alert("New move! Let's go back to game..."); document.getElementById("gameInfos").style.display = "none"; container.style.display = "block"; - setTimeout(() => this.launchAnimation(moves, callback), 700); + setTimeout( + () => this.launchAnimation(moves, container, callback), + 700 + ); + } + else { + setTimeout( + () => this.launchAnimation(moves, container, callback), + delay || 0 + ); } - else - setTimeout(() => this.launchAnimation(moves, callback), delay || 0); }; let container = document.getElementById(this.containerId); if (document.hidden) { diff --git a/common.css b/common.css index 167822b..cdfbc7a 100644 --- a/common.css +++ b/common.css @@ -178,6 +178,10 @@ main > div { max-width: 800px; margin: 20px auto; padding: 0 10px; + overflow: auto; +} +.full-rules > div { + margin-bottom: 20px; } .full-rules h1, .full-rules h2, .full-rules h3, .full-rules h4 { font-weight: bold; diff --git a/variants.js b/variants.js index d3831c6..1c4d4cb 100644 --- a/variants.js +++ b/variants.js @@ -9,7 +9,7 @@ const variants = [ {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'}, + {name: 'Arena', desc: 'Middle battle'}, // {name: 'Atarigo', desc: 'First capture wins', disp: 'Atari-Go'}, {name: 'Atomic', desc: 'Explosive captures'}, // {name: 'Avalam', desc: 'Build towers'}, diff --git a/variants/Apocalypse/complete_rules.html b/variants/Apocalypse/complete_rules.html new file mode 100644 index 0000000..ae45dad --- /dev/null +++ b/variants/Apocalypse/complete_rules.html @@ -0,0 +1,105 @@ +<html> +<head> + <title>Apocalypse Rules</title> + <link href="/common.css" rel="stylesheet"/> + <link href="/variants/Apocalypse/style.css" rel="stylesheet"/> +</head> +<body> + +<div class="full-rules"> +<h1>Apocalypse Rules</h1> + +<div> + <p> + Both players play a move "at the same time". + The goal is to eliminate all enemy pawns. + </p> + <figure> + <div class="diag" + data-fen='npppn/p3p/5/P3P/NPPPN w 0 {"whiteMove":"-","penalties":"00"}'> + </div> + <figcaption>Initial position.</figcaption> + </figure> + <p> + This variant is inspired by the + <a href="https://en.wikipedia.org/wiki/Four_Horsemen_of_the_Apocalypse"> + Four Horsemen of the Apocalypse + </a> + mythology. Knights are horsemen, and pawns are footmen. + If all footmen of one color die, the other side wins. + </p> + <p> + At each turn you can decide either to play safely an apparently valid + move, or speculate on your opponent's move and choose a move valid only + conditionally on his choice. In this last case the move may end up not + being playable: you would get a penalty point. Two penalty points loses + the game. For example in the initial position, 1.(c1)c2 is safe while + 1.axb3 will be valid only if black plays 1...Nb3. +</div> + +<div> + <p>Resolving rules:</p> + <ul> + <li> + If both moves are illegal none are played. + If one is illegal, the other is played. + </li> + <li> + If a capture is intended but the target moved, the move is still played + without capturing anything. + </li> + <li> + If both moves arrive on the same square: the illegal move prevails + (if any), so the other piece vanishes (higher risk is rewarded). + If both moves are legal, then a horseman wins over a footman, + whereas two pieces of the same nature disappear. + </li> + </ul> + <figure> + <div class="diag" + data-fen='npppn/p4/4P/P2pP/NPP1N w 0 {"whiteMove":"-","penalties":"00"}'> + </div> + <figcaption> + After 1.d1d2 e4e3 2.dxe3 exd2, pawns placements are inversed. + </figcaption> + </figure> +</div> + +<div> + <h3>Promotions</h3> + <p> + Pawns automatically promote in a knight, except if the player already + have two horsemen on the board. In this case the footman is relocated on + any free square which is not on last rank. + Even in this last case, pawn promotions may appear possible by + anticipation of a knight capture. This is risky but playable. + </p> + <h3>End of the game</h3> + <p> + As stated previously, losing all pawns lose the game, so promoting your + last pawn loses. It may be the only legal move. + If however both footmen armies vanish at the same time, it's a draw. + It can happen if the two last pawns decide to advance to the same square + for example. + Finally, if both sides get the second penalty point at the same time + it's also a draw. + </p> + <h3>Resources</h3> + <p> + <a href="https://www.chessvariants.com/rules/apocalypse"> + Apocalypse chess + </a> + on chessvariants.com. This variant is playable at + <a href="http://apocalypsechess.online/"> + apocalypsechess.online + </a> + without the promotion restriction. + </p> +</div> + +</div> + +</body> +<script src="/utils/drawDiagrams.js"></script> +<script>fenToDiag("Apocalypse");</script> +</html> diff --git a/variants/Apocalypse/rules.html b/variants/Apocalypse/rules.html index c65158e..211ad8c 100644 --- a/variants/Apocalypse/rules.html +++ b/variants/Apocalypse/rules.html @@ -1 +1,13 @@ -<p>TODO</p> +<p> + Both players play a move "at the same time". + It can be a legal move, or a move valid only if the opponent + play some specific move. + In this last case, if the move is impossible you get a penalty point. + Two penalty points lose the game. +</p> + +<p>The goal is to eliminate all enemy pawns.</p> + +<a href="/variants/Apocalypse/complete_rules.html">Full rules description.</a> + +<p class="author">C.S. Elliott (1976).</p> diff --git a/variants/Arena/class.js b/variants/Arena/class.js new file mode 100644 index 0000000..801469a --- /dev/null +++ b/variants/Arena/class.js @@ -0,0 +1,102 @@ +import ChessRules from "/base_rules.js"; + +export default class ArenaRules extends ChessRules { + + static get Options() { + return {}; //TODO + } + + get hasFlags() { + return false; + } + + getSvgChessboard() { + let board = super.getSvgChessboard().slice(0, -6); + // Add lines to delimitate the central area + board += ` + <line x1="0" y1="20" x2="80" y2="20" stroke="black" stroke-width="0.15"/> + <line x1="0" y1="60" x2="80" y2="60" stroke="black" stroke-width="0.15"/> + </svg>`; + return board; + } + + pieces(color, x, y) { + let allSpecs = super.pieces(color, x, y); + let pawnSpec = allSpecs['p'], + queenSpec = allSpecs['q'], + kingSpec = allSpecs['k']; + const pawnShift = (color == "w" ? -1 : 1); + Array.prototype.push.apply(pawnSpec.attack[0].steps, + [[-pawnShift, 1], [-pawnShift, -1]]); + queenSpec.moves[0].range = 3; + kingSpec.moves[0].range = 3; + return Object.assign({}, + allSpecs, + { + 'p': pawnSpec, + 'q': queenSpec, + 'k': kingSpec + } + ); + } + + static InArena(x) { + return Math.abs(3.5 - x) <= 1.5; + } + + getPotentialMovesFrom([x, y]) { + const moves = super.getPotentialMovesFrom([x, y]); + // Eliminate moves which neither enter the arena or capture something + return moves.filter(m => { + const startInArena = V.InArena(m.start.x); + const endInArena = V.InArena(m.end.x); + return ( + (startInArena && endInArena && m.vanish.length == 2) || + (!startInArena && endInArena) + ); + }); + } + + filterValid(moves) { + // No check conditions + return moves; + } + + getCurrentScore() { + const color = this.turn; + if (!this.atLeastOneMove(color)) + // I cannot move anymore + return color == 'w' ? "0-1" : "1-0"; + // Win if the opponent has no more pieces left (in the Arena), + // (and/)or if he lost both his dukes. + let someUnitRemain = false, + atLeastOneDuke = false, + somethingInArena = false; + outerLoop: for (let i=0; i<this.size.x; i++) { + for (let j=0; j<this.size.y; j++) { + if (this.getColor(i,j) == color) { + someUnitRemain = true; + if (this.movesCount >= 2 && V.InArena(i)) { + somethingInArena = true; + if (atLeastOneDuke) + break outerLoop; + } + if (['q', 'k'].includes(this.getPiece(i, j))) { + atLeastOneDuke = true; + if (this.movesCount < 2 || somethingInArena) + break outerLoop; + } + } + } + } + if ( + !someUnitRemain || + !atLeastOneDuke || + (this.movesCount >= 2 && !somethingInArena) + ) { + return color == 'w' ? "0-1" : "1-0"; + } + return "*"; + } + +}; diff --git a/variants/Arena/rules.html b/variants/Arena/rules.html new file mode 100644 index 0000000..fca97fe --- /dev/null +++ b/variants/Arena/rules.html @@ -0,0 +1,3 @@ +<p>TODO</p> + +<p class="author">Jeff Kiska (2000).</p> diff --git a/variants/Arena/style.css b/variants/Arena/style.css new file mode 100644 index 0000000..a3550bc --- /dev/null +++ b/variants/Arena/style.css @@ -0,0 +1 @@ +@import url("/base_pieces.css"); diff --git a/variants/Chakart/complete_rules.html b/variants/Chakart/complete_rules.html index 1f64dd6..7bf3080 100644 --- a/variants/Chakart/complete_rules.html +++ b/variants/Chakart/complete_rules.html @@ -7,7 +7,6 @@ <body> <div class="full-rules"> - <h1>Chakart Rules</h1> <div> diff --git a/variants/Chakart/rules.html b/variants/Chakart/rules.html index e48a4f7..4b88248 100644 --- a/variants/Chakart/rules.html +++ b/variants/Chakart/rules.html @@ -10,6 +10,6 @@ <li>Eggs hide either a bonus or malus: see full description.</li> </ul> -<a href="/variants/Chakart/complete_rules.html">Full rules description</a>. +<a href="/variants/Chakart/complete_rules.html">Full rules description.</a> <p class="author">Charlotte Blard & Benjamin Auder (2020).</p>