Fix Bario + bundle.py, start Emergo
authorBenjamin Auder <benjamin.auder@somewhere>
Wed, 13 May 2026 12:43:30 +0000 (14:43 +0200)
committerBenjamin Auder <benjamin.auder@somewhere>
Wed, 13 May 2026 12:43:30 +0000 (14:43 +0200)
bundle.py
initialize.sh
js/base_rules.js
package-lock.json
package.json
variants/Bario/class.js
variants/Emergo/class.js
variants/Emergo/style.css [new file with mode: 0644]

index 0b3b451..8876a05 100755 (executable)
--- a/bundle.py
+++ b/bundle.py
@@ -17,8 +17,8 @@ IGNORE_FILE_UPDATE = {"app.js"}
 # Files and folders to totally ignore
 IGNORE_FILES = {
     "LICENSE", "README.md", "TODO", "bundle.py", "js/parameters.js.dist",
-    "initialize.sh", "package-lock.json", "package.json", "js/server.js", ".gitignore",
-    "nginx_config.example", "start.sh", "stop.sh", "assets.zip", "extras.zip", ".pid"
+    "initialize.sh", "package-lock.json", "package.json", "js/server.js",
+    "nginx_config.example", "start.sh", "stop.sh", ".pid", ".gitignore"
 }
 IGNORE_DIRS = {".git", "node_modules", DEST_DIR}
 
index bf8d705..9e187d0 100755 (executable)
@@ -1,8 +1,8 @@
-!#/bin/sh
+#!/bin/sh
 
 wget https://xogo.casa/assets.zip && unzip assets.zip
 wget https://xogo.casa/extras.zip && unzip extras.zip
-cp parameters.js.dist parameters.js
+cp js/parameters.js.dist js/parameters.js
 npm i
 cd pieces/Avalam && python generateSVG.py && cd ../..
 #cd pieces/Emergo && python generateSVG.py && cd ../..
index 1039596..894e8aa 100644 (file)
@@ -1088,7 +1088,6 @@ export default class ChessRules {
   // DARK METHODS
 
   updateEnlightened() {
-    console.log("new light");
     this.oldEnlightened = this.enlightened;
     this.enlightened = ArrayFun.init(this.size.x, this.size.y, false);
     // Add pieces positions + all squares reachable by moves (includes Zen):
@@ -1098,9 +1097,6 @@ export default class ChessRules {
         {
           this.enlightened[x][y] = true;
           this.getPotentialMovesFrom([x, y]).forEach(m => {
-
-console.log(m.end);
-
             this.enlightened[m.end.x][m.end.y] = true;
           });
         }
index b657351..dbc6f9d 100644 (file)
@@ -4,7 +4,6 @@
   "requires": true,
   "packages": {
     "": {
-      "name": "xogo",
       "dependencies": {
         "ws": "^7.5.3"
       },
index acf1faa..eadd717 100644 (file)
@@ -1,4 +1,6 @@
 {
+  "name": "xogo",
+  "version": "0.1.0",
   "main": "js/server.js",
   "dependencies": {
     "ws": "^7.5.3"
index e66f356..0470f4a 100644 (file)
@@ -103,7 +103,7 @@ export default class BarioRules extends ChessRules {
         return (
           this.board[i][j] != "" &&
           this.getPiece(i, j) == 'u' &&
-          c == this.getColor(i, j)
+          this.getColor(i, j) == c
         );
     }
     return false; //never reached
@@ -267,39 +267,40 @@ export default class BarioRules extends ChessRules {
     const color = this.turn;
     if (this.movesCount <= 1 || move.reset || move.next) {
       if (!move.next)
-        this.tryChangeTurn();
+        this.tryChangeTurn(move);
       return;
     }
     if (this.subTurn == 0)
       this.captureUndef = null; //already used
-    const captureUndef = (
-      move.vanish.length == 2 && //exclude subTurn == 0
-      move.vanish[1].c != color &&
-      move.vanish[1].p == 'u'
-    );
-    if (typeof move.start.x == "number" && !captureUndef)
-      // Normal move (including Teleport)
-      super.tryPostPlayTeleport(move);
-    else if (typeof move.start.x == "string") {
+    if (typeof move.start.x == "string") {
       super.updateReserve(
         color, move.start.y, this.reserve[color][move.start.y] - 1);
       if (move.vanish.length == 1 && move.vanish[0].p == 'u')
         this.definition = move.end;
-      this.subTurn++;
     }
     else {
-      this.subTurn = 0;
-      this.captureUndef = move.end;
-      this.tryChangeTurn(null, captureUndef);
+      if (
+        move.vanish.length == 2 && //exclude subTurn == 0
+        move.vanish[1].c != color &&
+        move.vanish[1].p == 'u'
+      ) {
+        this.captureUndef = move.end;
+      }
+      else
+        super.tryPostPlayTeleport(move);
     }
+    this.tryChangeTurn(move);
   }
-//TODO
-  // NOTE: not "trying", the turn always change here (TODO?)
-  tryChangeTurn(move, captureUndef) {
-    this.definition = null;
-    this.subTurn = captureUndef ? 0 : 1;
-    this.turn = C.GetOppTurn(this.turn);
-    this.movesCount++;
+
+  tryChangeTurn(move) {
+    if (typeof move.start.x == "string")
+      this.subTurn++; //0 to 1, or 1 to 2
+    else {
+      this.subTurn = !!this.captureUndef ? 0 : 1;
+      this.definition = null;
+      this.turn = C.GetOppTurn(this.turn);
+      this.movesCount++;
+    }
     if (this.options["dark"] && this.movesCount >= 2)
       this.updateEnlightened();
   }
index 06e73b1..2635e63 100644 (file)
@@ -1,8 +1,9 @@
-import { ChessRules, Move, PiPo } from "@/js/base_rules";
-import { randInt } from "@/utils/alea";
+import { ChessRules } from "@/js/base_rules";
+import PiPo from "/utils/PiPo.js";
+import Move from "/utils/Move.js";
 import { ArrayFun } from "@/utils/array";
 
-export class EmergoRules extends ChessRules {
+export default class EmergoRules extends ChessRules {
 
   // Simple encoding: A to L = 1 to 12, from left to right, if white controls.
   // Lowercase if black controls.
@@ -12,152 +13,86 @@ export class EmergoRules extends ChessRules {
     return null;
   }
 
-  static get HasFlags() {
+  get hasFlags() {
     return false;
   }
-
-  static get HasEnpassant() {
+  get hasEnpassant() {
     return false;
   }
 
-  static get DarkBottomRight() {
-    return true;
-  }
-
-  // board element == file name:
-  static board2fen(b) {
+  // board element == piece class ref:
+  board2fen(b) {
     return b;
   }
-  static fen2board(f) {
+  fen2board(f) {
     return f;
   }
 
-  static IsGoodPosition(position) {
-    if (position.length == 0) return false;
-    const rows = position.split("/");
-    if (rows.length != V.size.x) return false;
-    for (let row of rows) {
-      let sumElts = 0;
-      for (let i = 0; i < row.length; i++) {
-        // Add only 0.5 per symbol because 2 per piece
-        if (row[i].toLowerCase().match(/^[a-lA-L@]$/)) sumElts += 0.5;
-        else {
-          const num = parseInt(row[i], 10);
-          if (isNaN(num) || num <= 0) return false;
-          sumElts += num;
-        }
-      }
-      if (sumElts != V.size.y) return false;
-    }
-    return true;
-  }
-
-  static GetBoard(position) {
+  getBoard(position) {
     const rows = position.split("/");
-    let board = ArrayFun.init(V.size.x, V.size.y, "");
+    let board = ArrayFun.init(this.size.x, this.size.y, "");
     for (let i = 0; i < rows.length; i++) {
       let j = 0;
       for (let indexInRow = 0; indexInRow < rows[i].length; indexInRow++) {
         const character = rows[i][indexInRow];
         const num = parseInt(character, 10);
-        // If num is a number, just shift j:
-        if (!isNaN(num)) j += num;
+        if (!isNaN(num))
+          // If num is a number, just shift j:
+          j += num;
         else
           // Something at position i,j
-          board[i][j++] = V.fen2board(character + rows[i][++indexInRow]);
+          board[i][j++] = this.fen2board(character + rows[i][++indexInRow]);
       }
     }
     return board;
   }
 
-  getPpath(b) {
-    return "Emergo/" + b;
-  }
-
   getColor(x, y) {
-    if (x >= V.size.x) return x == V.size.x ? "w" : "b";
-    if (this.board[x][y].charCodeAt(0) < 97) return 'w';
+    if (x >= this.size.x)
+      return x == this.size.x ? "w" : "b";
+    if (this.board[x][y].charCodeAt(0) < 97)
+      return 'w';
     return 'b';
   }
 
-  getPiece() {
-    return V.PAWN; //unused
-  }
-
-  static IsGoodFen(fen) {
-    if (!ChessRules.IsGoodFen(fen)) return false;
-    const fenParsed = V.ParseFen(fen);
-    // 3) Check reserves
-    if (
-      !fenParsed.reserve ||
-      !fenParsed.reserve.match(/^([0-9]{1,2},?){2,2}$/)
-    ) {
-      return false;
-    }
-    return true;
-  }
-
-  static ParseFen(fen) {
-    const fenParts = fen.split(" ");
-    return Object.assign(
-      ChessRules.ParseFen(fen),
-      { reserve: fenParts[3] }
-    );
+  getPiece(x, y) {
+    return this.board[x][y];
   }
 
-  static get size() {
+  get size() {
     return { x: 9, y: 9 };
   }
 
-  static GenRandInitFen() {
-    return "9/9/9/9/9/9/9/9/9 w 0 12,12";
-  }
-
-  getFen() {
-    return super.getFen() + " " + this.getReserveFen();
+  genRandInitBaseFen() {
+    return { fen: "9/9/9/9/9/9/9/9/9 w 0 12,12", o: {} };
   }
 
-  getFenForRepeat() {
-    return super.getFenForRepeat() + "_" + this.getReserveFen();
-  }
+  static get ReserveArray() {
+    // Piece type doesn't matter
+    return ['@']; //TODO ::
 
-  getReserveFen() {
-    return (
-      (!this.reserve["w"] ? 0 : this.reserve["w"][V.PAWN]) + "," +
-      (!this.reserve["b"] ? 0 : this.reserve["b"][V.PAWN])
-    );
-  }
 
-  getReservePpath(index, color) {
-    return "Emergo/" + (color == 'w' ? 'A' : 'a') + '@';
-  }
 
-  static get RESERVE_PIECES() {
-    return [V.PAWN]; //only array length matters
   }
 
-  setOtherVariables(fen) {
-    const reserve =
-      V.ParseFen(fen).reserve.split(",").map(x => parseInt(x, 10));
-    this.reserve = { w: null, b: null };
-    if (reserve[0] > 0) this.reserve['w'] = { [V.PAWN]: reserve[0] };
-    if (reserve[1] > 0) this.reserve['b'] = { [V.PAWN]: reserve[1] };
+  setOtherVariables(fenParsed) {
+    super.setOtherVariables(fenParsed);
     // Local stack of captures during a turn (squares + directions)
     this.captures = [ [] ];
   }
 
   atLeastOneCaptureFrom([x, y], color, forbiddenStep) {
-    for (let s of V.steps[V.BISHOP]) {
+    for (let s of super.pieces()['b'].both[0].steps) {
       if (
         !forbiddenStep ||
         (s[0] != -forbiddenStep[0] || s[1] != -forbiddenStep[1])
       ) {
         const [i, j] = [x + s[0], y + s[1]];
         if (
-          V.OnBoard(i + s[0], j + s[1]) &&
-          this.board[i][j] != V.EMPTY &&
+          this.onBoard(i + s[0], j + s[1]) &&
+          this.board[i][j] != "" &&
           this.getColor(i, j) != color &&
-          this.board[i + s[0]][j + s[1]] == V.EMPTY
+          this.board[i + s[0]][j + s[1]] == ""
         ) {
           return true;
         }
@@ -176,10 +111,10 @@ export class EmergoRules extends ChessRules {
           captures[L-1].square, color, captures[L-1].step)
       );
     }
-    for (let i = 0; i < V.size.x; i++) {
-      for (let j=0; j< V.size.y; j++) {
+    for (let i = 0; i < this.size.x; i++) {
+      for (let j=0; j< this.size.y; j++) {
         if (
-          this.board[i][j] != V.EMPTY &&
+          this.board[i][j] != "" &&
           this.getColor(i, j) == color &&
           this.atLeastOneCaptureFrom([i, j], color)
         ) {
@@ -198,7 +133,8 @@ export class EmergoRules extends ChessRules {
         res = [i];
         maxLength = caps[i].length;
       }
-      else if (caps[i].length == maxLength) res.push(i);
+      else if (caps[i].length == maxLength)
+        res.push(i);
     }
     return res;
   };
@@ -207,26 +143,28 @@ export class EmergoRules extends ChessRules {
     let res = [];
     const L = locSteps.length;
     const lastStep = (L > 0 ? locSteps[L-1] : null);
-    for (let s of V.steps[V.BISHOP]) {
-      if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) continue;
+    for (let s of super.pieces()['b'].both[0].steps) {
+      if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1])
+        continue;
       const [i, j] = [x + s[0], y + s[1]];
       if (
-        V.OnBoard(i + s[0], j + s[1]) &&
-        this.board[i + s[0]][j + s[1]] == V.EMPTY &&
-        this.board[i][j] != V.EMPTY &&
+        this.onBoard(i + s[0], j + s[1]) &&
+        this.board[i + s[0]][j + s[1]] == "" &&
+        this.board[i][j] != "" &&
         this.getColor(i, j) != color
       ) {
         const move = this.getBasicMove([x, y], [i + s[0], j + s[1]], [i, j]);
         locSteps.push(s);
-        V.PlayOnBoard(this.board, move);
+        this.playOnBoard(move);
         const nextRes =
           this.getLongestCaptures_aux([i + s[0], j + s[1]], color, locSteps);
         res.push(1 + nextRes);
         locSteps.pop();
-        V.UndoOnBoard(this.board, move);
+        this.undoOnBoard(move);
       }
     }
-    if (res.length == 0) return 0;
+    if (res.length == 0)
+      return 0;
     return Math.max(...res);
   }
 
@@ -234,23 +172,24 @@ export class EmergoRules extends ChessRules {
     let res = [];
     const L = locSteps.length;
     const lastStep = (L > 0 ? locSteps[L-1] : null);
-    for (let s of V.steps[V.BISHOP]) {
-      if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1]) continue;
+    for (let s of super.pieces()['b'].both[0].steps) {
+      if (!!lastStep && s[0] == -lastStep[0] && s[1] == -lastStep[1])
+        continue;
       const [i, j] = [x + s[0], y + s[1]];
       if (
-        V.OnBoard(i + s[0], j + s[1]) &&
-        this.board[i + s[0]][j + s[1]] == V.EMPTY &&
-        this.board[i][j] != V.EMPTY &&
+        this.onBoard(i + s[0], j + s[1]) &&
+        this.board[i + s[0]][j + s[1]] == "" &&
+        this.board[i][j] != "" &&
         this.getColor(i, j) != color
       ) {
         const move = this.getBasicMove([x, y], [i + s[0], j + s[1]], [i, j]);
         locSteps.push(s);
-        V.PlayOnBoard(this.board, move);
+        this.playOnBoard(move);
         const stepRes =
           this.getLongestCaptures_aux([i + s[0], j + s[1]], color, locSteps);
         res.push({ step: s, length: 1 + stepRes });
         locSteps.pop();
-        V.UndoOnBoard(this.board, move);
+        this.undoOnBoard(move);
       }
     }
     return this.maxLengthIndices(res).map(i => res[i]);;
@@ -271,10 +210,10 @@ export class EmergoRules extends ChessRules {
       );
     }
     else {
-      for (let i = 0; i < V.size.x; i++) {
-        for (let j=0; j < V.size.y; j++) {
+      for (let i = 0; i < this.size.x; i++) {
+        for (let j=0; j < this.size.y; j++) {
           if (
-            this.board[i][j] != V.EMPTY &&
+            this.board[i][j] != "" &&
             this.getColor(i, j) == color
           ) {
             let locSteps = [];
@@ -303,9 +242,11 @@ export class EmergoRules extends ChessRules {
     const firstCodes = (color == 'w' ? [65, 97] : [97, 65]);
     const cpCapt = this.board[capt[0]][capt[1]];
     let count1 = [cp1.charCodeAt(0) - firstCodes[0], -1];
-    if (cp1[1] != '@') count1[1] = cp1.charCodeAt(1) - firstCodes[0];
+    if (cp1[1] != '@')
+      count1[1] = cp1.charCodeAt(1) - firstCodes[0];
     let countC = [cpCapt.charCodeAt(0) - firstCodes[1], -1];
-    if (cpCapt[1] != '@') countC[1] = cpCapt.charCodeAt(1) - firstCodes[1];
+    if (cpCapt[1] != '@')
+      countC[1] = cpCapt.charCodeAt(1) - firstCodes[1];
     count1[1]++;
     countC[0]--;
     let colorChange = false,
@@ -315,7 +256,8 @@ export class EmergoRules extends ChessRules {
         colorChange = true;
         countC = [countC[1], -1];
       }
-      else captVanish = true;
+      else
+        captVanish = true;
     }
     const incPrisoners = String.fromCharCode(firstCodes[0] + count1[1]);
     let mv = new Move({
@@ -346,13 +288,24 @@ export class EmergoRules extends ChessRules {
     return mv;
   }
 
-  getReserveMoves(x) {
-    const color = this.turn;
-    if (!this.reserve[color] || this.atLeastOneCapture(color)) return [];
+
+// TODO: + style
+  getSquareColorClass(x, y) {
+    return ((x+y) % 2 == 0 ? "dark-square": "light-square");
+  }
+
+
+
+
+  getDropMovesFrom([c, p]) {
+    const color = c;
+    if (!this.reserve[color] || this.atLeastOneCapture(color))
+      return [];
     let moves = [];
+    const oppCol = C.GetOppTurn(color);
     const shadowPiece =
-      this.reserve[V.GetOppCol(color)] == null
-        ? this.reserve[color][V.PAWN] - 1
+      !this.reserve[oppCol]
+        ? this.reserve[color]['p'] - 1
         : 0;
     const appearColor = String.fromCharCode(
       (color == 'w' ? 'A' : 'a').charCodeAt(0) + shadowPiece);
@@ -361,35 +314,36 @@ export class EmergoRules extends ChessRules {
         new Move({
           appear: [ new PiPo({ x: i, y: j, c: appearColor, p: '@' }) ],
           vanish: [],
-          start: { x: V.size.x + (color == 'w' ? 0 : 1), y: 0 }
+          start: { x: this.size.x + (color == 'w' ? 0 : 1), y: 0 }
         })
       );
     };
-    const oppCol = V.GetOppCol(color);
     const opponentCanCapture = this.atLeastOneCapture(oppCol);
-    for (let i = 0; i < V.size.x; i++) {
-      for (let j = i % 2; j < V.size.y; j += 2) {
+    for (let i = 0; i < this.size.x; i++) {
+      for (let j = i % 2; j < this.size.y; j += 2) {
         if (
-          this.board[i][j] == V.EMPTY &&
+          this.board[i][j] == "" &&
           // prevent playing on central square at move 1:
           (this.movesCount >= 1 || i != 4 || j != 4)
         ) {
-          if (opponentCanCapture) addMove([i, j]);
+          if (opponentCanCapture)
+            addMove([i, j]);
           else {
             let canAddMove = true;
-            for (let s of V.steps[V.BISHOP]) {
+            for (let s of super.pieces()['b'].both[0].steps) {
               if (
-                V.OnBoard(i + s[0], j + s[1]) &&
-                V.OnBoard(i - s[0], j - s[1]) &&
-                this.board[i + s[0]][j + s[1]] != V.EMPTY &&
-                this.board[i - s[0]][j - s[1]] == V.EMPTY &&
+                this.onBoard(i + s[0], j + s[1]) &&
+                this.onBoard(i - s[0], j - s[1]) &&
+                this.board[i + s[0]][j + s[1]] != "" &&
+                this.board[i - s[0]][j - s[1]] == "" &&
                 this.getColor(i + s[0], j + s[1]) == oppCol
               ) {
                 canAddMove = false;
                 break;
               }
             }
-            if (canAddMove) addMove([i, j]);
+            if (canAddMove)
+              addMove([i, j]);
           }
         }
       }
@@ -397,13 +351,15 @@ export class EmergoRules extends ChessRules {
     return moves;
   }
 
-  getPotentialMovesFrom([x, y], longestCaptures) {
-    if (x >= V.size.x) {
-      if (longestCaptures.length == 0) return this.getReserveMoves(x);
+  getPossibleMovesFrom([x, y], longestCaptures) {
+    if (x >= this.size.x) {
+      if (longestCaptures.length == 0)
+        return this.getReserveMoves(x);
       return [];
     }
     const color = this.turn;
-    if (!!this.reserve[color] && !this.atLeastOneCapture(color)) return [];
+    if (!!this.reserve[color] && !this.atLeastOneCapture(color))
+      return [];
     const L0 = this.captures.length;
     const captures = this.captures[L0 - 1];
     const L = captures.length;
@@ -427,46 +383,21 @@ export class EmergoRules extends ChessRules {
     // Just search simple moves:
     for (let s of V.steps[V.BISHOP]) {
       const [i, j] = [x + s[0], y + s[1]];
-      if (V.OnBoard(i, j) && this.board[i][j] == V.EMPTY)
+      if (this.onBoard(i, j) && this.board[i][j] == "")
         moves.push(this.getBasicMove([x, y], [i, j]));
     }
     return moves;
   }
 
-  getAllValidMoves() {
-    const color = this.turn;
-    const longestCaptures = this.getAllLongestCaptures(color);
-    let potentialMoves = [];
-    for (let i = 0; i < V.size.x; i++) {
-      for (let j = 0; j < V.size.y; j++) {
-        if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
-          Array.prototype.push.apply(
-            potentialMoves,
-            this.getPotentialMovesFrom([i, j], longestCaptures)
-          );
-        }
-      }
-    }
-    // Add reserve moves
-    potentialMoves = potentialMoves.concat(
-      this.getReserveMoves(V.size.x + (color == "w" ? 0 : 1))
-    );
-    return potentialMoves;
-  }
-
-  getPossibleMovesFrom([x, y]) {
+  getPotentialMovesFrom([x, y]) {
     const longestCaptures = this.getAllLongestCaptures(this.getColor(x, y));
-    return this.getPotentialMovesFrom([x, y], longestCaptures);
+    return this.getPossibleMovesFrom([x, y], longestCaptures);
   }
 
   filterValid(moves) {
     return moves;
   }
 
-  getCheckSquares() {
-    return [];
-  }
-
   play(move) {
     const color = this.turn;
     move.turn = color; //for undo
@@ -496,81 +427,45 @@ export class EmergoRules extends ChessRules {
     }
   }
 
-  undo(move) {
-    V.UndoOnBoard(this.board, move);
-    if (!move.notTheEnd) {
-      this.turn = move.turn;
-      this.movesCount--;
-      this.captures.pop();
-    }
-    if (move.vanish.length == 0) {
-      const color = (move.appear[0].c == 'A' ? 'w' : 'b');
-      const firstCode = (color == 'w' ? 65 : 97);
-      const reserveCount = move.appear[0].c.charCodeAt() - firstCode + 1;
-      if (!this.reserve[color]) this.reserve[color] = { [V.PAWN]: 0 };
-      this.reserve[color][V.PAWN] += reserveCount;
-    }
-    else if (move.vanish.length == 2) {
-      const L0 = this.captures.length;
-      let captures = this.captures[L0 - 1];
-      captures.pop();
-    }
-  }
-
   atLeastOneMove() {
     const color = this.turn;
-    if (this.atLeastOneCapture(color)) return true;
-    for (let i = 0; i < V.size.x; i++) {
-      for (let j = 0; j < V.size.y; j++) {
-        if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
-          const moves = this.getPotentialMovesFrom([i, j], []);
-          if (moves.length > 0) return true;
+    if (this.atLeastOneCapture(color))
+      return true;
+    for (let i = 0; i < this.size.x; i++) {
+      for (let j = 0; j < this.size.y; j++) {
+        if (this.board[i][j] != "" && this.getColor(i, j) == color) {
+          const moves = this.getPossibleMovesFrom([i, j], []);
+          if (moves.length > 0)
+            return true;
         }
       }
     }
+
+
+    // TODO: adapt
     const reserveMoves =
-      this.getReserveMoves(V.size.x + (this.turn == "w" ? 0 : 1));
+      this.getReserveMoves(this.size.x + (this.turn == "w" ? 0 : 1));
     return (reserveMoves.length > 0);
   }
 
+
+
   getCurrentScore() {
     const color = this.turn;
+    const testColorCode = (c) => {
+      return (c <= 90 && color == 'w') || (c >= 97 && color == 'b');
+    };
     // If no pieces on board + reserve, I lose
-    if (!!this.reserve[color]) return "*";
-    let atLeastOnePiece = false;
-    outerLoop: for (let i=0; i < V.size.x; i++) {
-      for (let j=0; j < V.size.y; j++) {
-        if (this.board[i][j] != V.EMPTY && this.getColor(i, j) == color) {
-          atLeastOnePiece = true;
-          break outerLoop;
-        }
-      }
-    }
-    if (!atLeastOnePiece) return (color == 'w' ? "0-1" : "1-0");
-    if (!this.atLeastOneMove()) return "1/2";
+    if (!!this.reserve[color])
+      return "*";
+    const atLeastOnePiece = this.board.some(row => row.some(cell => {
+      return cell != "" && testColorCode(cell.charCodeAt(0));
+    });
+    if (!atLeastOnePiece)
+      return (color == 'w' ? "0-1" : "1-0");
+    if (!this.atLeastOneMove())
+      return "1/2";
     return "*";
   }
 
-  getComputerMove() {
-    // Random mover for now (TODO)
-    const color = this.turn;
-    let mvArray = [];
-    let mv = null;
-    while (this.turn == color) {
-      const moves = this.getAllValidMoves();
-      mv = moves[randInt(moves.length)];
-      mvArray.push(mv);
-      this.play(mv);
-    }
-    for (let i = mvArray.length - 1; i >= 0; i--) this.undo(mvArray[i]);
-    return (mvArray.length > 1 ? mvArray : mvArray[0]);
-  }
-
-  getNotation(move) {
-    if (move.vanish.length == 0) return "@" + V.CoordsToSquare(move.end);
-    const L0 = this.captures.length;
-    if (this.captures[L0 - 1].length > 0) return V.CoordsToSquare(move.end);
-    return V.CoordsToSquare(move.start) + V.CoordsToSquare(move.end);
-  }
-
 };
diff --git a/variants/Emergo/style.css b/variants/Emergo/style.css
new file mode 100644 (file)
index 0000000..9650899
--- /dev/null
@@ -0,0 +1,35 @@
+piece.white.stack {
+  background-image: url('/pieces/Emergo/white_.svg');
+}
+
+
+
+
+piece.white.stack2 {
+  background-image: url('/pieces/Avalam/white_stack2.svg');
+}
+piece.white.stack3 {
+  background-image: url('/pieces/Avalam/white_stack3.svg');
+}
+piece.white.stack4 {
+  background-image: url('/pieces/Avalam/white_stack4.svg');
+}
+piece.white.stack5 {
+  background-image: url('/pieces/Avalam/white_stack5.svg');
+}
+
+piece.black.stack {
+  background-image: url('/pieces/Avalam/black_stack.svg');
+}
+piece.black.stack2 {
+  background-image: url('/pieces/Avalam/black_stack2.svg');
+}
+piece.black.stack3 {
+  background-image: url('/pieces/Avalam/black_stack3.svg');
+}
+piece.black.stack4 {
+  background-image: url('/pieces/Avalam/black_stack4.svg');
+}
+piece.black.stack5 {
+  background-image: url('/pieces/Avalam/black_stack5.svg');
+}