Allow to navigate in game after it's over (undo/play)
authorBenjamin Auder <benjamin.auder@somewhere>
Sat, 8 Dec 2018 01:35:42 +0000 (02:35 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Sat, 8 Dec 2018 01:35:42 +0000 (02:35 +0100)
TODO
public/javascripts/components/game.js

diff --git a/TODO b/TODO
index 26aabd5..1aae2fb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,4 +1,3 @@
-Allow to navigate in game after it's over (back/play)
 For animation, moves should contains "moving" and "fading" maybe...
 (But it's really just for Magnetic chess)
 setInterval "CRON" task in sockets.js to check connected clients
 For animation, moves should contains "moving" and "fading" maybe...
 (But it's really just for Magnetic chess)
 setInterval "CRON" task in sockets.js to check connected clients
index 14d3007..11f99b0 100644 (file)
@@ -239,6 +239,34 @@ Vue.component('my-game', {
                                                [h('i', { 'class': { "material-icons": true } }, "flag")])
                                );
                        }
                                                [h('i', { 'class': { "material-icons": true } }, "flag")])
                                );
                        }
+                       else if (this.vr.moves.length > 0)
+                       {
+                               // A game finished, and another is not started yet: allow navigation
+                               actionArray = actionArray.concat([
+                                       h('button',
+                                               {
+                                                       style: { "margin-left": "30px" },
+                                                       on: { click: e => this.undo() },
+                                                       attrs: { "aria-label": 'Undo' },
+                                                       'class': {
+                                                               "tooltip":true,
+                                                               "bottom": true,
+                                                       },
+                                               },
+                                               [h('i', { 'class': { "material-icons": true } }, "fast_rewind")]),
+                                       h('button',
+                                               {
+                                                       on: { click: e => this.play() },
+                                                       attrs: { "aria-label": 'Play' },
+                                                       'class': {
+                                                               "tooltip":true,
+                                                               "bottom": true,
+                                                       },
+                                               },
+                                               [h('i', { 'class': { "material-icons": true } }, "fast_forward")]),
+                                       ]
+                               );
+                       }
                        elementArray.push(gameDiv);
                        if (!!this.vr.reserve)
                        {
                        elementArray.push(gameDiv);
                        if (!!this.vr.reserve)
                        {
@@ -562,6 +590,18 @@ Vue.component('my-game', {
                this.conn.onopen = socketOpenListener;
                this.conn.onmessage = socketMessageListener;
                this.conn.onclose = socketCloseListener;
                this.conn.onopen = socketOpenListener;
                this.conn.onmessage = socketMessageListener;
                this.conn.onclose = socketCloseListener;
+               // Listen to keyboard left/right to navigate in game
+               document.onkeydown = event => {
+                       if (this.mode == "idle" && this.vr.moves.length > 0
+                               && [37,39].includes(event.keyCode))
+                       {
+                               event.preventDefault();
+                               if (event.keyCode == 37) //Back
+                                       this.undo();
+                               else //Forward (39)
+                                       this.play();
+                       }
+               };
        },
        methods: {
                download: function() {
        },
        methods: {
                download: function() {
@@ -583,6 +623,7 @@ Vue.component('my-game', {
                        if (this.mode == "human")
                                this.clearStorage();
                        this.mode = "idle";
                        if (this.mode == "human")
                                this.clearStorage();
                        this.mode = "idle";
+                       this.cursor = this.vr.moves.length; //to navigate in finished game
                        this.oppid = "";
                },
                getEndgameMessage: function(score) {
                        this.oppid = "";
                },
                getEndgameMessage: function(score) {
@@ -866,6 +907,13 @@ Vue.component('my-game', {
                        }, 200);
                },
                play: function(move, programmatic) {
                        }, 200);
                },
                play: function(move, programmatic) {
+                       if (!move)
+                       {
+                               // Navigate after game is over
+                               if (this.cursor >= this.vr.moves.length)
+                                       return; //already at the end
+                               move = this.vr.moves[this.cursor++];
+                       }
                        if (!!programmatic) //computer or human opponent
                        {
                                this.animateMove(move);
                        if (!!programmatic) //computer or human opponent
                        {
                                this.animateMove(move);
@@ -876,14 +924,28 @@ Vue.component('my-game', {
                        if (this.mode == "human" && this.vr.turn == this.mycolor)
                                this.conn.send(JSON.stringify({code:"newmove", move:move, oppid:this.oppid}));
                        new Audio("/sounds/chessmove1.mp3").play().then(() => {}).catch(err => {});
                        if (this.mode == "human" && this.vr.turn == this.mycolor)
                                this.conn.send(JSON.stringify({code:"newmove", move:move, oppid:this.oppid}));
                        new Audio("/sounds/chessmove1.mp3").play().then(() => {}).catch(err => {});
-                       this.vr.play(move, "ingame");
+                       if (this.mode != "idle")
+                               this.vr.play(move, "ingame");
+                       else
+                               VariantRules.PlayOnBoard(this.vr.board, move);
                        if (this.mode == "human")
                                this.updateStorage(); //after our moves and opponent moves
                        if (this.mode == "human")
                                this.updateStorage(); //after our moves and opponent moves
-                       const eog = this.vr.checkGameOver();
-                       if (eog != "*")
-                               this.endGame(eog);
-                       else if (this.mode == "computer" && this.vr.turn != this.mycolor)
+                       if (this.mode != "idle")
+                       {
+                               const eog = this.vr.checkGameOver();
+                               if (eog != "*")
+                                       this.endGame(eog);
+                       }
+                       if (this.mode == "computer" && this.vr.turn != this.mycolor)
                                setTimeout(this.playComputerMove, 500);
                },
                                setTimeout(this.playComputerMove, 500);
                },
+               undo: function() {
+                       // Navigate after game is over
+                       if (this.cursor == 0)
+                               return; //already at the beginning
+                       const move = this.vr.moves[--this.cursor];
+                       VariantRules.UndoOnBoard(this.vr.board, move);
+                       this.$forceUpdate(); //TODO: ?!
+               }
        },
 })
        },
 })