Finish Empire variant main
authorBenjamin Auder <benjamin.auder@somewhere>
Sat, 13 Jun 2026 00:13:10 +0000 (02:13 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sat, 13 Jun 2026 00:13:10 +0000 (02:13 +0200)
variants/Empire/class.js
variants/Empire/complete_rules.html [new file with mode: 0644]
variants/Empire/rules.html

index df80d2e..64b2156 100644 (file)
@@ -79,6 +79,25 @@ export default class EmpireRules extends ChessRules {
   }
 
   filterValid(moves) {
   }
 
   filterValid(moves) {
+    // Sub-function to check a path (between kings)
+    const scanPath = (start, end, justOne) => {
+      let s = [end[0] - start[0], end[1] - start[1]];
+      for (const i in [0, 1]) {
+        if (s[i] != 0)
+          s[i] = s[i] / Math.abs(s[i]);
+      }
+      let onPath = {};
+      let [i, j] = [start[0] + s[0], start[1] + s[1]];
+      while (i != end[0] || j != end[1]) {
+        if (this.board[i][j] != "") {
+          onPath[i + "." + j] = true;
+          if (justOne)
+            return true;
+        }
+        [i, j] = [i + s[0], j + s[1]];
+      }
+      return (justOne ? false : onPath);
+    };
     const kp = {
       'w': super.searchKingPos('w')[0],
       'b': super.searchKingPos('b')[0]
     const kp = {
       'w': super.searchKingPos('w')[0],
       'b': super.searchKingPos('b')[0]
@@ -89,21 +108,39 @@ export default class EmpireRules extends ChessRules {
       // Filter out moves letting kings facing each other
       if (
         !pf &&
       // Filter out moves letting kings facing each other
       if (
         !pf &&
-        [m.start, m.end].every(xy => {
-          return ['w','b'].every(c => xy.x != kp[c][0] || xy.y != kp[c][1]);
-        })
+        ['w','b'].every(c => m.start.x != kp[c][0] || m.start.y != kp[c][1])
       ) {
       ) {
-        // King don't face each other and don't move
+        // Kings don't face each other and don't move
         return true;
       }
       if (pf) {
         // Check that current move doesn't clear the path between kings
         return true;
       }
       if (pf) {
         // Check that current move doesn't clear the path between kings
-        // TODO: apply vanish / appear on the path (horizontal or vertical)
-        return true;
+        const onPath = scanPath(kp['b'], kp['w']);
+        m.vanish.forEach(v => {
+          const key = v.x + "." + v.y;
+          if (onPath[key])
+            onPath[key] = false;
+        });
+        if (Object.values(onPath).some(z => z))
+          return true;
+        for (const a of m.appear) {
+          const key = a.x + "." + a.y;
+          if (Object.keys(onPath).includes(key))
+            return true;
+        }
+        return false;
       }
       }
-      // Situation: a king moves. Does it lead to a forbidden configuration ?
-      // TODO: check alignment, then check path (same as above).
-      return true;
+      // A king moves. Does it lead to a forbidden configuration ?
+      const kc =
+        ['w','b'].filter(c => m.start.x == kp[c][0] && m.start.y == kp[c][1]);
+      const oppCol = C.GetOppTurn(kc);
+      if (kp[oppCol][0] != m.end.x && kp[oppCol][1] != m.end.y)
+        return true;
+      // Potentially yes:
+      this.playOnBoard(m);
+      const valid = scanPath(kp[oppCol], [m.end.x, m.end.y], true);
+      this.undoOnBoard(m);
+      return valid;
     });
   }
 
     });
   }
 
diff --git a/variants/Empire/complete_rules.html b/variants/Empire/complete_rules.html
new file mode 100644 (file)
index 0000000..7fc2a1b
--- /dev/null
@@ -0,0 +1,134 @@
+<html>
+<head>
+  <title>Empire Rules</title>
+  <link href="/css/common.css" rel="stylesheet"/>
+  <link href="/variants/Empire/style.css" rel="stylesheet"/>
+</head>
+<body>
+<div class="full-rules">
+<h1>Empire Rules</h1>
+
+<div>
+  <p>
+    The player in first has a different set of pieces,
+    moving generally like a queen but capturing (almost) as usual.
+  </p>
+  <figure>
+    <img src="/extras/Empire/Board.png"/>
+    <figcaption>Initial deterministic setup.</figcaption>
+  </figure>
+  <p>
+    Empire Chess is a chess variant designed in 2020 by Couch Tomato, the
+    third asymmetric game. This game pits the army of the "Empire" (gold)
+    against the original chess army (the "Kingdom", black). The Empire's
+    unique feature is that its pieces move like queens but attack differently.
+  </p>
+</div>
+
+<h3>General Rules</h3>
+<ol>
+  <li>The Empire (gold) always moves first.</li>
+  <li>The Empire cannot castle.</li>
+  <li>
+    As the Empire's pawns start on the third rank, they do not have the
+    option to move two spaces or be captured by en passant.
+  </li>
+  <li>Pawns on either side can only promote to a queen.</li>
+  <li>
+    One can win by bringing the king into the final rank without being
+    check. This situation is called "campmate".
+  </li>
+  <li>Stalemate and repetition are both losses.</li>
+  <li>
+    The King and Kaiser (Imperial King) may not face
+    each other on a file or rank.
+  </li>
+</ol>
+
+<h3>Imperial Pieces</h3>
+<div>
+  <p>
+    There are five new units unique to the Empire: Siege Towers, Eagles,
+    Cardinals, Duke, and Soldiers. The bottom rank pieces are all stronger
+    than their Kingdom counterparts with the exception of the Duke.
+  </p>
+  <ul>
+    <li>
+      Kaiser (K) &mdash; The Imperial king is called the Kaiser and has a
+      different symbol, but the change is purely aesthetic and thematic:
+      it behave like an orthodox king.
+    </li>
+    <li>
+      Soldier (S) &mdash; The Soldiers are the two pawn-like pieces replacing
+      the two middle pawns. They can move one square orthogonally forward,
+      or lateraly.
+    </li>
+  </ul>
+  <p>
+    The remaining pieces are "divergent" pieces: they move differently
+    than they attack (such as pawns). Imperial pieces all move as queens,
+    but attack like their Kingdom counterpart except for the Duke.
+  </p>
+  <ul>
+    <li>
+      Siege Tower (T) &mdash; The Siege Tower, or Tower for short,
+      attacks like a Rook.
+    </li>
+    <li>Eagle (E) &mdash; The Eagle attacks like a Knight.</li>
+    <li>Cardinal (C) &mdash; The Cardinal attacks like a Bishop.</li>
+    <li>Duke (D) &mdash; The Duke attacks like a King.</li>
+  </ul>
+  <figure>
+    <img src="/extras/Empire/EagleMoves.png"/>
+    <figcaption>Eagle's moves (green) &amp; captures (red).</figcaption>
+  </figure>
+</div>
+
+<h3>Pieces valuation</h3>
+<div>
+  <p>The following simplified values can be used:</p>
+  <table>
+    <tr>
+      <th>Kingdom piece</th>
+      <th>Values</th>
+      <th>Imperial piece</th>
+    </tr>
+    <tr>
+      <td>Pawn</td>
+      <td>1 / 1</td>
+      <td>Pawn</td>
+    </tr>
+    <tr>
+      <td>Queen</td>
+      <td>9 / 4</td>
+      <td>Duke</td>
+    </tr>
+    <tr>
+      <td>Bishop</td>
+      <td>3 / 4</td>
+      <td>Cardinal</td>
+    </tr>
+    <tr>
+      <td>Knight</td>
+      <td>3 / 7</td>
+      <td>Eagle</td>
+    </tr>
+    <tr>
+      <td>Rook</td>
+      <td>5 / 7</td>
+      <td>Siege Tower</td>
+    </tr>
+    <tr>
+      <td> - </td>
+      <td> - / 2</td>
+      <td>Soldier</td>
+    </tr>
+  </table>
+</div>
+
+<h3>More information</h3>
+<p>
+  See 
+  <a href="https://www.pychess.org/variants/empire">Empire Chess</a>
+  on pychess.org, where you can also play this variant (among many others !).
+</p>
index c65158e..01f8682 100644 (file)
@@ -1 +1,19 @@
-<p>TODO</p>
+<p>
+  Two different armies: yellow pieces ("kingdom") generally move and
+  capture in two different ways. Tower, Eagle, Cardinal and Duke, initially
+  from square a1 to d1, all move like a queen, but capture respectively
+  like a rook, knight, bishop and king.
+</p>
+<p>
+  The two "big pawns" in the middle are soldiers, they move and capture in
+  the same way, forward one square or laterally.
+</p>
+<p>Win by checkmate or by crossing the board with your king.</p>
+
+<p>
+  <a target="_blank" href="/variants/Empire/complete_rules.html">
+    Full rules description.
+  </a>
+</p>
+
+<p class="author">Couch Tomato (2020).</p>