Some code cleaning + clarifying (TODO: work on variables names)
[vchess.git] / public / javascripts / base_rules.js
index 71695c4..5c1ef97 100644 (file)
@@ -1,3 +1,6 @@
+// (Orthodox) Chess rules are defined in ChessRules class.
+// Variants generally inherit from it, and modify some parts.
+
 class PiPo //Piece+Position
 {
        // o: {piece[p], color[c], posX[x], posY[y]}
@@ -10,6 +13,7 @@ class PiPo //Piece+Position
        }
 }
 
+// TODO: for animation, moves should contains "moving" and "fading" maybe...
 class Move
 {
        // o: {appear, vanish, [start,] [end,]}
@@ -60,7 +64,7 @@ class ChessRules
        {
                this.INIT_COL_KING = {'w':-1, 'b':-1};
                this.INIT_COL_ROOK = {'w':[-1,-1], 'b':[-1,-1]};
-               this.kingPos = {'w':[-1,-1], 'b':[-1,-1]}; //respective squares of white and black king
+               this.kingPos = {'w':[-1,-1], 'b':[-1,-1]}; //squares of white and black king
                const fenParts = fen.split(" ");
                const position = fenParts[0].split("/");
                for (let i=0; i<position.length; i++)
@@ -379,7 +383,8 @@ class ChessRules
        // What are the knight moves from square x,y ?
        getPotentialKnightMoves(sq)
        {
-               return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+               return this.getSlideNJumpMoves(
+                       sq, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
        }
 
        // What are the bishop moves from square x,y ?
@@ -480,7 +485,8 @@ class ChessRules
 
        canIplay(side, [x,y])
        {
-               return ((side=='w' && this.moves.length%2==0) || (side=='b' && this.moves.length%2==1))
+               return ((side=='w' && this.moves.length%2==0)
+                               || (side=='b' && this.moves.length%2==1))
                        && this.getColor(x,y) == side;
        }
 
@@ -490,7 +496,7 @@ class ChessRules
                return this.filterValid( this.getPotentialMovesFrom(sq) );
        }
 
-       // TODO: once a promotion is filtered, the others results are same: useless computations
+       // TODO: promotions (into R,B,N,Q) should be filtered only once
        filterValid(moves)
        {
                if (moves.length == 0)
@@ -509,7 +515,7 @@ class ChessRules
                {
                        for (let j=0; j<sizeY; j++)
                        {
-                               // Next condition ... != oppCol is a little HACK to work with checkered variant
+                               // Next condition "!= oppCol" = harmless hack to work with checkered variant
                                if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
                                        Array.prototype.push.apply(potentialMoves, this.getPotentialMovesFrom([i,j]));
                        }
@@ -821,7 +827,9 @@ class ChessRules
                this.shouldReturn = false;
                const maxeval = VariantRules.INFINITY;
                const color = this.turn;
-               let moves1 = this.getAllValidMoves();
+               // Some variants may show a bigger moves list to the human (Switching),
+               // thus the argument "computer" below (which is generally ignored)
+               let moves1 = this.getAllValidMoves("computer");
 
                // Can I mate in 1 ? (for Magnetic & Extinction)
                for (let i of _.shuffle(_.range(moves1.length)))
@@ -843,7 +851,7 @@ class ChessRules
                        {
                                eval2 = (color=="w" ? 1 : -1) * maxeval; //initialized with checkmate value
                                // Second half-move:
-                               let moves2 = this.getAllValidMoves();
+                               let moves2 = this.getAllValidMoves("computer");
                                for (let j=0; j<moves2.length; j++)
                                {
                                        this.play(moves2[j]);
@@ -866,8 +874,11 @@ class ChessRules
                                const score = this.checkGameEnd();
                                eval2 = (score=="1/2" ? 0 : (score=="1-0" ? 1 : -1) * maxeval);
                        }
-                       if ((color=="w" && eval2 > moves1[i].eval) || (color=="b" && eval2 < moves1[i].eval))
+                       if ((color=="w" && eval2 > moves1[i].eval)
+                               || (color=="b" && eval2 < moves1[i].eval))
+                       {
                                moves1[i].eval = eval2;
+                       }
                        this.undo(moves1[i]);
                }
                moves1.sort( (a,b) => { return (color=="w" ? 1 : -1) * (b.eval - a.eval); });
@@ -921,7 +932,7 @@ class ChessRules
                }
                if (depth == 0)
       return this.evalPosition();
-               const moves = this.getAllValidMoves();
+               const moves = this.getAllValidMoves("computer");
     let v = color=="w" ? -maxeval : maxeval;
                if (color == "w")
                {
@@ -1074,7 +1085,7 @@ class ChessRules
                for (let i of ['w','b'])
                {
                        for (let j=0; j<2; j++)
-                               fen += this.castleFlags[i][j] ? '1' : '0';
+                               fen += (this.castleFlags[i][j] ? '1' : '0');
                }
                return fen;
        }
@@ -1082,14 +1093,8 @@ 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.end.y < move.start.y)
-                               return "0-0-0";
-                       else
-                               return "0-0";
-               }
+               if (move.appear.length == 2 && move.appear[0].p == VariantRules.KING) //castle
+                       return (move.end.y < move.start.y ? "0-0-0" : "0-0");
 
                // Translate final square
                const finalSquare =
@@ -1134,12 +1139,14 @@ class ChessRules
        // The score is already computed when calling this function
        getPGN(mycolor, score, fenStart, mode)
        {
+               const zeroPad = x => { return (x<10 ? "0" : "") + x; };
                let pgn = "";
                pgn += '[Site "vchess.club"]<br>';
                const d = new Date();
                const opponent = mode=="human" ? "Anonymous" : "Computer";
                pgn += '[Variant "' + variant + '"]<br>';
-               pgn += '[Date "' + d.getFullYear() + '-' + (d.getMonth()+1) + '-' + d.getDate() + '"]<br>';
+               pgn += '[Date "' + d.getFullYear() + '-' + (d.getMonth()+1) +
+                       '-' + zeroPad(d.getDate()) + '"]<br>';
                pgn += '[White "' + (mycolor=='w'?'Myself':opponent) + '"]<br>';
                pgn += '[Black "' + (mycolor=='b'?'Myself':opponent) + '"]<br>';
                pgn += '[FenStart "' + fenStart + '"]<br>';