Code simplification + a few fixes
authorBenjamin Auder <benjamin.auder@somewhere>
Fri, 14 Dec 2018 18:30:57 +0000 (19:30 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Fri, 14 Dec 2018 18:30:57 +0000 (19:30 +0100)
17 files changed:
public/javascripts/base_rules.js
public/javascripts/components/game.js
public/javascripts/components/rules.js
public/javascripts/variants/Alice.js
public/javascripts/variants/Antiking.js
public/javascripts/variants/Atomic.js
public/javascripts/variants/Checkered.js
public/javascripts/variants/Crazyhouse.js
public/javascripts/variants/Extinction.js
public/javascripts/variants/Grand.js
public/javascripts/variants/Loser.js
public/javascripts/variants/Magnetic.js
public/javascripts/variants/Switching.js
public/javascripts/variants/Ultima.js
public/javascripts/variants/Wildebeest.js
public/javascripts/variants/Zen.js
views/variant.pug

index 63b535d..51c9dda 100644 (file)
@@ -55,7 +55,7 @@ class ChessRules
        {
                this.moves = moves;
                // Use fen string to initialize variables, flags and board
-               this.board = VariantRules.GetBoard(fen);
+               this.board = V.GetBoard(fen);
                this.setFlags(fen);
                this.initVariables(fen);
        }
@@ -102,7 +102,7 @@ class ChessRules
                                k++;
                        }
                }
-               const epSq = this.moves.length > 0 ? this.getEpSquare(this.lastMove) : undefined;
+               const epSq = (this.moves.length > 0 ? this.getEpSquare(this.lastMove) : undefined);
                this.epSquares = [ epSq ];
        }
 
@@ -110,8 +110,7 @@ class ChessRules
        static GetBoard(fen)
        {
                let rows = fen.split(" ")[0].split("/");
-               const [sizeX,sizeY] = VariantRules.size;
-               let board = doubleArray(sizeX, sizeY, "");
+               let board = doubleArray(V.size.x, V.size.y, "");
                for (let i=0; i<rows.length; i++)
                {
                        let j = 0;
@@ -122,7 +121,7 @@ class ChessRules
                                if (!isNaN(num))
                                        j += num; //just shift j
                                else //something at position i,j
-                                       board[i][j++] = VariantRules.fen2board(character);
+                                       board[i][j++] = V.fen2board(character);
                        }
                }
                return board;
@@ -141,20 +140,22 @@ class ChessRules
        ///////////////////
        // GETTERS, SETTERS
 
-       static get size() { return [8,8]; }
+       static get size() { return {x:8, y:8}; }
+
        // Two next functions return 'undefined' if called on empty square
        getColor(i,j) { return this.board[i][j].charAt(0); }
        getPiece(i,j) { return this.board[i][j].charAt(1); }
 
        // Color
-       getOppCol(color) { return color=="w" ? "b" : "w"; }
+       getOppCol(color) { return (color=="w" ? "b" : "w"); }
 
        get lastMove() {
                const L = this.moves.length;
-               return L>0 ? this.moves[L-1] : null;
+               return (L>0 ? this.moves[L-1] : null);
        }
+
        get turn() {
-               return this.moves.length%2==0 ? 'w' : 'b';
+               return (this.moves.length%2==0 ? 'w' : 'b');
        }
 
        // Pieces codes
@@ -192,7 +193,7 @@ class ChessRules
        getEpSquare(move)
        {
                const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x];
-               if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) == 2)
+               if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) == 2)
                {
                        return {
                                x: (sx + ex)/2,
@@ -205,7 +206,7 @@ class ChessRules
        // Can thing on square1 take thing on square2
        canTake([x1,y1], [x2,y2])
        {
-               return this.getColor(x1,y1) != this.getColor(x2,y2);
+               return this.getColor(x1,y1) !== this.getColor(x2,y2);
        }
 
        ///////////////////
@@ -216,17 +217,17 @@ class ChessRules
        {
                switch (this.getPiece(x,y))
                {
-                       case VariantRules.PAWN:
+                       case V.PAWN:
                                return this.getPotentialPawnMoves([x,y]);
-                       case VariantRules.ROOK:
+                       case V.ROOK:
                                return this.getPotentialRookMoves([x,y]);
-                       case VariantRules.KNIGHT:
+                       case V.KNIGHT:
                                return this.getPotentialKnightMoves([x,y]);
-                       case VariantRules.BISHOP:
+                       case V.BISHOP:
                                return this.getPotentialBishopMoves([x,y]);
-                       case VariantRules.QUEEN:
+                       case V.QUEEN:
                                return this.getPotentialQueenMoves([x,y]);
-                       case VariantRules.KING:
+                       case V.KING:
                                return this.getPotentialKingMoves([x,y]);
                }
        }
@@ -254,7 +255,7 @@ class ChessRules
                });
 
                // The opponent piece disappears if we take it
-               if (this.board[ex][ey] != VariantRules.EMPTY)
+               if (this.board[ex][ey] != V.EMPTY)
                {
                        mv.vanish.push(
                                new PiPo({
@@ -268,19 +269,23 @@ class ChessRules
                return mv;
        }
 
+       // Is (x,y) on the chessboard?
+       static OnBoard(x,y)
+       {
+               return (x>=0 && x<V.size.x && y>=0 && y<V.size.y);
+       }
+
        // Generic method to find possible moves of non-pawn pieces ("sliding or jumping")
        getSlideNJumpMoves([x,y], steps, oneStep)
        {
                const color = this.getColor(x,y);
                let moves = [];
-               const [sizeX,sizeY] = VariantRules.size;
                outerLoop:
                for (let step of steps)
                {
                        let i = x + step[0];
                        let j = y + step[1];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
-                               && this.board[i][j] == VariantRules.EMPTY)
+                       while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                        {
                                moves.push(this.getBasicMove([x,y], [i,j]));
                                if (oneStep !== undefined)
@@ -288,7 +293,7 @@ class ChessRules
                                i += step[0];
                                j += step[1];
                        }
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.canTake([x,y], [i,j]))
+                       if (V.OnBoard(i,j) && this.canTake([x,y], [i,j]))
                                moves.push(this.getBasicMove([x,y], [i,j]));
                }
                return moves;
@@ -299,8 +304,7 @@ class ChessRules
        {
                const color = this.turn;
                let moves = [];
-               const V = VariantRules;
-               const [sizeX,sizeY] = V.size;
+               const [sizeX,sizeY] = [V.size.x,V.size.y];
                const shift = (color == "w" ? -1 : 1);
                const firstRank = (color == 'w' ? sizeX-1 : 0);
                const startRank = (color == "w" ? sizeX-2 : 1);
@@ -320,13 +324,13 @@ class ChessRules
                                }
                        }
                        // Captures
-                       if (y>0 && this.canTake([x,y], [x+shift,y-1])
-                               && this.board[x+shift][y-1] != V.EMPTY)
+                       if (y>0 && this.board[x+shift][y-1] != V.EMPTY
+                               && this.canTake([x,y], [x+shift,y-1]))
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y-1]));
                        }
-                       if (y<sizeY-1 && this.canTake([x,y], [x+shift,y+1])
-                               && this.board[x+shift][y+1] != V.EMPTY)
+                       if (y<sizeY-1 && this.board[x+shift][y+1] != V.EMPTY
+                               && this.canTake([x,y], [x+shift,y+1]))
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y+1]));
                        }
@@ -342,13 +346,13 @@ class ChessRules
                                if (this.board[x+shift][y] == V.EMPTY)
                                        moves.push(this.getBasicMove([x,y], [x+shift,y], {c:pawnColor,p:p}));
                                // Captures
-                               if (y>0 && this.canTake([x,y], [x+shift,y-1])
-                                       && this.board[x+shift][y-1] != V.EMPTY)
+                               if (y>0 && this.board[x+shift][y-1] != V.EMPTY
+                                       && this.canTake([x,y], [x+shift,y-1]))
                                {
                                        moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:pawnColor,p:p}));
                                }
-                               if (y<sizeY-1 && this.canTake([x,y], [x+shift,y+1])
-                                       && this.board[x+shift][y+1] != V.EMPTY)
+                               if (y<sizeY-1 && this.board[x+shift][y+1] != V.EMPTY
+                                       && this.canTake([x,y], [x+shift,y+1]))
                                {
                                        moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:pawnColor,p:p}));
                                }
@@ -357,11 +361,11 @@ class ChessRules
 
                // En passant
                const Lep = this.epSquares.length;
-               const epSquare = Lep>0 ? this.epSquares[Lep-1] : undefined;
+               const epSquare = (Lep>0 ? this.epSquares[Lep-1] : undefined);
                if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1)
                {
-                       let epStep = epSquare.y - y;
-                       var enpassantMove = this.getBasicMove([x,y], [x+shift,y+epStep]);
+                       const epStep = epSquare.y - y;
+                       let enpassantMove = this.getBasicMove([x,y], [x+shift,y+epStep]);
                        enpassantMove.vanish.push({
                                x: x,
                                y: y+epStep,
@@ -377,33 +381,30 @@ class ChessRules
        // What are the rook moves from square x,y ?
        getPotentialRookMoves(sq)
        {
-               return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.ROOK]);
+               return this.getSlideNJumpMoves(sq, V.steps[V.ROOK]);
        }
 
        // What are the knight moves from square x,y ?
        getPotentialKnightMoves(sq)
        {
-               return this.getSlideNJumpMoves(
-                       sq, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+               return this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep");
        }
 
        // What are the bishop moves from square x,y ?
        getPotentialBishopMoves(sq)
        {
-               return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.BISHOP]);
+               return this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]);
        }
 
        // What are the queen moves from square x,y ?
        getPotentialQueenMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]));
        }
 
        // What are the king moves from square x,y ?
        getPotentialKingMoves(sq)
        {
-               const V = VariantRules;
                // Initialize with normal moves
                let moves = this.getSlideNJumpMoves(sq,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
@@ -413,17 +414,14 @@ class ChessRules
        getCastleMoves([x,y])
        {
                const c = this.getColor(x,y);
-               const [sizeX,sizeY] = VariantRules.size;
-               if (x != (c=="w" ? sizeX-1 : 0) || y != this.INIT_COL_KING[c])
+               if (x != (c=="w" ? V.size.x-1 : 0) || y != this.INIT_COL_KING[c])
                        return []; //x isn't first rank, or king has moved (shortcut)
 
-               const V = VariantRules;
-
                // Castling ?
                const oppCol = this.getOppCol(c);
                let moves = [];
                let i = 0;
-               const finalSquares = [ [2,3], [sizeY-2,sizeY-3] ]; //king, then rook
+               const finalSquares = [ [2,3], [V.size.y-2,V.size.y-3] ]; //king, then rook
                castlingCheck:
                for (let castleSide=0; castleSide < 2; castleSide++) //large, then small
                {
@@ -510,13 +508,12 @@ class ChessRules
                const color = this.turn;
                const oppCol = this.getOppCol(color);
                let potentialMoves = [];
-               const [sizeX,sizeY] = VariantRules.size;
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
                                // Next condition "!= oppCol" = harmless hack to work with checkered variant
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) != oppCol)
                                        Array.prototype.push.apply(potentialMoves, this.getPotentialMovesFrom([i,j]));
                        }
                }
@@ -530,12 +527,11 @@ class ChessRules
        {
                const color = this.turn;
                const oppCol = this.getOppCol(color);
-               const [sizeX,sizeY] = VariantRules.size;
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) != oppCol)
                                {
                                        const moves = this.getPotentialMovesFrom([i,j]);
                                        if (moves.length > 0)
@@ -566,15 +562,14 @@ class ChessRules
        // Is square x,y attacked by 'colors' pawns ?
        isAttackedByPawn([x,y], colors)
        {
-               const [sizeX,sizeY] = VariantRules.size;
                for (let c of colors)
                {
                        let pawnShift = (c=="w" ? 1 : -1);
-                       if (x+pawnShift>=0 && x+pawnShift<sizeX)
+                       if (x+pawnShift>=0 && x+pawnShift<V.size.x)
                        {
                                for (let i of [-1,1])
                                {
-                                       if (y+i>=0 && y+i<sizeY && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN
+                                       if (y+i>=0 && y+i<V.size.y && this.getPiece(x+pawnShift,y+i)==V.PAWN
                                                && this.getColor(x+pawnShift,y+i)==c)
                                        {
                                                return true;
@@ -588,28 +583,25 @@ class ChessRules
        // Is square x,y attacked by 'colors' rooks ?
        isAttackedByRook(sq, colors)
        {
-               return this.isAttackedBySlideNJump(sq, colors,
-                       VariantRules.ROOK, VariantRules.steps[VariantRules.ROOK]);
+               return this.isAttackedBySlideNJump(sq, colors, V.ROOK, V.steps[V.ROOK]);
        }
 
        // Is square x,y attacked by 'colors' knights ?
        isAttackedByKnight(sq, colors)
        {
                return this.isAttackedBySlideNJump(sq, colors,
-                       VariantRules.KNIGHT, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+                       V.KNIGHT, V.steps[V.KNIGHT], "oneStep");
        }
 
        // Is square x,y attacked by 'colors' bishops ?
        isAttackedByBishop(sq, colors)
        {
-               return this.isAttackedBySlideNJump(sq, colors,
-                       VariantRules.BISHOP, VariantRules.steps[VariantRules.BISHOP]);
+               return this.isAttackedBySlideNJump(sq, colors, V.BISHOP, V.steps[V.BISHOP]);
        }
 
        // Is square x,y attacked by 'colors' queens ?
        isAttackedByQueen(sq, colors)
        {
-               const V = VariantRules;
                return this.isAttackedBySlideNJump(sq, colors, V.QUEEN,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]));
        }
@@ -617,7 +609,6 @@ class ChessRules
        // Is square x,y attacked by 'colors' king(s) ?
        isAttackedByKing(sq, colors)
        {
-               const V = VariantRules;
                return this.isAttackedBySlideNJump(sq, colors, V.KING,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
@@ -626,19 +617,16 @@ class ChessRules
        // is x,y attacked by a piece of color in array 'colors' ?
        isAttackedBySlideNJump([x,y], colors, piece, steps, oneStep)
        {
-               const [sizeX,sizeY] = VariantRules.size;
                for (let step of steps)
                {
                        let rx = x+step[0], ry = y+step[1];
-                       while (rx>=0 && rx<sizeX && ry>=0 && ry<sizeY
-                               && this.board[rx][ry] == VariantRules.EMPTY && !oneStep)
+                       while (V.OnBoard(rx,ry) && this.board[rx][ry] == V.EMPTY && !oneStep)
                        {
                                rx += step[0];
                                ry += step[1];
                        }
-                       if (rx>=0 && rx<sizeX && ry>=0 && ry<sizeY
-                               && this.board[rx][ry] != VariantRules.EMPTY
-                               && this.getPiece(rx,ry) == piece && colors.includes(this.getColor(rx,ry)))
+                       if (V.OnBoard(rx,ry) && this.getPiece(rx,ry) === piece
+                               && colors.includes(this.getColor(rx,ry)))
                        {
                                return true;
                        }
@@ -672,7 +660,7 @@ class ChessRules
        static PlayOnBoard(board, move)
        {
                for (let psq of move.vanish)
-                       board[psq.x][psq.y] = VariantRules.EMPTY;
+                       board[psq.x][psq.y] = V.EMPTY;
                for (let psq of move.appear)
                        board[psq.x][psq.y] = psq.c + psq.p;
        }
@@ -680,7 +668,7 @@ class ChessRules
        static UndoOnBoard(board, move)
        {
                for (let psq of move.appear)
-                       board[psq.x][psq.y] = VariantRules.EMPTY;
+                       board[psq.x][psq.y] = V.EMPTY;
                for (let psq of move.vanish)
                        board[psq.x][psq.y] = psq.c + psq.p;
        }
@@ -689,12 +677,11 @@ class ChessRules
        updateVariables(move)
        {
                const piece = this.getPiece(move.start.x,move.start.y);
-               const c = this.getColor(move.start.x,move.start.y);
-               const [sizeX,sizeY] = VariantRules.size;
-               const firstRank = (c == "w" ? sizeX-1 : 0);
+               const c = this.turn;
+               const firstRank = (c == "w" ? V.size.x-1 : 0);
 
                // Update king position + flags
-               if (piece == VariantRules.KING && move.appear.length > 0)
+               if (piece == V.KING && move.appear.length > 0)
                {
                        this.kingPos[c][0] = move.appear[0].x;
                        this.kingPos[c][1] = move.appear[0].y;
@@ -702,7 +689,7 @@ class ChessRules
                        return;
                }
                const oppCol = this.getOppCol(c);
-               const oppFirstRank = (sizeX-1) - firstRank;
+               const oppFirstRank = (V.size.x-1) - firstRank;
                if (move.start.x == firstRank //our rook moves?
                        && this.INIT_COL_ROOK[c].includes(move.start.y))
                {
@@ -723,7 +710,7 @@ class ChessRules
        {
                // (Potentially) Reset king position
                const c = this.getColor(move.start.x,move.start.y);
-               if (this.getPiece(move.start.x,move.start.y) == VariantRules.KING)
+               if (this.getPiece(move.start.x,move.start.y) == V.KING)
                        this.kingPos[c] = [move.start.x, move.start.y];
        }
 
@@ -746,7 +733,7 @@ class ChessRules
                this.updateVariables(move);
                this.moves.push(move);
                this.epSquares.push( this.getEpSquare(move) );
-               VariantRules.PlayOnBoard(this.board, move);
+               V.PlayOnBoard(this.board, move);
 
                if (!!ingame)
                        move.hash = this.getHashState();
@@ -754,7 +741,7 @@ class ChessRules
 
        undo(move)
        {
-               VariantRules.UndoOnBoard(this.board, move);
+               V.UndoOnBoard(this.board, move);
                this.epSquares.pop();
                this.moves.pop();
                this.unupdateVariables(move);
@@ -834,7 +821,7 @@ class ChessRules
 
        static get THRESHOLD_MATE() {
                // At this value or above, the game is over
-               return VariantRules.INFINITY;
+               return V.INFINITY;
        }
 
        static get SEARCH_DEPTH() {
@@ -845,7 +832,7 @@ class ChessRules
        // NOTE: works also for extinction chess because depth is 3...
        getComputerMove()
        {
-               const maxeval = VariantRules.INFINITY;
+               const maxeval = V.INFINITY;
                const color = this.turn;
                // Some variants may show a bigger moves list to the human (Switching),
                // thus the argument "computer" below (which is generally ignored)
@@ -855,7 +842,14 @@ class ChessRules
                for (let i of _.shuffle(_.range(moves1.length)))
                {
                        this.play(moves1[i]);
-                       const finish = (Math.abs(this.evalPosition()) >= VariantRules.THRESHOLD_MATE);
+                       let finish = (Math.abs(this.evalPosition()) >= V.THRESHOLD_MATE);
+                       if (!finish && !this.atLeastOneMove())
+                       {
+                               // Try mate (for other variants)
+                               const score = this.checkGameEnd();
+                               if (score != "1/2")
+                                       finish = true;
+                       }
                        this.undo(moves1[i]);
                        if (finish)
                                return moves1[i];
@@ -913,8 +907,7 @@ class ChessRules
                const timeStart = Date.now();
 
                // Skip depth 3+ if we found a checkmate (or if we are checkmated in 1...)
-               if (VariantRules.SEARCH_DEPTH >= 3
-                       && Math.abs(moves1[0].eval) < VariantRules.THRESHOLD_MATE)
+               if (V.SEARCH_DEPTH >= 3 && Math.abs(moves1[0].eval) < V.THRESHOLD_MATE)
                {
                        for (let i=0; i<moves1.length; i++)
                        {
@@ -923,7 +916,7 @@ class ChessRules
                                this.play(moves1[i]);
                                // 0.1 * oldEval : heuristic to avoid some bad moves (not all...)
                                moves1[i].eval = 0.1*moves1[i].eval +
-                                       this.alphabeta(VariantRules.SEARCH_DEPTH-1, -maxeval, maxeval);
+                                       this.alphabeta(V.SEARCH_DEPTH-1, -maxeval, maxeval);
                                this.undo(moves1[i]);
                        }
                        moves1.sort( (a,b) => { return (color=="w" ? 1 : -1) * (b.eval - a.eval); });
@@ -940,7 +933,7 @@ class ChessRules
 
        alphabeta(depth, alpha, beta)
   {
-               const maxeval = VariantRules.INFINITY;
+               const maxeval = V.INFINITY;
                const color = this.turn;
                if (!this.atLeastOneMove())
                {
@@ -986,17 +979,16 @@ class ChessRules
 
        evalPosition()
        {
-               const [sizeX,sizeY] = VariantRules.size;
                let evaluation = 0;
                // Just count material for now
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY)
+                               if (this.board[i][j] != V.EMPTY)
                                {
                                        const sign = this.getColor(i,j) == "w" ? 1 : -1;
-                                       evaluation += sign * VariantRules.VALUES[this.getPiece(i,j)];
+                                       evaluation += sign * V.VALUES[this.getPiece(i,j)];
                                }
                        }
                }
@@ -1069,13 +1061,12 @@ class ChessRules
        getBaseFen()
        {
                let fen = "";
-               let [sizeX,sizeY] = VariantRules.size;
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
                        let emptyCount = 0;
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] == VariantRules.EMPTY)
+                               if (this.board[i][j] == V.EMPTY)
                                        emptyCount++;
                                else
                                {
@@ -1085,7 +1076,7 @@ class ChessRules
                                                fen += emptyCount;
                                                emptyCount = 0;
                                        }
-                                       fen += VariantRules.board2fen(this.board[i][j]);
+                                       fen += V.board2fen(this.board[i][j]);
                                }
                        }
                        if (emptyCount > 0)
@@ -1093,7 +1084,7 @@ class ChessRules
                                // "Flush remainder"
                                fen += emptyCount;
                        }
-                       if (i < sizeX - 1)
+                       if (i < V.size.x - 1)
                                fen += "/"; //separate rows
                }
                return fen;
@@ -1115,15 +1106,14 @@ class ChessRules
        // Context: just before move is played, turn hasn't changed
        getNotation(move)
        {
-               if (move.appear.length == 2 && move.appear[0].p == VariantRules.KING) //castle
+               if (move.appear.length == 2 && move.appear[0].p == V.KING) //castle
                        return (move.end.y < move.start.y ? "0-0-0" : "0-0");
 
                // Translate final square
-               const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+               const finalSquare = String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
 
                const piece = this.getPiece(move.start.x, move.start.y);
-               if (piece == VariantRules.PAWN)
+               if (piece == V.PAWN)
                {
                        // Pawn move
                        let notation = "";
@@ -1152,9 +1142,8 @@ class ChessRules
        getLongNotation(move)
        {
                const startSquare =
-                       String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
-               const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x);
+               const finalSquare = String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                return startSquare + finalSquare; //not encoding move. But short+long is enough
        }
 
index deccd5d..63bf675 100644 (file)
@@ -24,7 +24,7 @@ Vue.component('my-game', {
                };
        },
        render(h) {
-               const [sizeX,sizeY] = VariantRules.size;
+               const [sizeX,sizeY] = [V.size.x,V.size.y];
                const smallScreen = (window.innerWidth <= 420);
                // Precompute hints squares to facilitate rendering
                let hintSquares = doubleArray(sizeX, sizeY, false);
index 25f8a3b..c3107a6 100644 (file)
@@ -21,7 +21,7 @@ Vue.component('my-rules', {
        },
        methods: {
                drawDiag: function(fen) {
-                       let [sizeX,sizeY] = VariantRules.size;
+                       let [sizeX,sizeY] = [V.size.x,V.size.y];
                        let fenParts = fen.split(" ");
                        // Obtain array of pieces images names
                        let board = VariantRules.GetBoard(fenParts[0]);
index 220fbd4..5e10a05 100644 (file)
@@ -65,7 +65,6 @@ class AliceRules extends ChessRules
        getSquareOccupation(i, j, mirrorSide)
        {
                const piece = this.getPiece(i,j);
-               const V = VariantRules;
                if (mirrorSide==1 && Object.keys(V.ALICE_CODES).includes(piece))
                        return this.board[i][j];
                else if (mirrorSide==2 && Object.keys(V.ALICE_PIECES).includes(piece))
@@ -77,11 +76,10 @@ class AliceRules extends ChessRules
        getSideBoard(mirrorSide)
        {
                // Build corresponding board from complete board
-               const [sizeX,sizeY] = VariantRules.size;
-               let sideBoard = doubleArray(sizeX, sizeY, "");
-               for (let i=0; i<sizeX; i++)
+               let sideBoard = doubleArray(V.size.x, V.size.y, "");
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                                sideBoard[i][j] = this.getSquareOccupation(i, j, mirrorSide);
                }
                return sideBoard;
@@ -90,8 +88,8 @@ class AliceRules extends ChessRules
        // NOTE: castle & enPassant https://www.chessvariants.com/other.dir/alice.html
        getPotentialMovesFrom([x,y], sideBoard)
        {
-               const pieces = Object.keys(VariantRules.ALICE_CODES);
-               const codes = Object.keys(VariantRules.ALICE_PIECES);
+               const pieces = Object.keys(V.ALICE_CODES);
+               const codes = Object.keys(V.ALICE_PIECES);
                const mirrorSide = (pieces.includes(this.getPiece(x,y)) ? 1 : 2);
 
                // Search valid moves on sideBoard
@@ -107,11 +105,11 @@ class AliceRules extends ChessRules
                                // appear[i] must be an empty square on the other board
                                for (let psq of m.appear)
                                {
-                                       if (this.getSquareOccupation(psq.x,psq.y,3-mirrorSide) != VariantRules.EMPTY)
+                                       if (this.getSquareOccupation(psq.x,psq.y,3-mirrorSide) != V.EMPTY)
                                                return false;
                                }
                        }
-                       else if (this.board[m.end.x][m.end.y] != VariantRules.EMPTY)
+                       else if (this.board[m.end.x][m.end.y] != V.EMPTY)
                        {
                                // Attempt to capture
                                const piece = this.getPiece(m.end.x,m.end.y);
@@ -125,18 +123,18 @@ class AliceRules extends ChessRules
                        if (mirrorSide==1)
                        {
                                m.appear.forEach(psq => { //forEach: castling taken into account
-                                       psq.p = VariantRules.ALICE_CODES[psq.p]; //goto board2
+                                       psq.p = V.ALICE_CODES[psq.p]; //goto board2
                                });
                        }
                        else //move on board2: mark vanishing pieces as Alice
                        {
                                m.vanish.forEach(psq => {
-                                       psq.p = VariantRules.ALICE_CODES[psq.p];
+                                       psq.p = V.ALICE_CODES[psq.p];
                                });
                        }
                        // Fix en-passant captures
-                       if (m.vanish[0].p == VariantRules.PAWN
-                               && m.vanish.length == 2 && this.board[m.end.x][m.end.y] == VariantRules.EMPTY)
+                       if (m.vanish[0].p == V.PAWN && m.vanish.length == 2
+                               && this.board[m.end.x][m.end.y] == V.EMPTY)
                        {
                                m.vanish[1].c = this.getOppCol(this.getColor(x,y));
                                // In the special case of en-passant, if
@@ -144,9 +142,9 @@ class AliceRules extends ChessRules
                                //  - board2 takes board1 : vanish[1] --> normal
                                let van = m.vanish[1];
                                if (mirrorSide==1 && codes.includes(this.getPiece(van.x,van.y)))
-                                       van.p = VariantRules.ALICE_CODES[van.p];
+                                       van.p = V.ALICE_CODES[van.p];
                                else if (mirrorSide==2 && pieces.includes(this.getPiece(van.x,van.y)))
-                                       van.p = VariantRules.ALICE_PIECES[van.p];
+                                       van.p = V.ALICE_PIECES[van.p];
                        }
                        return true;
                });
@@ -166,16 +164,15 @@ class AliceRules extends ChessRules
                const color = this.turn;
                const oppCol = this.getOppCol(color);
                var potentialMoves = [];
-               let [sizeX,sizeY] = VariantRules.size;
                let sideBoard = [this.getSideBoard(1), this.getSideBoard(2)];
-               for (var i=0; i<sizeX; i++)
+               for (var i=0; i<V.size.x; i++)
                {
-                       for (var j=0; j<sizeY; j++)
+                       for (var j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) == color)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) == color)
                                {
                                        const mirrorSide =
-                                               Object.keys(VariantRules.ALICE_CODES).includes(this.getPiece(i,j))
+                                               Object.keys(V.ALICE_CODES).includes(this.getPiece(i,j))
                                                        ? 1
                                                        : 2;
                                        Array.prototype.push.apply(potentialMoves,
@@ -189,16 +186,16 @@ class AliceRules extends ChessRules
        // Play on sideboards [TODO: only one sideBoard required]
        playSide(move, sideBoard)
        {
-               const pieces = Object.keys(VariantRules.ALICE_CODES);
+               const pieces = Object.keys(V.ALICE_CODES);
                move.vanish.forEach(psq => {
                        const mirrorSide = (pieces.includes(psq.p) ? 1 : 2);
-                       sideBoard[mirrorSide-1][psq.x][psq.y] = VariantRules.EMPTY;
+                       sideBoard[mirrorSide-1][psq.x][psq.y] = V.EMPTY;
                });
                move.appear.forEach(psq => {
                        const mirrorSide = (pieces.includes(psq.p) ? 1 : 2);
-                       const piece = (mirrorSide == 1 ? psq.p : VariantRules.ALICE_PIECES[psq.p]);
+                       const piece = (mirrorSide == 1 ? psq.p : V.ALICE_PIECES[psq.p]);
                        sideBoard[mirrorSide-1][psq.x][psq.y] = psq.c + piece;
-                       if (piece == VariantRules.KING)
+                       if (piece == V.KING)
                                this.kingPos[psq.c] = [psq.x,psq.y];
                });
        }
@@ -206,16 +203,16 @@ class AliceRules extends ChessRules
        // Undo on sideboards
        undoSide(move, sideBoard)
        {
-               const pieces = Object.keys(VariantRules.ALICE_CODES);
+               const pieces = Object.keys(V.ALICE_CODES);
                move.appear.forEach(psq => {
                        const mirrorSide = (pieces.includes(psq.p) ? 1 : 2);
-                       sideBoard[mirrorSide-1][psq.x][psq.y] = VariantRules.EMPTY;
+                       sideBoard[mirrorSide-1][psq.x][psq.y] = V.EMPTY;
                });
                move.vanish.forEach(psq => {
                        const mirrorSide = (pieces.includes(psq.p) ? 1 : 2);
-                       const piece = (mirrorSide == 1 ? psq.p : VariantRules.ALICE_PIECES[psq.p]);
+                       const piece = (mirrorSide == 1 ? psq.p : V.ALICE_PIECES[psq.p]);
                        sideBoard[mirrorSide-1][psq.x][psq.y] = psq.c + piece;
-                       if (piece == VariantRules.KING)
+                       if (piece == V.KING)
                                this.kingPos[psq.c] = [psq.x,psq.y];
                });
        }
@@ -225,7 +222,7 @@ class AliceRules extends ChessRules
                const color = this.turn;
                this.playSide(move, sideBoard); //no need to track flags
                const kp = this.kingPos[color];
-               const mirrorSide = sideBoard[0][kp[0]][kp[1]] != VariantRules.EMPTY ? 1 : 2;
+               const mirrorSide = (sideBoard[0][kp[0]][kp[1]] != V.EMPTY ? 1 : 2);
                let saveBoard = this.board;
                this.board = sideBoard[mirrorSide-1];
                let res = this.isAttacked(kp, [this.getOppCol(color)]);
@@ -238,7 +235,7 @@ class AliceRules extends ChessRules
        {
                this.play(move);
                const color = this.turn; //opponent
-               const pieces = Object.keys(VariantRules.ALICE_CODES);
+               const pieces = Object.keys(V.ALICE_CODES);
                const kp = this.kingPos[color];
                const mirrorSide = (pieces.includes(this.getPiece(kp[0],kp[1])) ? 1 : 2);
                let sideBoard = this.getSideBoard(mirrorSide);
@@ -276,7 +273,7 @@ class AliceRules extends ChessRules
 
        checkGameEnd()
        {
-               const pieces = Object.keys(VariantRules.ALICE_CODES);
+               const pieces = Object.keys(V.ALICE_CODES);
                const color = this.turn;
                const kp = this.kingPos[color];
                const mirrorSide = (pieces.includes(this.getPiece(kp[0],kp[1])) ? 1 : 2);
@@ -308,7 +305,7 @@ class AliceRules extends ChessRules
 
        getNotation(move)
        {
-               if (move.appear.length == 2 && move.appear[0].p == VariantRules.KING)
+               if (move.appear.length == 2 && move.appear[0].p == V.KING)
                {
                        if (move.end.y < move.start.y)
                                return "0-0-0";
@@ -316,8 +313,7 @@ class AliceRules extends ChessRules
                                return "0-0";
                }
 
-               const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+               const finalSquare = String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                const piece = this.getPiece(move.start.x, move.start.y);
 
                const captureMark = (move.vanish.length > move.appear.length ? "x" : "");
index 014a9c8..e741168 100644 (file)
@@ -49,7 +49,7 @@ class AntikingRules extends ChessRules
        {
                switch (this.getPiece(x,y))
                {
-                       case VariantRules.ANTIKING:
+                       case V.ANTIKING:
                                return this.getPotentialAntikingMoves([x,y]);
                        default:
                                return super.getPotentialMovesFrom([x,y]);
@@ -58,7 +58,6 @@ class AntikingRules extends ChessRules
 
        getPotentialAntikingMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
@@ -70,7 +69,6 @@ class AntikingRules extends ChessRules
 
        isAttackedByKing([x,y], colors)
        {
-               const V = VariantRules;
                if (this.getPiece(x,y) == V.ANTIKING)
                        return false; //antiking is not attacked by king
                return this.isAttackedBySlideNJump([x,y], colors, V.KING,
@@ -79,7 +77,6 @@ class AntikingRules extends ChessRules
 
        isAttackedByAntiking([x,y], colors)
        {
-               const V = VariantRules;
                if ([V.KING,V.ANTIKING].includes(this.getPiece(x,y)))
                        return false; //(anti)king is not attacked by antiking
                return this.isAttackedBySlideNJump([x,y], colors, V.ANTIKING,
@@ -114,7 +111,7 @@ class AntikingRules extends ChessRules
                const piece = this.getPiece(move.start.x,move.start.y);
                const c = this.getColor(move.start.x,move.start.y);
                // Update antiking position
-               if (piece == VariantRules.ANTIKING)
+               if (piece == V.ANTIKING)
                {
                        this.antikingPos[c][0] = move.appear[0].x;
                        this.antikingPos[c][1] = move.appear[0].y;
@@ -125,7 +122,7 @@ class AntikingRules extends ChessRules
        {
                super.unupdateVariables(move);
                const c = this.getColor(move.start.x,move.start.y);
-               if (this.getPiece(move.start.x,move.start.y) == VariantRules.ANTIKING)
+               if (this.getPiece(move.start.x,move.start.y) == V.ANTIKING)
                        this.antikingPos[c] = [move.start.x, move.start.y];
        }
 
index 28ee1f2..e2f8ea3 100644 (file)
@@ -14,8 +14,8 @@ class AtomicRules extends ChessRules
                                {
                                        let x = m.end.x + step[0];
                                        let y = m.end.y + step[1];
-                                       if (x>=0 && x<8 && y>=0 && y<8 && this.board[x][y] != VariantRules.EMPTY
-                                               && this.getPiece(x,y) != VariantRules.PAWN)
+                                       if (V.OnBoard(x,y) && this.board[x][y] != V.EMPTY
+                                               && this.getPiece(x,y) != V.PAWN)
                                        {
                                                m.vanish.push(
                                                        new PiPo({p:this.getPiece(x,y),c:this.getColor(x,y),x:x,y:y}));
@@ -31,16 +31,14 @@ class AtomicRules extends ChessRules
 
        getPotentialKingMoves([x,y])
        {
-               const V = VariantRules;
                // King cannot capture:
                let moves = [];
-               let [sizeX,sizeY] = V.size;
                const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
                for (let step of steps)
                {
-                       var i = x + step[0];
-                       var j = y + step[1];
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] == VariantRules.EMPTY)
+                       const i = x + step[0];
+                       const j = y + step[1];
+                       if (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                                moves.push(this.getBasicMove([x,y], [i,j]));
                }
                return moves.concat(this.getCastleMoves([x,y]));
@@ -48,11 +46,8 @@ class AtomicRules extends ChessRules
 
        isAttacked(sq, colors)
        {
-               if (this.getPiece(sq[0],sq[1]) == VariantRules.KING
-                       && this.isAttackedByKing(sq, colors))
-               {
+               if (this.getPiece(sq[0],sq[1]) == V.KING && this.isAttackedByKing(sq, colors))
                        return false; //king cannot take...
-               }
                return (this.isAttackedByPawn(sq, colors)
                        || this.isAttackedByRook(sq, colors)
                        || this.isAttackedByKnight(sq, colors)
index 814d91b..2d62d4b 100644 (file)
@@ -72,16 +72,16 @@ class CheckeredRules extends ChessRules
        {
                let standardMoves = super.getPotentialMovesFrom([x,y]);
                const lastRank = this.turn == "w" ? 0 : 7;
-               if (this.getPiece(x,y) == VariantRules.KING)
+               if (this.getPiece(x,y) == V.KING)
                        return standardMoves; //king has to be treated differently (for castles)
                let moves = [];
                standardMoves.forEach(m => {
-                       if (m.vanish[0].p == VariantRules.PAWN)
+                       if (m.vanish[0].p == V.PAWN)
                        {
                                if (Math.abs(m.end.x-m.start.x)==2 && !this.pawnFlags[this.turn][m.start.y])
                                        return; //skip forbidden 2-squares jumps
-                               if (this.board[m.end.x][m.end.y] == VariantRules.EMPTY
-                                       && m.vanish.length==2 && this.getColor(m.start.x,m.start.y) == 'c')
+                               if (this.board[m.end.x][m.end.y] == V.EMPTY && m.vanish.length==2
+                                       && this.getColor(m.start.x,m.start.y) == 'c')
                                {
                                        return; //checkered pawns cannot take en-passant
                                }
@@ -94,7 +94,7 @@ class CheckeredRules extends ChessRules
                                m.appear[0].c = "c";
                                moves.push(m);
                                if (m.appear[0].p != m.vanish[1].p //avoid promotions (already treated):
-                                       && (m.vanish[0].p != VariantRules.PAWN || m.end.x != lastRank))
+                                       && (m.vanish[0].p != V.PAWN || m.end.x != lastRank))
                                {
                                        // Add transformation into captured piece
                                        let m2 = JSON.parse(JSON.stringify(m));
@@ -147,7 +147,7 @@ class CheckeredRules extends ChessRules
                        {
                                for (let i of [-1,1])
                                {
-                                       if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN
+                                       if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==V.PAWN
                                                && this.getColor(x+pawnShift,y+i)==c)
                                        {
                                                return true;
@@ -184,13 +184,10 @@ class CheckeredRules extends ChessRules
 
        updateVariables(move)
        {
-               const c = this.getColor(move.start.x,move.start.y);
-               if (c != 'c') //checkered not concerned by castle flags
-                       super.updateVariables(move);
-
-               // Does it turn off a 2-squares pawn flag?
+               super.updateVariables(move);
+               // Does this move turn off a 2-squares pawn flag?
                const secondRank = [1,6];
-               if (secondRank.includes(move.start.x) && move.vanish[0].p == VariantRules.PAWN)
+               if (secondRank.includes(move.start.x) && move.vanish[0].p == V.PAWN)
                        this.pawnFlags[move.start.x==6 ? "w" : "b"][move.start.y] = false;
        }
 
@@ -207,18 +204,17 @@ class CheckeredRules extends ChessRules
 
        evalPosition()
        {
-               const [sizeX,sizeY] = VariantRules.size;
                let evaluation = 0;
                //Just count material for now, considering checkered neutral (...)
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY)
+                               if (this.board[i][j] != V.EMPTY)
                                {
                                        const sqColor = this.getColor(i,j);
                                        const sign = sqColor == "w" ? 1 : (sqColor=="b" ? -1 : 0);
-                                       evaluation += sign * VariantRules.VALUES[this.getPiece(i,j)];
+                                       evaluation += sign * V.VALUES[this.getPiece(i,j)];
                                }
                        }
                }
@@ -255,10 +251,10 @@ class CheckeredRules extends ChessRules
 
                // Translate final square
                let finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
 
                let piece = this.getPiece(move.start.x, move.start.y);
-               if (piece == VariantRules.PAWN)
+               if (piece == V.PAWN)
                {
                        // Pawn move
                        let notation = "";
index b297f1f..bf47197 100644 (file)
@@ -4,7 +4,6 @@ class CrazyhouseRules extends ChessRules
        {
                super.initVariables(fen);
                // Also init reserves (used by the interface to show landing pieces)
-               const V = VariantRules;
                this.reserve =
                {
                        "w":
@@ -24,53 +23,48 @@ class CrazyhouseRules extends ChessRules
                                [V.QUEEN]: 0,
                        }
                };
-               const [sizeX,sizeY] = VariantRules.size;
-               this.promoted = doubleArray(sizeX, sizeY, false);
+               this.promoted = doubleArray(V.size.x, V.size.y, false);
                // May be a continuation: adjust numbers of pieces in reserve + promoted pieces
                this.moves.forEach(m => { this.updateVariables(m); });
        }
 
        getColor(i,j)
        {
-               const sizeX = VariantRules.size[0];
-               if (i >= sizeX)
-                       return (i==sizeX ? "w" : "b");
+               if (i >= V.size.x)
+                       return (i==V.size.x ? "w" : "b");
                return this.board[i][j].charAt(0);
        }
        getPiece(i,j)
        {
-               const sizeX = VariantRules.size[0];
-               if (i >= sizeX)
-                       return VariantRules.RESERVE_PIECES[j];
+               if (i >= V.size.x)
+                       return V.RESERVE_PIECES[j];
                return this.board[i][j].charAt(1);
        }
 
        // Used by the interface:
        getReservePpath(color, index)
        {
-               return color + VariantRules.RESERVE_PIECES[index];
+               return color + V.RESERVE_PIECES[index];
        }
 
        // Ordering on reserve pieces
        static get RESERVE_PIECES() {
-               const V = VariantRules;
                return [V.PAWN,V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
        }
 
        getReserveMoves([x,y])
        {
                const color = this.turn;
-               const p = VariantRules.RESERVE_PIECES[y];
+               const p = V.RESERVE_PIECES[y];
                if (this.reserve[color][p] == 0)
                        return [];
                let moves = [];
-               const [sizeX,sizeY] = VariantRules.size;
-               const pawnShift = (p==VariantRules.PAWN ? 1 : 0);
-               for (let i=pawnShift; i<sizeX-pawnShift; i++)
+               const pawnShift = (p==V.PAWN ? 1 : 0);
+               for (let i=pawnShift; i<V.size.x-pawnShift; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] == VariantRules.EMPTY)
+                               if (this.board[i][j] == V.EMPTY)
                                {
                                        let mv = new Move({
                                                appear: [
@@ -94,8 +88,7 @@ class CrazyhouseRules extends ChessRules
 
        getPotentialMovesFrom([x,y])
        {
-               const sizeX = VariantRules.size[0];
-               if (x >= sizeX)
+               if (x >= V.size.x)
                {
                        // Reserves, outside of board: x == sizeX(+1)
                        return this.getReserveMoves([x,y]);
@@ -108,9 +101,8 @@ class CrazyhouseRules extends ChessRules
        {
                let moves = super.getAllValidMoves();
                const color = this.turn;
-               const sizeX = VariantRules.size[0];
-               for (let i=0; i<VariantRules.RESERVE_PIECES.length; i++)
-                       moves = moves.concat(this.getReserveMoves([sizeX+(color=="w"?0:1),i]));
+               for (let i=0; i<V.RESERVE_PIECES.length; i++)
+                       moves = moves.concat(this.getReserveMoves([V.size.x+(color=="w"?0:1),i]));
                return this.filterValid(moves);
        }
 
@@ -118,11 +110,12 @@ class CrazyhouseRules extends ChessRules
        {
                if (!super.atLeastOneMove())
                {
-                       const sizeX = VariantRules.size[0];
-                       // Scan for reserve moves
-                       for (let i=0; i<VariantRules.RESERVE_PIECES.length; i++)
+                       const color = this.turn;
+                       // Search one reserve move
+                       for (let i=0; i<V.RESERVE_PIECES.length; i++)
                        {
-                               let moves = this.filterValid(this.getReserveMoves([sizeX,i]));
+                               let moves = this.filterValid(
+                                       this.getReserveMoves([V.size.x+(this.turn=="w"?0:1), i]) );
                                if (moves.length > 0)
                                        return true;
                        }
@@ -137,7 +130,6 @@ class CrazyhouseRules extends ChessRules
                if (move.vanish.length == 2 && move.appear.length == 2)
                        return; //skip castle
                const color = this.turn;
-               const V = VariantRules;
                if (move.vanish.length == 0)
                {
                        this.reserve[color][move.appear[0].p]--;
@@ -149,7 +141,7 @@ class CrazyhouseRules extends ChessRules
                this.promoted[move.end.x][move.end.y] = move.movePromoted
                        || (move.vanish[0].p == V.PAWN && move.appear[0].p != V.PAWN);
                if (move.capturePromoted)
-                       this.reserve[color][VariantRules.PAWN]++;
+                       this.reserve[color][V.PAWN]++;
                else if (move.vanish.length == 2)
                        this.reserve[color][move.vanish[1].p]++;
        }
@@ -160,7 +152,6 @@ class CrazyhouseRules extends ChessRules
                if (move.vanish.length == 2 && move.appear.length == 2)
                        return;
                const color = this.turn;
-               const V = VariantRules;
                if (move.vanish.length == 0)
                {
                        this.reserve[color][move.appear[0].p]++;
@@ -170,7 +161,7 @@ class CrazyhouseRules extends ChessRules
                        this.promoted[move.start.x][move.start.y] = true;
                this.promoted[move.end.x][move.end.y] = move.capturePromoted;
                if (move.capturePromoted)
-                       this.reserve[color][VariantRules.PAWN]--;
+                       this.reserve[color][V.PAWN]--;
                else if (move.vanish.length == 2)
                        this.reserve[color][move.vanish[1].p]--;
        }
@@ -181,11 +172,11 @@ class CrazyhouseRules extends ChessRules
        {
                let evaluation = super.evalPosition();
                // Add reserves:
-               for (let i=0; i<VariantRules.RESERVE_PIECES.length; i++)
+               for (let i=0; i<V.RESERVE_PIECES.length; i++)
                {
-                       const p = VariantRules.RESERVE_PIECES[i];
-                       evaluation += this.reserve["w"][p] * VariantRules.VALUES[p];
-                       evaluation -= this.reserve["b"][p] * VariantRules.VALUES[p];
+                       const p = V.RESERVE_PIECES[i];
+                       evaluation += this.reserve["w"][p] * V.VALUES[p];
+                       evaluation -= this.reserve["b"][p] * V.VALUES[p];
                }
                return evaluation;
        }
@@ -196,9 +187,9 @@ class CrazyhouseRules extends ChessRules
                        return super.getNotation(move);
                // Rebirth:
                const piece =
-                       (move.appear[0].p != VariantRules.PAWN ? move.appear[0].p.toUpperCase() : "");
+                       (move.appear[0].p != V.PAWN ? move.appear[0].p.toUpperCase() : "");
                const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                return piece + "@" + finalSquare;
        }
 
@@ -207,7 +198,7 @@ class CrazyhouseRules extends ChessRules
                if (move.vanish.length > 0)
                        return super.getLongNotation(move);
                const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                return "@" + finalSquare;
        }
 }
index f0ebeab..2b0aeca 100644 (file)
@@ -3,7 +3,6 @@ class ExtinctionRules extends ChessRules
        initVariables(fen)
        {
                super.initVariables(fen);
-               const V = VariantRules;
                this.material =
                {
                        "w":
@@ -32,10 +31,8 @@ class ExtinctionRules extends ChessRules
                let moves = super.getPotentialPawnMoves([x,y]);
                // Add potential promotions into king
                const color = this.turn;
-               const V = VariantRules;
-               const [sizeX,sizeY] = V.size;
                const shift = (color == "w" ? -1 : 1);
-               const lastRank = (color == "w" ? 0 : sizeX-1);
+               const lastRank = (color == "w" ? 0 : V.size.x-1);
 
                if (x+shift == lastRank)
                {
@@ -43,13 +40,13 @@ class ExtinctionRules extends ChessRules
                        if (this.board[x+shift][y] == V.EMPTY)
                                moves.push(this.getBasicMove([x,y], [x+shift,y], {c:color,p:V.KING}));
                        // Captures
-                       if (y>0 && this.canTake([x,y], [x+shift,y-1])
-                               && this.board[x+shift][y-1] != V.EMPTY)
+                       if (y>0 && this.board[x+shift][y-1] != V.EMPTY
+                               && this.canTake([x,y], [x+shift,y-1]))
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:V.KING}));
                        }
-                       if (y<sizeY-1 && this.canTake([x,y], [x+shift,y+1])
-                               && this.board[x+shift][y+1] != V.EMPTY)
+                       if (y<V.size.y-1 && this.board[x+shift][y+1] != V.EMPTY
+                               && this.canTake([x,y], [x+shift,y+1]))
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:color,p:V.KING}));
                        }
@@ -81,7 +78,7 @@ class ExtinctionRules extends ChessRules
                if (move.appear[0].p != move.vanish[0].p)
                {
                        this.material[move.appear[0].c][move.appear[0].p]++;
-                       this.material[move.appear[0].c][VariantRules.PAWN]--;
+                       this.material[move.appear[0].c][V.PAWN]--;
                }
                if (move.vanish.length==2 && move.appear.length==1) //capture
                        this.material[move.vanish[1].c][move.vanish[1].p]--;
@@ -93,7 +90,7 @@ class ExtinctionRules extends ChessRules
                if (move.appear[0].p != move.vanish[0].p)
                {
                        this.material[move.appear[0].c][move.appear[0].p]--;
-                       this.material[move.appear[0].c][VariantRules.PAWN]++;
+                       this.material[move.appear[0].c][V.PAWN]++;
                }
                if (move.vanish.length==2 && move.appear.length==1)
                        this.material[move.vanish[1].c][move.vanish[1].p]++;
@@ -130,7 +127,7 @@ class ExtinctionRules extends ChessRules
                        p => { return this.material[color][p] == 0; }))
                {
                        // Very negative (resp. positive) if white (reps. black) pieces set is incomplete
-                       return (color=="w"?-1:1) * VariantRules.INFINITY;
+                       return (color=="w"?-1:1) * V.INFINITY;
                }
                return super.evalPosition();
        }
index 9e1504d..f5ae065 100644 (file)
@@ -4,7 +4,6 @@ class GrandRules extends ChessRules
 {
        static getPpath(b)
        {
-               const V = VariantRules;
                return ([V.MARSHALL,V.CARDINAL].includes(b[1]) ? "Grand/" : "") + b;
        }
 
@@ -14,7 +13,7 @@ class GrandRules extends ChessRules
                this.captures = { "w": {}, "b": {} }; //for promotions
        }
 
-       static get size() { return [10,10]; }
+       static get size() { return {x:10,y:10}; }
 
        static get MARSHALL() { return 'm'; } //rook+knight
        static get CARDINAL() { return 'c'; } //bishop+knight
@@ -23,7 +22,7 @@ class GrandRules extends ChessRules
        getEpSquare(move)
        {
                const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x];
-               if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) >= 2)
+               if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) >= 2)
                {
                        const step = (ex-sx) / Math.abs(ex-sx);
                        let res = [{
@@ -46,9 +45,9 @@ class GrandRules extends ChessRules
        {
                switch (this.getPiece(x,y))
                {
-                       case VariantRules.MARSHALL:
+                       case V.MARSHALL:
                                return this.getPotentialMarshallMoves([x,y]);
-                       case VariantRules.CARDINAL:
+                       case V.CARDINAL:
                                return this.getPotentialCardinalMoves([x,y]);
                        default:
                                return super.getPotentialMovesFrom([x,y])
@@ -61,8 +60,7 @@ class GrandRules extends ChessRules
        {
                const color = this.turn;
                let moves = [];
-               const V = VariantRules;
-               const [sizeX,sizeY] = VariantRules.size;
+               const [sizeX,sizeY] = [V.size.x,V.size.y];
                const shift = (color == "w" ? -1 : 1);
                const startRanks = (color == "w" ? [sizeX-2,sizeX-3] : [1,2]);
                const lastRanks = (color == "w" ? [0,1,2] : [sizeX-1,sizeX-2,sizeX-3]);
@@ -151,14 +149,12 @@ class GrandRules extends ChessRules
 
        getPotentialMarshallMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq, V.steps[V.ROOK]).concat(
                        this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep"));
        }
 
        getPotentialCardinalMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]).concat(
                        this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep"));
        }
@@ -172,7 +168,6 @@ class GrandRules extends ChessRules
 
        isAttackedByMarshall(sq, colors)
        {
-               const V = VariantRules;
                return this.isAttackedBySlideNJump(sq, colors, V.MARSHALL, V.steps[V.ROOK])
                        || this.isAttackedBySlideNJump(
                                sq, colors, V.MARSHALL, V.steps[V.KNIGHT], "oneStep");
@@ -180,7 +175,6 @@ class GrandRules extends ChessRules
 
        isAttackedByCardinal(sq, colors)
        {
-               const V = VariantRules;
                return this.isAttackedBySlideNJump(sq, colors, V.CARDINAL, V.steps[V.BISHOP])
                        || this.isAttackedBySlideNJump(
                                sq, colors, V.CARDINAL, V.steps[V.KNIGHT], "oneStep");
@@ -189,8 +183,7 @@ class GrandRules extends ChessRules
        updateVariables(move)
        {
                super.updateVariables(move);
-               if (move.vanish.length==2 && move.appear.length==1
-                       && move.vanish[1].p != VariantRules.PAWN)
+               if (move.vanish.length==2 && move.appear.length==1 && move.vanish[1].p != V.PAWN)
                {
                        // Capture: update this.captures
                        if (!this.captures[move.vanish[1].c][move.vanish[1].p])
@@ -203,8 +196,7 @@ class GrandRules extends ChessRules
        unupdateVariables(move)
        {
                super.unupdateVariables(move);
-               if (move.vanish.length==2 && move.appear.length==1
-                       && move.vanish[1].p != VariantRules.PAWN)
+               if (move.vanish.length==2 && move.appear.length==1 && move.vanish[1].p != V.PAWN)
                {
                        this.captures[move.vanish[1].c][move.vanish[1].p] =
                                Math.max(0, this.captures[move.vanish[1].c][move.vanish[1].p]-1);
index 6a322b9..3def40a 100644 (file)
@@ -18,10 +18,8 @@ class LoserRules extends ChessRules
 
                // Complete with promotion(s) into king, if possible
                const color = this.turn;
-               const V = VariantRules;
-               const [sizeX,sizeY] = VariantRules.size;
                const shift = (color == "w" ? -1 : 1);
-               const lastRank = (color == "w" ? 0 : sizeX-1);
+               const lastRank = (color == "w" ? 0 : V.size.x-1);
                if (x+shift == lastRank)
                {
                        // Normal move
@@ -33,7 +31,7 @@ class LoserRules extends ChessRules
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y-1], {c:color,p:V.KING}));
                        }
-                       if (y<sizeY-1 && this.canTake([x,y], [x+shift,y+1])
+                       if (y<V.size.y-1 && this.canTake([x,y], [x+shift,y+1])
                                && this.board[x+shift][y+1] != V.EMPTY)
                        {
                                moves.push(this.getBasicMove([x,y], [x+shift,y+1], {c:color,p:V.KING}));
@@ -45,7 +43,6 @@ class LoserRules extends ChessRules
 
        getPotentialKingMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
@@ -55,12 +52,11 @@ class LoserRules extends ChessRules
        {
                const color = this.turn;
                const oppCol = this.getOppCol(color);
-               const [sizeX,sizeY] = VariantRules.size;
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) != oppCol)
                                {
                                        const moves = this.getPotentialMovesFrom([i,j]);
                                        if (moves.length > 0)
@@ -88,7 +84,7 @@ class LoserRules extends ChessRules
                let moves = this.filterValid( this.getPotentialMovesFrom(sq) );
                // This is called from interface: we need to know if a capture is possible
                if (this.atLeastOneCapture())
-                       moves = VariantRules.KeepCaptures(moves);
+                       moves = V.KeepCaptures(moves);
                return moves;
        }
 
@@ -96,7 +92,7 @@ class LoserRules extends ChessRules
        {
                let moves = super.getAllValidMoves();
                if (moves.some(m => { return m.vanish.length == 2; }))
-                       moves = VariantRules.KeepCaptures(moves);
+                       moves = V.KeepCaptures(moves);
                return moves;
        }
 
index ec2c975..2e90e6c 100644 (file)
@@ -23,7 +23,6 @@ class MagneticRules extends ChessRules
        // TODO: job is done multiple times for (normal) promotions.
        applyMagneticLaws(move)
        {
-               const V = VariantRules;
                if (move.appear[0].p == V.KING && move.appear.length==1)
                        return [move]; //kings are not charged
                const aIdx = (move.appear[0].p != V.KING ? 0 : 1); //if castling, rook is charged
@@ -32,11 +31,10 @@ class MagneticRules extends ChessRules
                const lastRank = (color=="w" ? 0 : 7);
                const standardMove = JSON.parse(JSON.stringify(move));
                this.play(standardMove);
-               const [sizeX,sizeY] = V.size;
                for (let step of [[-1,0],[1,0],[0,-1],[0,1]])
                {
                        let [i,j] = [x+step[0],y+step[1]];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY)
+                       while (V.OnBoard(i,j))
                        {
                                if (this.board[i][j] != V.EMPTY)
                                {
@@ -71,7 +69,7 @@ class MagneticRules extends ChessRules
                                                {
                                                        // Push it until we meet an obstacle or edge of the board
                                                        let [ii,jj] = [i+step[0],j+step[1]];
-                                                       while (ii>=0 && ii<sizeX && jj>=0 && jj<sizeY)
+                                                       while (V.OnBoard(ii,jj))
                                                        {
                                                                if (this.board[ii][jj] != V.EMPTY)
                                                                        break;
@@ -166,9 +164,9 @@ class MagneticRules extends ChessRules
        {
                super.updateVariables(move);
                const c = this.getColor(move.start.x,move.start.y);
-               if (this.board[move.end.x][move.end.y] != VariantRules.EMPTY
+               if (this.board[move.end.x][move.end.y] != V.EMPTY
                        && c != this.getColor(move.end.x,move.end.y)
-                       && this.getPiece(move.end.x,move.end.y) == VariantRules.KING)
+                       && this.getPiece(move.end.x,move.end.y) == V.KING)
                {
                        // We took opponent king !
                        const oppCol = this.getOppCol(c);
index cedba3d..ee84e4c 100644 (file)
@@ -6,7 +6,6 @@ class SwitchingRules extends ChessRules
                const c = this.getColor(x1,y1); //same as color at square 2
                const p1 = this.getPiece(x1,y1);
                const p2 = this.getPiece(x2,y2);
-               const V = VariantRules;
                if (p1 == V.KING && p2 == V.ROOK)
                        return []; //avoid duplicate moves (potential conflict with castle)
                let move = new Move({
@@ -22,8 +21,7 @@ class SwitchingRules extends ChessRules
                        end: {x:x2,y:y2}
                });
                // Move completion: promote switched pawns (as in Magnetic)
-               const sizeX = VariantRules.size[0];
-               const lastRank = (c == "w" ? 0 : sizeX-1);
+               const lastRank = (c == "w" ? 0 : V.size.x-1);
                let moves = [];
                if ((p1==V.PAWN && x2==lastRank) || (p2==V.PAWN && x1==lastRank))
                {
@@ -55,10 +53,8 @@ class SwitchingRules extends ChessRules
        {
                let moves = super.getPotentialMovesFrom([x,y]);
                // Add switches: respecting chessboard ordering if "computer" is on
-               const V = VariantRules;
                const color = this.turn;
                const piece = this.getPiece(x,y);
-               const [sizeX,sizeY] = V.size;
                const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
                const kp = this.kingPos[color];
                const oppCol = this.getOppCol(color);
@@ -67,7 +63,7 @@ class SwitchingRules extends ChessRules
                        let [i,j] = [x+step[0],y+step[1]];
                        if (!!computer && (i<x || (i==x && j<y)))
                                continue; //only switch with superior indices
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j]!=V.EMPTY
+                       if (V.OnBoard(i,j) && this.board[i][j]!=V.EMPTY
                                && this.getColor(i,j)==color && this.getPiece(i,j)!=piece
                                // No switching under check (theoretically non-king pieces could, but not)
                                && !this.isAttacked(kp, [oppCol]))
@@ -87,12 +83,11 @@ class SwitchingRules extends ChessRules
                const color = this.turn;
                const oppCol = this.getOppCol(color);
                let potentialMoves = [];
-               const [sizeX,sizeY] = VariantRules.size;
-               for (let i=0; i<sizeX; i++)
+               for (let i=0; i<V.size.x; i++)
                {
-                       for (let j=0; j<sizeY; j++)
+                       for (let j=0; j<V.size.y; j++)
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) == color)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) == color)
                                {
                                        Array.prototype.push.apply(potentialMoves,
                                                this.getPotentialMovesFrom([i,j], computer));
@@ -106,7 +101,7 @@ class SwitchingRules extends ChessRules
        {
                super.updateVariables(move);
                if (move.appear.length == 2 && move.vanish.length == 2
-                       && move.appear[1].p == VariantRules.KING)
+                       && move.appear[1].p == V.KING)
                {
                        // Switch with the king; not castle, and not handled by main class
                        const color = this.getColor(move.start.x, move.start.y);
@@ -118,7 +113,7 @@ class SwitchingRules extends ChessRules
        {
                super.unupdateVariables(move);
                if (move.appear.length == 2 && move.vanish.length == 2
-                       && move.appear[1].p == VariantRules.KING)
+                       && move.appear[1].p == V.KING)
                {
                        const color = this.getColor(move.start.x, move.start.y);
                        this.kingPos[color] = [move.appear[0].x, move.appear[0].y];
@@ -132,13 +127,13 @@ class SwitchingRules extends ChessRules
                if (move.appear.length == 1)
                        return super.getNotation(move); //no switch
                // Switch or castle
-               if (move.appear[0].p == VariantRules.KING && move.appear[1].p == VariantRules.ROOK)
+               if (move.appear[0].p == V.KING && move.appear[1].p == V.ROOK)
                        return (move.end.y < move.start.y ? "0-0-0" : "0-0");
                // Switch:
                const startSquare =
-                       String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
+                       String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x);
                const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                return "S" + startSquare + finalSquare;
        }
 }
index ab12c71..04ef29b 100644 (file)
@@ -56,14 +56,12 @@ class UltimaRules extends ChessRules
                const piece = this.getPiece(x,y);
                const color = this.getColor(x,y);
                const oppCol = this.getOppCol(color);
-               const V = VariantRules;
                const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
-               const [sizeX,sizeY] = V.size;
                outerLoop:
                for (let step of adjacentSteps)
                {
                        const [i,j] = [x+step[0],y+step[1]];
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] != V.EMPTY
+                       if (V.OnBoard(i,j) && this.board[i][j] != V.EMPTY
                                && this.getColor(i,j) == oppCol)
                        {
                                const oppPiece = this.getPiece(i,j);
@@ -75,8 +73,8 @@ class UltimaRules extends ChessRules
                                                const [i2,j2] = [i+step2[0],j+step2[1]];
                                                if (i2 == x && j2 == y)
                                                        continue; //skip initial piece!
-                                               if (i2>=0 && i2<sizeX && j2>=0 && j2<sizeY
-                                                       && this.board[i2][j2] != V.EMPTY && this.getColor(i2,j2) == color)
+                                               if (V.OnBoard(i2,j2) && this.board[i2][j2] != V.EMPTY
+                                                       && this.getColor(i2,j2) == color)
                                                {
                                                        if ([V.BISHOP,V.IMMOBILIZER].includes(this.getPiece(i2,j2)))
                                                                return false;
@@ -99,7 +97,7 @@ class UltimaRules extends ChessRules
                        return [];
                switch (this.getPiece(x,y))
                {
-                       case VariantRules.IMMOBILIZER:
+                       case V.IMMOBILIZER:
                                return this.getPotentialImmobilizerMoves([x,y]);
                        default:
                                return super.getPotentialMovesFrom([x,y]);
@@ -111,14 +109,12 @@ class UltimaRules extends ChessRules
                const color = this.getColor(x,y);
                const piece = this.getPiece(x,y);
                let moves = [];
-               const [sizeX,sizeY] = VariantRules.size;
                outerLoop:
                for (let step of steps)
                {
                        let i = x + step[0];
                        let j = y + step[1];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
-                               && this.board[i][j] == VariantRules.EMPTY)
+                       while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                        {
                                moves.push(this.getBasicMove([x,y], [i,j]));
                                if (oneStep !== undefined)
@@ -127,11 +123,8 @@ class UltimaRules extends ChessRules
                                j += step[1];
                        }
                        // Only king can take on occupied square:
-                       if (piece==VariantRules.KING && i>=0 && i<sizeX && j>=0
-                               && j<sizeY && this.canTake([x,y], [i,j]))
-                       {
+                       if (piece==V.KING && V.OnBoard(i,j) && this.canTake([x,y], [i,j]))
                                moves.push(this.getBasicMove([x,y], [i,j]));
-                       }
                }
                return moves;
        }
@@ -139,8 +132,7 @@ class UltimaRules extends ChessRules
        // Modify capturing moves among listed pawn moves
        addPawnCaptures(moves, byChameleon)
        {
-               const steps = VariantRules.steps[VariantRules.ROOK];
-               const [sizeX,sizeY] = VariantRules.size;
+               const steps = V.steps[V.ROOK];
                const color = this.turn;
                const oppCol = this.getOppCol(color);
                moves.forEach(m => {
@@ -150,17 +142,16 @@ class UltimaRules extends ChessRules
                        for (let step of steps)
                        {
                                const sq2 = [m.end.x+2*step[0],m.end.y+2*step[1]];
-                               if (sq2[0]>=0 && sq2[0]<sizeX && sq2[1]>=0 && sq2[1]<sizeY
-                                       && this.board[sq2[0]][sq2[1]] != VariantRules.EMPTY
+                               if (V.OnBoard(sq2[0],sq2[1]) && this.board[sq2[0]][sq2[1]] != V.EMPTY
                                        && this.getColor(sq2[0],sq2[1]) == color)
                                {
                                        // Potential capture
                                        const sq1 = [m.end.x+step[0],m.end.y+step[1]];
-                                       if (this.board[sq1[0]][sq1[1]] != VariantRules.EMPTY
+                                       if (this.board[sq1[0]][sq1[1]] != V.EMPTY
                                                && this.getColor(sq1[0],sq1[1]) == oppCol)
                                        {
                                                const piece1 = this.getPiece(sq1[0],sq1[1]);
-                                               if (!byChameleon || piece1 == VariantRules.PAWN)
+                                               if (!byChameleon || piece1 == V.PAWN)
                                                {
                                                        m.vanish.push(new PiPo({
                                                                x:sq1[0],
@@ -196,10 +187,10 @@ class UltimaRules extends ChessRules
                        const corner2 = [kp[0], m.end.y];
                        for (let [i,j] of [corner1,corner2])
                        {
-                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) == oppCol)
+                               if (this.board[i][j] != V.EMPTY && this.getColor(i,j) == oppCol)
                                {
                                        const piece = this.getPiece(i,j);
-                                       if (!byChameleon || piece == VariantRules.ROOK)
+                                       if (!byChameleon || piece == V.ROOK)
                                        {
                                                m.vanish.push( new PiPo({
                                                        x:i,
@@ -225,9 +216,7 @@ class UltimaRules extends ChessRules
        getKnightCaptures(startSquare, byChameleon)
        {
                // Look in every direction for captures
-               const V = VariantRules;
                const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
-               const [sizeX,sizeY] = V.size;
                const color = this.turn;
                const oppCol = this.getOppCol(color);
                let moves = [];
@@ -237,12 +226,12 @@ class UltimaRules extends ChessRules
                for (let step of steps)
                {
                        let [i,j] = [x+step[0], y+step[1]];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j]==V.EMPTY)
+                       while (V.OnBoard(i,j) && this.board[i][j]==V.EMPTY)
                        {
                                i += step[0];
                                j += step[1];
                        }
-                       if (i<0 || i>=sizeX || j<0 || j>=sizeY || this.getColor(i,j)==color
+                       if (!V.OnBoard(i,j) || this.getColor(i,j)==color
                                || (!!byChameleon && this.getPiece(i,j)!=V.KNIGHT))
                        {
                                continue;
@@ -254,7 +243,7 @@ class UltimaRules extends ChessRules
                        let last = [i,j];
                        let cur = [i+step[0],j+step[1]];
                        let vanished = [ new PiPo({x:x,y:y,c:color,p:piece}) ];
-                       while (cur[0]>=0 && cur[0]<sizeX && cur[1]>=0 && cur[1]<sizeY)
+                       while (V.OnBoard(cur[0],cur[1]))
                        {
                                if (this.board[last[0]][last[1]] != V.EMPTY)
                                {
@@ -304,9 +293,8 @@ class UltimaRules extends ChessRules
                this.addQueenCaptures(moves, "asChameleon");
                // Post-processing: merge similar moves, concatenating vanish arrays
                let mergedMoves = {};
-               const [sizeX,sizeY] = VariantRules.size;
                moves.forEach(m => {
-                       const key = m.end.x + sizeX * m.end.y;
+                       const key = m.end.x + V.size.x * m.end.y;
                        if (!mergedMoves[key])
                                mergedMoves[key] = m;
                        else
@@ -327,16 +315,13 @@ class UltimaRules extends ChessRules
                if (moves.length == 0)
                        return;
                const [x,y] = [moves[0].start.x,moves[0].start.y];
-               const V = VariantRules;
                const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
                let capturingDirections = [];
                const color = this.turn;
                const oppCol = this.getOppCol(color);
-               const [sizeX,sizeY] = V.size;
                adjacentSteps.forEach(step => {
                        const [i,j] = [x+step[0],y+step[1]];
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY
-                               && this.board[i][j] != V.EMPTY && this.getColor(i,j) == oppCol
+                       if (V.OnBoard(i,j) && this.board[i][j] != V.EMPTY && this.getColor(i,j) == oppCol
                                && (!byChameleon || this.getPiece(i,j) == V.QUEEN))
                        {
                                capturingDirections.push(step);
@@ -378,7 +363,6 @@ class UltimaRules extends ChessRules
 
        getPotentialKingMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(sq,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
@@ -390,38 +374,31 @@ class UltimaRules extends ChessRules
                // Square (x,y) must be surroundable by two enemy pieces,
                // and one of them at least should be a pawn (moving).
                const dirs = [ [1,0],[0,1] ];
-               const steps = VariantRules.steps[VariantRules.ROOK];
-               const [sizeX,sizeY] = VariantRules.size;
+               const steps = V.steps[V.ROOK];
                for (let dir of dirs)
                {
                        const [i1,j1] = [x-dir[0],y-dir[1]]; //"before"
                        const [i2,j2] = [x+dir[0],y+dir[1]]; //"after"
-                       if (i1>=0 && i1<sizeX && i2>=0 && i2<sizeX
-                               && j1>=0 && j1<sizeY && j2>=0 && j2<sizeY)
+                       if (V.OnBoard(i1,j1) && V.OnBoard(i2,j2))
                        {
-                               if ((this.board[i1][j1]!=VariantRules.EMPTY
-                                       && colors.includes(this.getColor(i1,j1))
-                                       && this.board[i2][j2]==VariantRules.EMPTY)
+                               if ((this.board[i1][j1]!=V.EMPTY && colors.includes(this.getColor(i1,j1))
+                                       && this.board[i2][j2]==V.EMPTY)
                                                ||
-                                       (this.board[i2][j2]!=VariantRules.EMPTY
-                                       && colors.includes(this.getColor(i2,j2))
-                                       && this.board[i1][j1]==VariantRules.EMPTY))
+                                       (this.board[i2][j2]!=V.EMPTY && colors.includes(this.getColor(i2,j2))
+                                       && this.board[i1][j1]==V.EMPTY))
                                {
                                        // Search a movable enemy pawn landing on the empty square
                                        for (let step of steps)
                                        {
-                                               let [ii,jj] = (this.board[i1][j1]==VariantRules.EMPTY ? [i1,j1] : [i2,j2]);
+                                               let [ii,jj] = (this.board[i1][j1]==V.EMPTY ? [i1,j1] : [i2,j2]);
                                                let [i3,j3] = [ii+step[0],jj+step[1]];
-                                               while (i3>=0 && i3<sizeX && j3>=0 && j3<sizeY
-                                                       && this.board[i3][j3]==VariantRules.EMPTY)
+                                               while (V.OnBoard(i3,j3) && this.board[i3][j3]==V.EMPTY)
                                                {
                                                        i3 += step[0];
                                                        j3 += step[1];
                                                }
-                                               if (i3>=0 && i3<sizeX && j3>=0 && j3<sizeY
-                                                       && colors.includes(this.getColor(i3,j3))
-                                                       && this.getPiece(i3,j3) == VariantRules.PAWN
-                                                       && !this.isImmobilized([i3,j3]))
+                                               if (V.OnBoard(i3,j3) && colors.includes(this.getColor(i3,j3))
+                                                       && this.getPiece(i3,j3) == V.PAWN && !this.isImmobilized([i3,j3]))
                                                {
                                                        return true;
                                                }
@@ -436,20 +413,18 @@ class UltimaRules extends ChessRules
        {
                // King must be on same column or row,
                // and a rook should be able to reach a capturing square
-               const [sizeX,sizeY] = VariantRules.size;
                // colors contains only one element, giving the oppCol and thus king position
                const sameRow = (x == this.kingPos[colors[0]][0]);
                const sameColumn = (y == this.kingPos[colors[0]][1]);
                if (sameRow || sameColumn)
                {
                        // Look for the enemy rook (maximum 1)
-                       for (let i=0; i<sizeX; i++)
+                       for (let i=0; i<V.size.x; i++)
                        {
-                               for (let j=0; j<sizeY; j++)
+                               for (let j=0; j<V.size.y; j++)
                                {
-                                       if (this.board[i][j] != VariantRules.EMPTY
-                                               && colors.includes(this.getColor(i,j))
-                                               && this.getPiece(i,j) == VariantRules.ROOK)
+                                       if (this.board[i][j] != V.EMPTY && colors.includes(this.getColor(i,j))
+                                               && this.getPiece(i,j) == V.ROOK)
                                        {
                                                if (this.isImmobilized([i,j]))
                                                        return false; //because only one rook
@@ -472,25 +447,23 @@ class UltimaRules extends ChessRules
        {
                // Square (x,y) must be on same line as a knight,
                // and there must be empty square(s) behind.
-               const V = VariantRules;
                const steps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
-               const [sizeX,sizeY] = V.size;
                outerLoop:
                for (let step of steps)
                {
                        const [i0,j0] = [x+step[0],y+step[1]];
-                       if (i0>=0 && i0<sizeX && j0>=0 && j0<sizeY && this.board[i0][j0] == V.EMPTY)
+                       if (V.OnBoard(i0,j0) && this.board[i0][j0] == V.EMPTY)
                        {
                                // Try in opposite direction:
                                let [i,j] = [x-step[0],y-step[1]];
-                               while (i>=0 && i<sizeX && j>=0 && j<sizeY)
+                               while (V.OnBoard(i,j))
                                {
-                                       while (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] == V.EMPTY)
+                                       while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                                        {
                                                i -= step[0];
                                                j -= step[1];
                                        }
-                                       if (i>=0 && i<sizeX && j>=0 && j<sizeY)
+                                       if (V.OnBoard(i,j))
                                        {
                                                if (colors.includes(this.getColor(i,j)))
                                                {
@@ -514,13 +487,11 @@ class UltimaRules extends ChessRules
        {
                // We cheat a little here: since this function is used exclusively for king,
                // it's enough to check the immediate surrounding of the square.
-               const V = VariantRules;
                const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
-               const [sizeX,sizeY] = V.size;
                for (let step of adjacentSteps)
                {
                        const [i,j] = [x+step[0],y+step[1]];
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j]!=V.EMPTY
+                       if (V.OnBoard(i,j) && this.board[i][j]!=V.EMPTY
                                && colors.includes(this.getColor(i,j)) && this.getPiece(i,j) == V.BISHOP)
                        {
                                return true; //bishops are never immobilized
@@ -533,14 +504,11 @@ class UltimaRules extends ChessRules
        {
                // Square (x,y) must be adjacent to a queen, and the queen must have
                // some free space in the opposite direction from (x,y)
-               const V = VariantRules;
                const adjacentSteps = V.steps[V.ROOK].concat(V.steps[V.BISHOP]);
-               const [sizeX,sizeY] = V.size;
                for (let step of adjacentSteps)
                {
                        const sq2 = [x+2*step[0],y+2*step[1]];
-                       if (sq2[0]>=0 && sq2[0]<sizeX && sq2[1]>=0 && sq2[1]<sizeY
-                               && this.board[sq2[0]][sq2[1]] == V.EMPTY)
+                       if (V.OnBoard(sq2[0],sq2[1]) && this.board[sq2[0]][sq2[1]] == V.EMPTY)
                        {
                                const sq1 = [x+step[0],y+step[1]];
                                if (this.board[sq1[0]][sq1[1]] != V.EMPTY
@@ -560,7 +528,7 @@ class UltimaRules extends ChessRules
                // Just update king(s) position(s)
                const piece = this.getPiece(move.start.x,move.start.y);
                const c = this.getColor(move.start.x,move.start.y);
-               if (piece == VariantRules.KING && move.appear.length > 0)
+               if (piece == V.KING && move.appear.length > 0)
                {
                        this.kingPos[c][0] = move.appear[0].x;
                        this.kingPos[c][1] = move.appear[0].y;
@@ -642,20 +610,19 @@ class UltimaRules extends ChessRules
        getNotation(move)
        {
                const initialSquare =
-                       String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
-               const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x);
+               const finalSquare = String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
                let notation = undefined;
-               if (move.appear[0].p == VariantRules.PAWN)
+               if (move.appear[0].p == V.PAWN)
                {
                        // Pawn: generally ambiguous short notation, so we use full description
                        notation = "P" + initialSquare + finalSquare;
                }
-               else if (move.appear[0].p == VariantRules.KING)
+               else if (move.appear[0].p == V.KING)
                        notation = "K" + (move.vanish.length>1 ? "x" : "") + finalSquare;
                else
                        notation = move.appear[0].p.toUpperCase() + finalSquare;
-               if (move.vanish.length > 1 && move.appear[0].p != VariantRules.KING)
+               if (move.vanish.length > 1 && move.appear[0].p != V.KING)
                        notation += "X"; //capture mark (not describing what is captured...)
                return notation;
        }
index 5bfa87b..bb478cc 100644 (file)
@@ -2,11 +2,10 @@ class WildebeestRules extends ChessRules
 {
        static getPpath(b)
        {
-               const V = VariantRules;
                return ([V.CAMEL,V.WILDEBEEST].includes(b[1]) ? "Wildebeest/" : "") + b;
        }
 
-       static get size() { return [10,11]; }
+       static get size() { return {x:10,y:11}; }
 
        static get CAMEL() { return 'c'; }
        static get WILDEBEEST() { return 'w'; }
@@ -22,7 +21,7 @@ class WildebeestRules extends ChessRules
        getEpSquare(move)
        {
                const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x];
-               if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) >= 2)
+               if (this.getPiece(sx,sy) == V.PAWN && Math.abs(sx - ex) >= 2)
                {
                        const step = (ex-sx) / Math.abs(ex-sx);
                        let res = [{
@@ -45,9 +44,9 @@ class WildebeestRules extends ChessRules
        {
                switch (this.getPiece(x,y))
                {
-                       case VariantRules.CAMEL:
+                       case V.CAMEL:
                                return this.getPotentialCamelMoves([x,y]);
-                       case VariantRules.WILDEBEEST:
+                       case V.WILDEBEEST:
                                return this.getPotentialWildebeestMoves([x,y]);
                        default:
                                return super.getPotentialMovesFrom([x,y])
@@ -59,8 +58,7 @@ class WildebeestRules extends ChessRules
        {
                const color = this.turn;
                let moves = [];
-               const V = VariantRules;
-               const [sizeX,sizeY] = VariantRules.size;
+               const [sizeX,sizeY] = [V.size.x,V.size.y];
                const shift = (color == "w" ? -1 : 1);
                const startRanks = (color == "w" ? [sizeX-2,sizeX-3] : [1,2]);
                const lastRank = (color == "w" ? 0 : sizeX-1);
@@ -147,13 +145,11 @@ class WildebeestRules extends ChessRules
 
        getPotentialCamelMoves(sq)
        {
-               return this.getSlideNJumpMoves(
-                       sq, VariantRules.steps[VariantRules.CAMEL], "oneStep");
+               return this.getSlideNJumpMoves(sq, V.steps[V.CAMEL], "oneStep");
        }
 
        getPotentialWildebeestMoves(sq)
        {
-               const V = VariantRules;
                return this.getSlideNJumpMoves(
                        sq, V.steps[V.KNIGHT].concat(V.steps[V.CAMEL]), "oneStep");
        }
@@ -168,12 +164,11 @@ class WildebeestRules extends ChessRules
        isAttackedByCamel(sq, colors)
        {
                return this.isAttackedBySlideNJump(sq, colors,
-                       VariantRules.CAMEL, VariantRules.steps[VariantRules.CAMEL], "oneStep");
+                       V.CAMEL, V.steps[V.CAMEL], "oneStep");
        }
 
        isAttackedByWildebeest(sq, colors)
        {
-               const V = VariantRules;
                return this.isAttackedBySlideNJump(sq, colors, V.WILDEBEEST,
                        V.steps[V.KNIGHT].concat(V.steps[V.CAMEL]), "oneStep");
        }
index f57ab3c..64587d2 100644 (file)
@@ -11,15 +11,13 @@ class ZenRules extends ChessRules
        {
                const color = this.getColor(x,y);
                let moves = [];
-               const [sizeX,sizeY] = VariantRules.size;
                outerLoop:
                for (let loop=0; loop<steps.length; loop++)
                {
                        const step = steps[loop];
                        let i = x + step[0];
                        let j = y + step[1];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
-                               && this.board[i][j] == VariantRules.EMPTY)
+                       while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                        {
                                moves.push(this.getBasicMove([x,y], [i,j]));
                                if (!!oneStep)
@@ -38,13 +36,11 @@ class ZenRules extends ChessRules
        {
                const color = this.getColor(x,y);
                var moves = [];
-               const V = VariantRules;
                const steps = asA != V.PAWN
                        ? (asA==V.QUEEN ? V.steps[V.ROOK].concat(V.steps[V.BISHOP]) : V.steps[asA])
                        : color=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
                const oneStep = (asA==V.KNIGHT || asA==V.PAWN); //we don't capture king
-               const [sizeX,sizeY] = V.size;
-               const lastRank = (color == 'w' ? 0 : sizeY-1);
+               const lastRank = (color == 'w' ? 0 : V.size.x-1);
                const promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
                outerLoop:
                for (let loop=0; loop<steps.length; loop++)
@@ -52,15 +48,15 @@ class ZenRules extends ChessRules
                        const step = steps[loop];
                        let i = x + step[0];
                        let j = y + step[1];
-                       while (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] == V.EMPTY)
+                       while (V.OnBoard(i,j) && this.board[i][j] == V.EMPTY)
                        {
                                if (oneStep)
                                        continue outerLoop;
                                i += step[0];
                                j += step[1];
                        }
-                       if (i>=0 && i<sizeX && j>=0 && j<sizeY &&
-                               this.getColor(i,j) == this.getOppCol(color) && this.getPiece(i,j) == asA)
+                       if (V.OnBoard(i,j) && this.getColor(i,j) == this.getOppCol(color)
+                               && this.getPiece(i,j) == asA)
                        {
                                // eat!
                                if (this.getPiece(x,y) == V.PAWN && i == lastRank)
@@ -85,11 +81,11 @@ class ZenRules extends ChessRules
        {
                let moves = [];
 
-               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, VariantRules.PAWN));
-               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, VariantRules.ROOK));
-               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, VariantRules.KNIGHT));
-               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, VariantRules.BISHOP));
-               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, VariantRules.QUEEN));
+               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.PAWN));
+               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.ROOK));
+               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.KNIGHT));
+               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.BISHOP));
+               Array.prototype.push.apply(moves, this.findCaptures_aux(sq, V.QUEEN));
 
                return moves;
        }
@@ -97,13 +93,12 @@ class ZenRules extends ChessRules
        getPotentialPawnMoves([x,y])
        {
                const color = this.getColor(x,y);
-               var moves = [];
-               var V = VariantRules;
-               let [sizeX,sizeY] = VariantRules.size;
-               let shift = (color == 'w' ? -1 : 1);
-               let startRank = (color == 'w' ? sizeY-2 : 1);
-               let firstRank = (color == 'w' ? sizeY-1 : 0);
-               let lastRank = (color == "w" ? 0 : sizeY-1);
+               let moves = [];
+               const [sizeX,sizeY] = [V.size.x,V.size.y];
+               const shift = (color == 'w' ? -1 : 1);
+               const startRank = (color == 'w' ? sizeY-2 : 1);
+               const firstRank = (color == 'w' ? sizeY-1 : 0);
+               const lastRank = (color == "w" ? 0 : sizeY-1);
 
                if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
                {
@@ -140,31 +135,27 @@ class ZenRules extends ChessRules
 
        getPotentialRookMoves(sq)
        {
-               let noCaptures = this.getSlideNJumpMoves(
-                       sq, VariantRules.steps[VariantRules.ROOK]);
+               let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.ROOK]);
                let captures = this.findCaptures(sq);
                return noCaptures.concat(captures);
        }
 
        getPotentialKnightMoves(sq)
        {
-               let noCaptures = this.getSlideNJumpMoves(
-                       sq, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+               let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.KNIGHT], "oneStep");
                let captures = this.findCaptures(sq);
                return noCaptures.concat(captures);
        }
 
        getPotentialBishopMoves(sq)
        {
-               let noCaptures = this.getSlideNJumpMoves(
-                       sq, VariantRules.steps[VariantRules.BISHOP]);
+               let noCaptures = this.getSlideNJumpMoves(sq, V.steps[V.BISHOP]);
                let captures = this.findCaptures(sq);
                return noCaptures.concat(captures);
        }
 
        getPotentialQueenMoves(sq)
        {
-               const V = VariantRules;
                let noCaptures = this.getSlideNJumpMoves(
                        sq, V.steps[V.ROOK].concat(V.steps[V.BISHOP]));
                let captures = this.findCaptures(sq);
@@ -173,7 +164,6 @@ class ZenRules extends ChessRules
 
        getPotentialKingMoves(sq)
        {
-               const V = VariantRules;
                // Initialize with normal moves
                let noCaptures = this.getSlideNJumpMoves(sq,
                        V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
@@ -195,15 +185,15 @@ class ZenRules extends ChessRules
 
                // Translate initial square (because pieces may fly unusually in this variant!)
                const initialSquare =
-                       String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
+                       String.fromCharCode(97 + move.start.y) + (V.size.x-move.start.x);
 
                // Translate final square
                const finalSquare =
-                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+                       String.fromCharCode(97 + move.end.y) + (V.size.x-move.end.x);
 
                let notation = "";
                const piece = this.getPiece(move.start.x, move.start.y);
-               if (piece == VariantRules.PAWN)
+               if (piece == V.PAWN)
                {
                        // pawn move (TODO: enPassant indication)
                        if (move.vanish.length > 1)
index 7de86ca..a44a374 100644 (file)
@@ -23,6 +23,7 @@ block javascripts
        script(src="/javascripts/variants/" + variant + ".js")
        script.
                const VariantRules = #{variant}Rules;
+               const V = VariantRules; //because this variable is often used
                const variant = "#{variant}";
        script(src="/javascripts/components/rules.js")
        script(src="/javascripts/components/game.js")