More robust in-check indications (ready for Antiking)
authorBenjamin Auder <benjamin.auder@somewhere>
Sun, 18 Nov 2018 00:47:58 +0000 (01:47 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Sun, 18 Nov 2018 00:47:58 +0000 (01:47 +0100)
TODO
public/javascripts/base_rules.js
public/javascripts/components/game.js
public/javascripts/variants/Atomic.js
sockets.js

diff --git a/TODO b/TODO
index d4e48b0..006b915 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,7 +1,6 @@
 Styles must be improved (full width for smartphones, selectable text for PGN...)
 Tooltip text should fade (even when mouse stay on it, especially for small screens)
 Styles must be improved (full width for smartphones, selectable text for PGN...)
 Tooltip text should fade (even when mouse stay on it, especially for small screens)
-Checkered stage 2: switch button at reserve position.
+Checkered stage 2: switch button at reserve position (or on top).
 If a played disconnect right after opponent sent a move, it might be never received: secure this
 If a played disconnect right after opponent sent a move, it might be never received: secure this
-Think about non-conventional variants with 2 kings for example: undercheck highlight?
-  --> underCheck should return a vector in this case. Adapt.
-       --> incheck should be an array of squares, in general. Think AntiKing
+Mode expert: game.js, button on top (with online indicator)
+Turn indicator on top too (black or white)
index 9a4ef91..b604e79 100644 (file)
@@ -629,6 +629,7 @@ class ChessRules
                return false;
        }
 
                return false;
        }
 
+       // Is color c under check after move ?
        underCheck(move, c)
        {
                this.play(move);
        underCheck(move, c)
        {
                this.play(move);
@@ -637,6 +638,17 @@ class ChessRules
                return res;
        }
 
                return res;
        }
 
+       // On which squares is color c under check (after move) ?
+       getCheckSquares(move, c)
+       {
+               this.play(move);
+               let res = this.isAttacked(this.kingPos[c], this.getOppCol(c))
+                       ? [ JSON.parse(JSON.stringify(this.kingPos[c])) ] //need to duplicate!
+                       : [ ];
+               this.undo(move);
+               return res;
+       }
+
        // Apply a move on board
        static PlayOnBoard(board, move)
        {
        // Apply a move on board
        static PlayOnBoard(board, move)
        {
index 125aeea..499e473 100644 (file)
@@ -16,7 +16,7 @@ Vue.component('my-game', {
                        oppConnected: false,
                        seek: false,
                        fenStart: "",
                        oppConnected: false,
                        seek: false,
                        fenStart: "",
-                       incheck: false,
+                       incheck: [],
                };
        },
        render(h) {
                };
        },
        render(h) {
@@ -24,6 +24,9 @@ Vue.component('my-game', {
                // Precompute hints squares to facilitate rendering
                let hintSquares = doubleArray(sizeX, sizeY, false);
                this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; });
                // Precompute hints squares to facilitate rendering
                let hintSquares = doubleArray(sizeX, sizeY, false);
                this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; });
+               // Also precompute in-check squares
+               let incheckSq = doubleArray(sizeX, sizeY, false);
+               this.incheck.forEach(sq => { incheckSq[sq[0]][sq[1]] = true; });
                let elementArray = [];
                let square00 = document.getElementById("sq-0-0");
                let squareWidth = !!square00
                let elementArray = [];
                let square00 = document.getElementById("sq-0-0");
                let squareWidth = !!square00
@@ -172,8 +175,6 @@ Vue.component('my-game', {
                                                        }
                                                        const lm = this.vr.lastMove;
                                                        const highlight = !!lm && _.isMatch(lm.end, {x:ci,y:cj});
                                                        }
                                                        const lm = this.vr.lastMove;
                                                        const highlight = !!lm && _.isMatch(lm.end, {x:ci,y:cj});
-                                                       const incheck = this.incheck
-                                                               && _.isEqual(this.vr.kingPos[this.vr.turn], [ci,cj]);
                                                        return h(
                                                                'div',
                                                                {
                                                        return h(
                                                                'div',
                                                                {
@@ -182,7 +183,7 @@ Vue.component('my-game', {
                                                                                'light-square': !highlight && (i+j)%2==0,
                                                                                'dark-square': !highlight && (i+j)%2==1,
                                                                                'highlight': highlight,
                                                                                'light-square': !highlight && (i+j)%2==0,
                                                                                'dark-square': !highlight && (i+j)%2==1,
                                                                                'highlight': highlight,
-                                                                               'incheck': incheck,
+                                                                               'incheck': incheckSq[ci][cj],
                                                                        },
                                                                        attrs: {
                                                                                id: this.getSquareId({x:ci,y:cj}),
                                                                        },
                                                                        attrs: {
                                                                                id: this.getSquareId({x:ci,y:cj}),
@@ -499,8 +500,8 @@ Vue.component('my-game', {
                                {
                                        const oppCol = this.vr.turn;
                                        const lastMove = moves[moves.length-1];
                                {
                                        const oppCol = this.vr.turn;
                                        const lastMove = moves[moves.length-1];
-                                       this.vr.undo(lastMove);
-                                       this.incheck = this.vr.underCheck(lastMove, oppCol);
+                                       this.vr.undo(lastMove, "ingame");
+                                       this.incheck = this.vr.getCheckSquares(lastMove, oppCol);
                                        this.vr.play(lastMove, "ingame");
                                }
                                delete localStorage["newgame"];
                                        this.vr.play(lastMove, "ingame");
                                }
                                delete localStorage["newgame"];
@@ -631,7 +632,7 @@ Vue.component('my-game', {
                                return;
                        }
                        const oppCol = this.vr.getOppCol(this.vr.turn);
                                return;
                        }
                        const oppCol = this.vr.getOppCol(this.vr.turn);
-                       this.incheck = this.vr.underCheck(move, oppCol); //is opponent in check?
+                       this.incheck = this.vr.getCheckSquares(move, oppCol); //is opponent in check?
                        // Not programmatic, or animation is over
                        if (this.mode == "human" && this.vr.turn == this.mycolor)
                        {
                        // Not programmatic, or animation is over
                        if (this.mode == "human" && this.vr.turn == this.mycolor)
                        {
index b7c7504..bf860df 100644 (file)
@@ -131,6 +131,19 @@ class AtomicRules extends ChessRules
                return res;
        }
 
                return res;
        }
 
+       getCheckSquares(move, c)
+       {
+               const saveKingPos = this.kingPos[c]; //king might explode
+               this.play(move);
+               let res = [ ];
+               if (this.kingPos[c][0] < 0)
+                       res = [saveKingPos];
+               else if (this.isAttacked(this.kingPos[c], this.getOppCol(c)))
+                       res = [ this.kingPos[c] ]
+               this.undo(move);
+               return res;
+       }
+
        checkGameEnd(color)
        {
                const kp = this.kingPos[color];
        checkGameEnd(color)
        {
                const kp = this.kingPos[color];
index c3190aa..a1818e0 100644 (file)
@@ -20,6 +20,7 @@ module.exports = function(wss) {
 
        // TODO: when relaying to opponent, check readyState, potential setTimeout()? + send opponent (re)disconnect
        // (resign, newgame, newmove). See https://github.com/websockets/ws/blob/master/lib/websocket.js around line 313
 
        // TODO: when relaying to opponent, check readyState, potential setTimeout()? + send opponent (re)disconnect
        // (resign, newgame, newmove). See https://github.com/websockets/ws/blob/master/lib/websocket.js around line 313
+       // TODO: awaiting newmove, resign, newgame :: in memory structure
 
        wss.on("connection", (socket, req) => {
                //const params = new URL("http://localhost" + req.url).searchParams;
 
        wss.on("connection", (socket, req) => {
                //const params = new URL("http://localhost" + req.url).searchParams;