[8pieces] Basic lancers move are ok main
authorBenjamin Auder <benjamin.auder@somewhere>
Mon, 20 Apr 2026 10:14:56 +0000 (12:14 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Mon, 20 Apr 2026 10:14:56 +0000 (12:14 +0200)
base_rules.js
variants/Eightpieces/class.js

index daeb337..b73776b 100644 (file)
@@ -1028,8 +1028,10 @@ export default class ChessRules {
     chessboard.style.opacity = "0.5";
     container.appendChild(choices);
     const squareWidth = r.width / this.size.y;
-    const firstUpLeft = (r.width - (moves.length * squareWidth)) / 2;
-    const firstUpTop = (r.height - squareWidth) / 2;
+    const firstUpLeft =
+      (r.width - (Math.min(moves.length, this.size.y) * squareWidth)) / 2;
+    const firstUpTop =
+      (r.height - Math.ceil(moves.length / this.size.y) * squareWidth) / 2;
     const color = moves[0].appear[0].c;
     const callback = (m) => {
       chessboard.style.opacity = "1";
@@ -1041,8 +1043,10 @@ export default class ChessRules {
       choice.classList.add("choice");
       choice.style.width = squareWidth + "px";
       choice.style.height = squareWidth + "px";
-      choice.style.left = (firstUpLeft + i * squareWidth) + "px";
-      choice.style.top = firstUpTop + "px";
+      choice.style.left =
+        (firstUpLeft + (i % this.size.y) * squareWidth) + "px";
+      choice.style.top =
+        firstUpTop + Math.floor(i / this.size.y) * squareWidth + "px";
       choice.style.backgroundColor = "lightyellow";
       choice.onclick = () => callback(moves[i]);
       const piece = document.createElement("piece");
index 1b50694..70f3296 100644 (file)
@@ -14,28 +14,33 @@ export default class EightpiecesRules extends ChessRules {
     };
   }
 
-  pawnPromotions(x, y) {
-    const base_pieces = ['q', 'r', 'n', 'b', 'j', 's'];
-    let lancers = [];
+  getLancerOptions(x, y) {
+    let options = [];
     if (y > 0)
-      lancers.push('m');
+      options.push('m');
     if (y < this.size.y)
-      lancers.push('e');
-    if (x == 0) {
-      lancers.push('g');
+      options.push('e');
+    if (x < this.size.x) {
+      options.push('g');
       if (y > 0)
-        lancers.push('h');
+        options.push('h');
       if (y < this.size.y)
-        lancers.push('f');
+        options.push('f');
     }
-    else { //x == this.size.x-1 (7)
-      lancers.push('c');
+    if (x > 0) {
+      options.push('c');
       if (y > 0)
-        lancers.push('o');
+        options.push('o');
       if (y < this.size.y)
-        lancers.push('d');
+        options.push('d');
     }
-    return base_pieces.concat(lancers);
+    return options;
+  }
+
+  pawnPromotions(x, y) {
+    const base_pieces = ['q', 'r', 'n', 'b', 'j', 's'];
+    let lancer_orients = this.getLancerOptions(x, y);
+    return base_pieces.concat(lancer_orients);
   }
 
   genRandInitBaseFen() {
@@ -54,11 +59,15 @@ export default class EightpiecesRules extends ChessRules {
       "/pppppppp/8/8/8/8/PPPPPPPP/" +
       s.w.join("").replace('l', random > 0 ? 'c' : 'd').toUpperCase();
     return {
-      fen: fen,
+      fen: 'jfs1kb1r/1P3ppp/3p1q2/p7/2P5/8/P2PPPPP/J1SQKBNR', //     fen,
       o: {flags: s.flags}
     };
   }
 
+  static get LANCERS() {
+    return ['c', 'd', 'e', 'f', 'g', 'h', 'm', 'o'];
+  }
+
   setOtherVariables(fenParsed) {
     super.setOtherVariables(fenParsed);
     //this.pushFrom = 
@@ -165,32 +174,42 @@ export default class EightpiecesRules extends ChessRules {
     return [{x: x+1, y: y-1}];
   }
 
-  // Post-process sentry pushes (if any)
+  // Post-process sentry pushes (if any), regular lancer moves, lancer drops..
   postProcessPotentialMoves(moves) {
+    moves = super.postProcessPotentialMoves(moves);
     let finalMoves = [];
     for (const m of moves) {
-      if (m.vanish.length == m.appear.length || m.vanish[0].p != 's')
+      //if (m.vanish.length == 0 && ... TODO: drop
+      if (V.LANCERS.includes(m.vanish[0].p)) {
+        // TODO: how to know it's regular?
+        this.getLancerOptions(m.end.x, m.end.y).forEach(o => {
+          finalMoves.push( new Move({
+            appear: [new PiPo({x:m.end.x,y:m.end.y,c:m.appear[0].c,p:o})],
+            vanish: m.vanish
+          }) );
+        });
+      }
+      else if (m.vanish.length == m.appear.length || m.vanish[0].p != 's')
         finalMoves.push(m);
       else {
         // Sentry "capture" --> turn into pushes
         const [x, y] = [m.end.x, m.end.y]
         const p = this.getPiece(x, y);
         const c = this.getColor(x, y);
-        const squares = this.getSentryPushes(x, y);
-        for (const sq of squares) {
+        this.getSentryPushes(x, y).forEach(sq => {
           finalMoves.push( new Move({
             appear: m.appear.concat(new PiPo({x:sq.x, y:sq.y, p:p, c:c})),
             vanish: m.vanish
           }) );
-        }
+        });
       }
     }
     return finalMoves;
   }
 
-  underAttack() {
+  underAttack([x, y], oppCols) {
     // TODO: check enemy sentry(ies), for each, check all of our own pieces which attack the square (if belonging to opponent!). Then, call :
-    return super.undeerAttack();
+    return super.underAttack([x, y], oppCols);
   }
 
   // Lazy sentry attacks check: after push move
@@ -206,4 +225,10 @@ export default class EightpiecesRules extends ChessRules {
     return super.filterValid(moves, color).concat(sentryAttack);
   }
 
+  updateReserve(color, piece, count) {
+    if (V.LANCERS.includes(piece))
+      piece = 'c'; //TODO: orientation, or new drawing?
+    super.updateReserve(color, piece, count);
+  }
+
 };