Alice rules implemented, but unfinished and with bugs...
authorBenjamin Auder <benjamin.auder@somewhere>
Thu, 22 Nov 2018 17:22:05 +0000 (18:22 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Thu, 22 Nov 2018 17:22:05 +0000 (18:22 +0100)
public/javascripts/base_rules.js
public/javascripts/components/game.js
public/javascripts/variants/Alice.js

index e757f7a..cb426f3 100644 (file)
@@ -699,6 +699,8 @@ class ChessRules
 
        play(move, ingame)
        {
+               console.log("play " + this.getNotation(move));
+               console.log(JSON.stringify(move));
                if (!!ingame)
                        move.notation = this.getNotation(move);
 
@@ -716,6 +718,7 @@ class ChessRules
                this.moves.pop();
                this.unupdateVariables(move);
                this.parseFlags(JSON.parse(move.flags));
+               console.log("undo " + this.getNotation(move));
        }
 
        //////////////
@@ -1011,10 +1014,10 @@ class ChessRules
                }
 
                // Translate final square
-               let finalSquare =
+               const finalSquare =
                        String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
 
-               let piece = this.getPiece(move.start.x, move.start.y);
+               const piece = this.getPiece(move.start.x, move.start.y);
                if (piece == VariantRules.PAWN)
                {
                        // Pawn move
@@ -1022,7 +1025,7 @@ class ChessRules
                        if (move.vanish.length > move.appear.length)
                        {
                                // Capture
-                               let startColumn = String.fromCharCode(97 + move.start.y);
+                               const startColumn = String.fromCharCode(97 + move.start.y);
                                notation = startColumn + "x" + finalSquare;
                        }
                        else //no capture
index 5690eb1..e3cc6af 100644 (file)
@@ -672,10 +672,9 @@ Vue.component('my-game', {
                                this.selectedPiece.style.display = "inline-block";
                                this.selectedPiece.style.zIndex = 3000;
                                let startSquare = this.getSquareFromId(e.target.parentNode.id);
-                               this.possibleMoves = this.mode!="idle" && this.vr.canIplay(this.mycolor,startSquare)
+                               this.possibleMoves = true//this.mode!="idle" && this.vr.canIplay(this.mycolor,startSquare)
                                        ? this.vr.getPossibleMovesFrom(startSquare)
                                        : [];
-                               console.log(this.possibleMoves);
                                e.target.parentNode.appendChild(this.selectedPiece);
                        }
                },
index db0881e..3cba8d0 100644 (file)
-class AliceRules extends ChessRUles
+class AliceRules extends ChessRules
 {
-       // TODO: more general double correspondance normal <--> alice
        static get ALICE_PIECES()
        {
-               return ['s','t','u','c','o','l']; //king is 'l'
+               return {
+                       's': 'p',
+                       't': 'q',
+                       'u': 'r',
+                       'c': 'b',
+                       'o': 'n',
+                       'l': 'k',
+               };
+       }
+       static get ALICE_CODES()
+       {
+               return {
+                       'p': 's',
+                       'q': 't',
+                       'r': 'u',
+                       'b': 'c',
+                       'n': 'o',
+                       'k': 'l',
+               };
        }
 
        static getPpath(b)
        {
-               return (this.ALICE_PIECES.includes(b[1]) ? "Alice/" : "") + b;
+               return (Object.keys(this.ALICE_PIECES).includes(b[1]) ? "Alice/" : "") + b;
        }
 
-       getPotentialMovesFrom([x,y])
+       getBoardOfPiece([x,y])
        {
-               // Build board1+board2 from complete board
-               let board1 = doubleArray(sizeX, sizeY, "");
-               let board2 = doubleArray(sizeX, sizeY, "");
-               const [sizeX,sizeY] = variantRules.size;
+               const V = VariantRules;
+               // Build board where the piece is
+               const mirrorSide = (Object.keys(V.ALICE_CODES).includes(this.getPiece(x,y)) ? 1 : 2);
+               // Build corresponding board from complete board
+               const [sizeX,sizeY] = V.size;
+               let sideBoard = doubleArray(sizeX, sizeY, "");
                for (let i=0; i<sizeX; i++)
                {
                        for (let j=0; j<sizeY; j++)
                        {
                                const piece = this.getPiece(i,j);
-                               if (this.ALICE_PIECES.includes(piece))
-                                       board2[i][j] = this.board[i][j];
-                               else
-                                       board1[i][j] = this.board[i][j];
+                               if (mirrorSide==1 && Object.keys(V.ALICE_CODES).includes(piece))
+                                       sideBoard[i][j] = this.board[i][j];
+                               else if (mirrorSide==2 && Object.keys(V.ALICE_PIECES).includes(piece))
+                                       sideBoard[i][j] = this.getColor(i,j) + V.ALICE_PIECES[piece];
                        }
                }
-               let saveBoard = JSON.parse(JSON.stringify(this.board));
-
-               // Search valid moves on both boards
-               let moves = [];
-               this.board = board1;
-
+               return sideBoard;
+       }
 
-               this.board = board2;
+       // 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
+       getPotentialMovesFrom([x,y])
+       {
+               let sideBoard = this.getBoardOfPiece([x,y]);
 
+               // Search valid moves on sideBoard
+               let saveBoard = this.board;
+               this.board = sideBoard;
+               let moves = super.getPotentialMovesFrom([x,y]);
                this.board = saveBoard;
 
                // Finally filter impossible moves
-
-               return 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)
+                       {
+                               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)))
+                               {
+                                       return false;
+                               }
+                       }
+                       m.appear.forEach(psq => {
+                               if (Object.keys(VariantRules.ALICE_CODES).includes(psq.p))
+                                       psq.p = VariantRules.ALICE_CODES[psq.p]; //goto board2
+                               else
+                                       psq.p = VariantRules.ALICE_PIECES[psq.p]; //goto board1
+                       });
+                       return true;
+               });
        }
 
        underCheck(move)
        {
-               // 1 where is king ? if board1 then build it, if board2 then build it. then check.
                const color = this.turn;
                this.play(move);
+               let sideBoard = this.getBoardOfPiece(this.kingPos[color]);
+               let saveBoard = this.board;
+               this.board = sideBoard;
                let res = this.isAttacked(this.kingPos[color], this.getOppCol(color));
+               this.board = saveBoard;
                this.undo(move);
                return res;
        }
 
-       // TODO also:
-       //getCheckSquares(move)
-
-       // TODO: pieces change side!
-       static PlayOnBoard(board, move)
+       getCheckSquares(move)
        {
-               for (let psq of move.vanish)
-                       board[psq.x][psq.y] = VariantRules.EMPTY;
-               for (let psq of move.appear)
-                       board[psq.x][psq.y] = psq.c + psq.p;
+               this.play(move);
+               const color = this.turn; //opponent
+               let sideBoard = this.getBoardOfPiece(this.kingPos[color]);
+               let saveBoard = this.board;
+               this.board = sideBoard;
+               let res = this.isAttacked(this.kingPos[color], this.getOppCol(color))
+                       ? [ JSON.parse(JSON.stringify(this.kingPos[color])) ]
+                       : [ ];
+               this.board = saveBoard;
+               this.undo(move);
+               return res;
        }
-       static UndoOnBoard(board, move)
+
+       getNotation(move)
        {
-               for (let psq of move.appear)
-                       board[psq.x][psq.y] = VariantRules.EMPTY;
-               for (let psq of move.vanish)
-                       board[psq.x][psq.y] = psq.c + psq.p;
+               if (move.appear.length == 2 && move.appear[0].p == VariantRules.KING)
+               {
+                       if (move.end.y < move.start.y)
+                               return "0-0-0";
+                       else
+                               return "0-0";
+               }
+
+               const finalSquare =
+                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+               const piece = this.getPiece(move.start.x, move.start.y);
+
+               // Piece or pawn movement
+               let notation = piece.toUpperCase() +
+                       (move.vanish.length > move.appear.length ? "x" : "") + finalSquare;
+               if (['s','p'].includes(piece) && !['s','p'].includes(move.appear[0].p))
+               {
+                       // Promotion
+                       notation += "=" + move.appear[0].p.toUpperCase();
+               }
+               return notation;
        }
 
        checkGameEnd()
        {
                const color = this.turn;
-               // No valid move: stalemate or checkmate?
-               // TODO: here also, need to build the board with king on it
+               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)))
-                       return "1/2";
-               // OK, checkmate
-               return color == "w" ? "0-1" : "1-0";
+                       res = "1/2";
+               else
+                       res = (color == "w" ? "0-1" : "1-0");
+               this.board = saveBoard;
+               return res;
        }
 }