Some code cleaning + clarifying (TODO: work on variables names)
[vchess.git] / public / javascripts / variants / Antiking.js
index 2770261..014a9c8 100644 (file)
@@ -1,6 +1,5 @@
 class AntikingRules extends ChessRules
 {
-       // Path to pieces
        static getPpath(b)
        {
                return b[1]=='a' ? "Antiking/"+b : b;
@@ -15,23 +14,23 @@ class AntikingRules extends ChessRules
                const position = fen.split(" ")[0].split("/");
                for (let i=0; i<position.length; i++)
                {
-                       let j = 0;
-                       while (j < position[i].length)
+                       let k = 0;
+                       for (let j=0; j<position[i].length; j++)
                        {
                                switch (position[i].charAt(j))
                                {
                                        case 'a':
-                                               this.antikingPos['b'] = [i,j];
+                                               this.antikingPos['b'] = [i,k];
                                                break;
                                        case 'A':
-                                               this.antikingPos['w'] = [i,j];
+                                               this.antikingPos['w'] = [i,k];
                                                break;
                                        default:
                                                let num = parseInt(position[i].charAt(j));
                                                if (!isNaN(num))
-                                                       j += (num-1);
+                                                       k += (num-1);
                                }
-                               j++;
+                               k++;
                        }
                }
        }
@@ -42,7 +41,7 @@ class AntikingRules extends ChessRules
                const piece2 = this.getPiece(x2,y2);
                const color1 = this.getColor(x1,y1);
                const color2 = this.getColor(x2,y2);
-               return !["a","A"].includes(piece2) &&
+               return piece2 != "a" &&
                        ((piece1 != "a" && color1 != color2) || (piece1 == "a" && color1 == color2));
        }
 
@@ -59,7 +58,9 @@ class AntikingRules extends ChessRules
 
        getPotentialAntikingMoves(sq)
        {
-               return this.getSlideNJumpMoves(sq, VariantRules.steps[VariantRules.QUEEN], "oneStep");
+               const V = VariantRules;
+               return this.getSlideNJumpMoves(sq,
+                       V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
 
        isAttacked(sq, colors)
@@ -67,13 +68,22 @@ class AntikingRules extends ChessRules
                return (super.isAttacked(sq, colors) || this.isAttackedByAntiking(sq, colors));
        }
 
+       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,
+                       V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
+       }
+
        isAttackedByAntiking([x,y], colors)
        {
-               console.log(x + " " + y); //TODO: debug -1, -1 (wrong undo ?!)
-               if (this.getPiece(x,y) == VariantRules.KING)
-                       return false; //king is not attacked by antiking
-               return super.isAttackedBySlideNJump([x,y], colors,
-                       VariantRules.ANTIKING, VariantRules.steps[VariantRules.QUEEN], "oneStep");
+               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,
+                       V.steps[V.ROOK].concat(V.steps[V.BISHOP]), "oneStep");
        }
 
        underCheck(move)
@@ -81,8 +91,8 @@ class AntikingRules extends ChessRules
                const c = this.turn;
                const oppCol = this.getOppCol(c);
                this.play(move)
-               let res = this.isAttacked(this.kingPos[c], oppCol)
-                       || !this.isAttacked(this.antikingPos[c], oppCol);
+               let res = this.isAttacked(this.kingPos[c], [oppCol])
+                       || !this.isAttacked(this.antikingPos[c], [oppCol]);
                this.undo(move);
                return res;
        }
@@ -92,7 +102,7 @@ class AntikingRules extends ChessRules
                let res = super.getCheckSquares(move);
                this.play(move);
                const c = this.turn;
-               if (!this.isAttacked(this.antikingPos[c], this.getOppCol(c)))
+               if (!this.isAttacked(this.antikingPos[c], [this.getOppCol(c)]))
                        res.push(JSON.parse(JSON.stringify(this.antikingPos[c])));
                this.undo(move);
                return res;
@@ -123,38 +133,73 @@ class AntikingRules extends ChessRules
        {
                const color = this.turn;
                const oppCol = this.getOppCol(color);
-               if (!this.isAttacked(this.kingPos[color], oppCol)
-                       && this.isAttacked(this.antikingPos[color], oppCol))
+               if (!this.isAttacked(this.kingPos[color], [oppCol])
+                       && this.isAttacked(this.antikingPos[color], [oppCol]))
                {
                        return "1/2";
                }
                return color == "w" ? "0-1" : "1-0";
        }
 
-       // Pieces values (TODO: use Object.assign() + ChessRules.VALUES ?)
        static get VALUES() {
-               return {
-                       'p': 1,
-                       'r': 5,
-                       'n': 3,
-                       'b': 3,
-                       'q': 9,
-                       'k': 1000,
-                       'a': 1000
-               };
+               return Object.assign(
+                       ChessRules.VALUES,
+                       { 'a': 1000 }
+               );
        }
 
        static GenRandInitFen()
        {
-               let randFen = ChessRules.GenRandInitFen();
-               // Black side
-               let antikingPos = _.random(7);
-               let ranks23 = "pppppppp/" + (antikingPos>0?antikingPos:"") + "A" + (antikingPos<7?7-antikingPos:"");
-               randFen = randFen.replace("pppppppp/8", ranks23);
-               // White side
-               antikingPos = _.random(7);
-               ranks23 = (antikingPos>0?antikingPos:"") + "a" + (antikingPos<7?7-antikingPos:"") + "/PPPPPPPP";
-               randFen = randFen.replace("8/PPPPPPPP", ranks23);
-               return randFen;
+               let pieces = { "w": new Array(8), "b": new Array(8) };
+               let antikingPos = { "w": -1, "b": -1 };
+               for (let c of ["w","b"])
+               {
+                       let positions = _.range(8);
+
+                       // Get random squares for bishops, but avoid corners; because,
+                       // if an antiking blocks a cornered bishop, it can never be checkmated
+                       let randIndex = 2 * _.random(1,3);
+                       const bishop1Pos = positions[randIndex];
+                       let randIndex_tmp = 2 * _.random(2) + 1;
+                       const bishop2Pos = positions[randIndex_tmp];
+                       positions.splice(Math.max(randIndex,randIndex_tmp), 1);
+                       positions.splice(Math.min(randIndex,randIndex_tmp), 1);
+
+                       randIndex = _.random(5);
+                       const knight1Pos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+                       randIndex = _.random(4);
+                       const knight2Pos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+
+                       randIndex = _.random(3);
+                       const queenPos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+
+                       const rook1Pos = positions[0];
+                       const kingPos = positions[1];
+                       const rook2Pos = positions[2];
+
+                       // Random squares for antikings
+                       antikingPos[c] = _.random(7);
+
+                       pieces[c][rook1Pos] = 'r';
+                       pieces[c][knight1Pos] = 'n';
+                       pieces[c][bishop1Pos] = 'b';
+                       pieces[c][queenPos] = 'q';
+                       pieces[c][kingPos] = 'k';
+                       pieces[c][bishop2Pos] = 'b';
+                       pieces[c][knight2Pos] = 'n';
+                       pieces[c][rook2Pos] = 'r';
+               }
+               const ranks23_black = "pppppppp/" + (antikingPos["w"]>0?antikingPos["w"]:"")
+                       + "A" + (antikingPos["w"]<7?7-antikingPos["w"]:"");
+               const ranks23_white = (antikingPos["b"]>0?antikingPos["b"]:"") + "a"
+                       + (antikingPos["b"]<7?7-antikingPos["b"]:"") + "/PPPPPPPP";
+               let fen = pieces["b"].join("") + "/" + ranks23_black +
+                       "/8/8/" +
+                       ranks23_white + "/" + pieces["w"].join("").toUpperCase() +
+                       " 1111";
+               return fen;
        }
 }