Finish Sleepy, update TODO
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 10 May 2026 23:58:32 +0000 (01:58 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 10 May 2026 23:58:32 +0000 (01:58 +0200)
TODO
js/variants.js
variants/Sleepy/class.js

diff --git a/TODO b/TODO
index f49a584..7114f80 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,10 +1,6 @@
-Hmm... non ? -->
 Otage, Emergo, Pacosako : fonction "buildPiece(arg1, arg2)" returns HTML element with 2 SVG or SVG + number
-==> plus simple : deux classes, images superposées.
+==> plus simple : deux classes, images superposées (?)
 
 https://fr.wikipedia.org/wiki/Unlur
-Yoxii ?
 
-Idée new variant: "bed" random moves and "capture" (opponent?) pieces which cannot move on next turn (sleeping). (Crazybed ?)
-one "bed" per player.
-one turn = place bed (potentially with opponent piece), then normal move, then random bed move - dropping potential piece on initial square (awaken).
+DuckChess + crazyduck --> move it at random ? Capturing ? Hmm.
index 6519dcc..6b3e6aa 100644 (file)
@@ -133,6 +133,7 @@ const variants = [
 //  {name: 'Shogi', desc: 'Japanese Chess'},
 //  {name: 'Shogun', desc: "General's Chess"},
 //  {name: 'Sittuyin', desc: 'Burmese Chess'},
+  {name: 'Sleepy', desc: 'Lazy pieces', disp: 'Sleepy'},
 //  {name: 'Spartan', desc: 'Spartan versus Persians'},
 //  {name: 'Squatter', desc: 'Squat last rank'},
 //  {name: 'Stealthbomb', desc: 'Beware the bomb'},
@@ -154,6 +155,7 @@ const variants = [
 //  {name: 'Wormhole', desc: 'Squares disappear'},
 //  {name: 'Xiangqi', desc: 'Chinese Chess'},
 //  {name: 'Yote', desc: 'African Draughts'},
+//  {name: 'Yoxii', desc: 'Moving totem'},
   {name: "Zen", desc: "Reverse captures"}
 ];
 
index b50ca0b..07c9a9b 100644 (file)
@@ -1,23 +1,31 @@
 import ChessRules from "/js/base_rules.js";
+import PiPo from "/utils/PiPo.js";
 
 export default class SleepyRules extends ChessRules {
 
   static get Options() {
     return {
       select: C.Options.select,
-      input: C.Options.input,
-      styles: ["balance", "capture", "cylinder", "dark", "rifle", "zen"]
+      input: C.Options.input.concat([
+        {
+          label: "Reset friends",
+          variable: "refresh",
+          type: "checkbox",
+          defaut: false
+        }
+      ]),
+      styles: ["balance", "capture", "cylinder", "dark", "zen"]
     };
   }
 
   setOtherVariables(fenParsed) {
+    this.states = fenParsed.states.split('').map(x => parseInt(x, 10));
     super.setOtherVariables(fenParsed);
-    this.states = JSON.parse(fenParsed.states);
   }
 
   getPartFen(o) {
     return {
-      "states": (o.init ? '0'.repeat(64) : JSON.stringify(this.states)),
+      "states": (o.init ? '0'.repeat(64) : this.states.join('')),
       ...super.getPartFen(o)
     };
   }
@@ -46,21 +54,58 @@ export default class SleepyRules extends ChessRules {
     return super.getPotentialMovesOf(piece, [x, y]);
   }
 
+  // TODO: should post-process only the chosen move ?
+  postProcessPotentialMoves(moves) {
+    moves = super.postProcessPotentialMoves(moves);
+    moves.forEach(mv => {
+      mv.statePatch = {};
+      // 1) Wake up observed pieces
+      const color = mv.vanish[0].c;
+      this.board[mv.start.x][mv.start.y] = "";
+      const rs = super.findDestSquares(
+        [mv.end.x, mv.end.y],
+        {
+          attackOnly: true,
+          // NOTE: wake up others just before falling asleep
+          stepSpec: super.getStepSpec(mv.vanish[0].c, 0, 0, mv.vanish[0].p)
+        },
+        (sq1, [x2, y2]) => this.getColor(x2, y2) == color
+      );
+      this.board[mv.start.x][mv.start.y] = color + mv.vanish[0].p;
+      rs.forEach(r => {
+        const r_idx = this.getStateIndex({x: r.sq[0], y: r.sq[1]});
+        if (!this.states) debugger;
+        if (this.states[r_idx] == 3) {
+          const sleepyPiece = this.getPiece(r.sq[0], r.sq[1]);
+          const awokenPiece = V.M_PIECES[V.S_PIECES.indexOf(sleepyPiece)]
+          mv.vanish.push(
+            new PiPo({x: r.sq[0], y: r.sq[1], c: color, p: sleepyPiece}) );
+          mv.appear.push(
+            new PiPo({x: r.sq[0], y: r.sq[1], c: color, p: awokenPiece}) );
+          mv.statePatch[r_idx] = 0;
+        }
+        else if (this.options["refresh"] && this.states[r_idx] >= 1)
+          mv.statePatch[r_idx] = 0;
+      });
+      // 2) Update sleepy status
+      const m_idx = this.getStateIndex(mv.start);
+      if (this.states[m_idx] == 2)
+        mv.appear[0].p = V.S_PIECES[V.M_PIECES.indexOf(mv.appear[0].p)];
+      mv.statePatch[m_idx] = 0;
+      mv.statePatch[this.getStateIndex(mv.end)] = this.states[m_idx] + 1;
+    });
+    return moves;
+  }
+
   getStateIndex(coords) {
     return this.size.y * coords.x + coords.y;
   }
 
-  prePlay(move) {
-    super.prePlay(move);
-    // 1) Wake up observed pieces
-    // TODO: findDestSquares(attackOnly = true) with changing piece color on board
-    // Loop on found squares + if index in S_PIECES then change
-    // 2) Update sleepy status
-    const indices = [move.start, move.end].map(this.getStateIndex);
-    this.states[indices[1]] = this.states[indices[0]] + 1;
-    this.states[indices[0]] = 0;
-    if (this.states[indices[1]] >= 3)
-      move.appear[0].p = V.S_PIECES[V.M_PIECES.indexOf(move.appear[0].p)];
+  postPlay(move) {
+    // Apply state diff:
+    for (const [k, v] of Object.entries(move.statePatch))
+      this.states[k] = v;
+    super.postPlay(move);
   }
 
 };