}
// Some variants reveal moves only after both players played
- hideMoves() {
+ get hideMoves() {
return false;
}
return 0; //nb of targets
}
- launchAnimation(moves, callback) {
+ launchAnimation(moves, container, callback) {
if (this.hideMoves) {
moves.forEach(m => this.play(m));
callback();
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) {
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;
{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'},
--- /dev/null
+<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>
-<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>
--- /dev/null
+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 "*";
+ }
+
+};
--- /dev/null
+<p>TODO</p>
+
+<p class="author">Jeff Kiska (2000).</p>
--- /dev/null
+@import url("/base_pieces.css");
<body>
<div class="full-rules">
-
<h1>Chakart Rules</h1>
<div>
<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>