Improve Alice notation, PGN. Add debugging instruction for Alice
[vchess.git] / public / javascripts / variants / Alice.js
index 3cba8d0..a15c30c 100644 (file)
@@ -28,6 +28,38 @@ class AliceRules extends ChessRules
                return (Object.keys(this.ALICE_PIECES).includes(b[1]) ? "Alice/" : "") + b;
        }
 
+       initVariables(fen)
+       {
+               super.initVariables(fen);
+               const fenParts = fen.split(" ");
+               const position = fenParts[0].split("/");
+               if (this.kingPos["w"][0] < 0 || this.kingPos["b"][0] < 0)
+               {
+                       // INIT_COL_XXX won't be used, so no need to set them for Alice kings
+                       for (let i=0; i<position.length; i++)
+                       {
+                               let k = 0; //column index on board
+                               for (let j=0; j<position[i].length; j++)
+                               {
+                                       switch (position[i].charAt(j))
+                                       {
+                                               case 'l':
+                                                       this.kingPos['b'] = [i,k];
+                                                       break;
+                                               case 'L':
+                                                       this.kingPos['w'] = [i,k];
+                                                       break;
+                                               default:
+                                                       let num = parseInt(position[i].charAt(j));
+                                                       if (!isNaN(num))
+                                                               k += (num-1);
+                                       }
+                                       k++;
+                               }
+                       }
+               }
+       }
+
        getBoardOfPiece([x,y])
        {
                const V = VariantRules;
@@ -50,10 +82,9 @@ class AliceRules extends ChessRules
                return sideBoard;
        }
 
-       // TODO: castle & enPassant https://www.chessvariants.com/other.dir/alice.html
-       // TODO: enPassant seulement si l'on est du même coté que le coté de départ du pion adverse
-       // (en passant en sortant du monde... : il faut donc ajouter des coups non trouvés)
-       // castle: check that all destination squares are not occupied
+       // TODO: move board building one level up (findAllMoves()) to avoid re-building at every piece...
+       // NOTE: castle & enPassant https://www.chessvariants.com/other.dir/alice.html
+       // --> Should be OK as is.
        getPotentialMovesFrom([x,y])
        {
                let sideBoard = this.getBoardOfPiece([x,y]);
@@ -67,8 +98,20 @@ class AliceRules extends ChessRules
                // Finally filter impossible moves
                const mirrorSide = (Object.keys(VariantRules.ALICE_CODES).includes(this.getPiece(x,y)) ? 1 : 2);
                return moves.filter(m => {
-                       if (this.board[m.end.x][m.end.y] != VariantRules.EMPTY)
+                       if (m.appear.length == 2) //castle
+                       {
+                               // If appear[i] not in vanish array, then must be empty square on other board
+                               m.appear.forEach(psq => {
+                                       if (this.board[psq.x][psq.y] != VariantRules.EMPTY &&
+                                               ![m.vanish[0].y,m.vanish[1].y].includes(psq.y))
+                                       {
+                                               return false;
+                                       }
+                               });
+                       }
+                       else if (this.board[m.end.x][m.end.y] != VariantRules.EMPTY)
                        {
+                               // Attempt to capture
                                const piece = this.getPiece(m.end.x,m.end.y);
                                if ((mirrorSide==1 && Object.keys(VariantRules.ALICE_PIECES).includes(piece))
                                        || (mirrorSide==2 && Object.keys(VariantRules.ALICE_CODES).includes(piece)))
@@ -76,12 +119,22 @@ class AliceRules extends ChessRules
                                        return false;
                                }
                        }
-                       m.appear.forEach(psq => {
-                               if (Object.keys(VariantRules.ALICE_CODES).includes(psq.p))
+                       // If the move is computed on board1, m.appear change for Alice pieces.
+                       if (mirrorSide==1)
+                       {
+                               m.appear.forEach(psq => { //forEach: castling taken into account
                                        psq.p = VariantRules.ALICE_CODES[psq.p]; //goto board2
-                               else
-                                       psq.p = VariantRules.ALICE_PIECES[psq.p]; //goto board1
-                       });
+                               });
+                       }
+                       else //move on board2: mark vanishing pieces as Alice
+                       {
+                               m.vanish.forEach(psq => {
+                                       psq.p = VariantRules.ALICE_CODES[psq.p];
+                               });
+                       }
+                       // Fix en-passant captures
+                       if (m.vanish.length == 2 && this.board[m.end.x][m.end.y] == VariantRules.EMPTY)
+                               m.vanish[1].c = this.getOppCol(this.getColor(x,y));
                        return true;
                });
        }
@@ -114,6 +167,60 @@ class AliceRules extends ChessRules
                return res;
        }
 
+       updateVariables(move)
+       {
+               super.updateVariables(move); //standard king
+               const piece = this.getPiece(move.start.x,move.start.y);
+               const c = this.getColor(move.start.x,move.start.y);
+               // "l" = Alice king
+               if (piece == "l")
+               {
+                       this.kingPos[c][0] = move.appear[0].x;
+                       this.kingPos[c][1] = move.appear[0].y;
+                       this.castleFlags[c] = [false,false];
+               }
+       }
+
+       unupdateVariables(move)
+       {
+               super.unupdateVariables(move);
+               const c = this.getColor(move.start.x,move.start.y);
+               if (this.getPiece(move.start.x,move.start.y) == "l")
+                       this.kingPos[c] = [move.start.x, move.start.y];
+       }
+
+       checkGameEnd()
+       {
+               const color = this.turn;
+               let sideBoard = this.getBoardOfPiece(this.kingPos[color]);
+               let saveBoard = this.board;
+               this.board = sideBoard;
+               let res = "*";
+               if (!this.isAttacked(this.kingPos[color], this.getOppCol(color)))
+                       res = "1/2";
+               else
+                       res = (color == "w" ? "0-1" : "1-0");
+               this.board = saveBoard;
+               return res;
+       }
+
+       static get VALUES() {
+               return {
+                       'p': 1,
+                       's': 1,
+                       'r': 5,
+                       'u': 5,
+                       'n': 3,
+                       'o': 3,
+                       'b': 3,
+                       'c': 3,
+                       'q': 9,
+                       't': 9,
+                       'k': 1000,
+                       'l': 1000
+               };
+       }
+
        getNotation(move)
        {
                if (move.appear.length == 2 && move.appear[0].p == VariantRules.KING)
@@ -128,9 +235,13 @@ class AliceRules extends ChessRules
                        String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
                const piece = this.getPiece(move.start.x, move.start.y);
 
+               const captureMark = (move.vanish.length > move.appear.length ? "x" : "");
+               let pawnMark = "";
+               if (["p","s"].includes(piece) && captureMark.length == 1)
+                       pawnMark = String.fromCharCode(97 + move.start.y); //start column
+
                // Piece or pawn movement
-               let notation = piece.toUpperCase() +
-                       (move.vanish.length > move.appear.length ? "x" : "") + finalSquare;
+               let notation = piece.toUpperCase() + pawnMark + captureMark + finalSquare;
                if (['s','p'].includes(piece) && !['s','p'].includes(move.appear[0].p))
                {
                        // Promotion
@@ -138,19 +249,4 @@ class AliceRules extends ChessRules
                }
                return notation;
        }
-
-       checkGameEnd()
-       {
-               const color = this.turn;
-               let sideBoard = this.getBoardOfPiece(this.kingPos[color]);
-               let saveBoard = this.board;
-               this.board = sideBoard;
-               let res = "*";
-               if (!this.isAttacked(this.kingPos[color], this.getOppCol(color)))
-                       res = "1/2";
-               else
-                       res = (color == "w" ? "0-1" : "1-0");
-               this.board = saveBoard;
-               return res;
-       }
 }