A few fixes, specify Apocalypse rules, draft Arena
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 3 Jul 2022 22:20:27 +0000 (00:20 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 3 Jul 2022 22:20:27 +0000 (00:20 +0200)
base_rules.js
common.css
variants.js
variants/Apocalypse/complete_rules.html [new file with mode: 0644]
variants/Apocalypse/rules.html
variants/Arena/class.js [new file with mode: 0644]
variants/Arena/rules.html [new file with mode: 0644]
variants/Arena/style.css [new file with mode: 0644]
variants/Chakart/complete_rules.html
variants/Chakart/rules.html

index 08e9d1b..0b7d6ed 100644 (file)
@@ -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) {
index 167822b..cdfbc7a 100644 (file)
@@ -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;
index d3831c6..1c4d4cb 100644 (file)
@@ -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 (file)
index 0000000..ae45dad
--- /dev/null
@@ -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>
index c65158e..211ad8c 100644 (file)
@@ -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 (file)
index 0000000..801469a
--- /dev/null
@@ -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 (file)
index 0000000..fca97fe
--- /dev/null
@@ -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 (file)
index 0000000..a3550bc
--- /dev/null
@@ -0,0 +1 @@
+@import url("/base_pieces.css");
index 1f64dd6..7bf3080 100644 (file)
@@ -7,7 +7,6 @@
 <body>
 
 <div class="full-rules">
-
 <h1>Chakart Rules</h1>
 
 <div>
index e48a4f7..4b88248 100644 (file)
@@ -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 &amp; Benjamin Auder (2020).</p>