From: Benjamin Auder Date: Tue, 18 Jun 2019 17:30:14 +0000 (+0200) Subject: Some fixes. TODO: game.mode must be analyze when score is not '*' ==> simplify Board... X-Git-Url: https://git.auder.net/variants/Chakart/css/assets/doc/html/%7B%7B%20pkg.url%20%7D%7D?a=commitdiff_plain;h=d4036efea5b57656478affd7d71f53dcea0f8017;p=vchess.git Some fixes. TODO: game.mode must be analyze when score is not '*' ==> simplify Board.analyze --- diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index 442579d0..4a40a3a5 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -7,7 +7,7 @@ label.modal-close(for="modalEog") h3#eogMessage.section {{ endgameMessage }} // TODO: or "BoardHex" if this.game.vname in "Hexagonal..." - Board(:vr="vr" :last-move="lastMove" :analyze="game.mode=='analyze'" + Board(:vr="vr" :last-move="lastMove" :analyze="analyze" :user-color="game.mycolor" :orientation="orientation" :vname="game.vname" @play-move="play") .button-group @@ -22,7 +22,17 @@ a#download(href="#") .button-group button#downloadBtn(@click="download") {{ st.tr["Download PGN"] }} - button Import game + + // TODO: Import game button copy game locally in IndexedDB + //button Import game + + +// TODO: do not use localStorage for current game, but directly indexedDB +// update function is similar +// ==> retrieval functions must filter on score, and potential "imported" tag +// ==> this should allow several simultaneous games + + //MoveList(v-if="showMoves" :moves="moves" :cursor="cursor" @goto-move="gotoMove") @@ -32,6 +42,7 @@ import Board from "@/components/Board.vue"; //import MoveList from "@/components/MoveList.vue"; import { store } from "@/store"; import { getSquareId } from "@/utils/squareId"; +import { getDate } from "@/utils/datetime"; export default { name: 'my-base-game', @@ -68,7 +79,7 @@ export default { return this.game.vname != "Dark" || this.score != "*"; }, analyze: function() { - return this.game.mode == "analyze"; + return this.game.mode == "analyze" || this.game.score != "*"; }, }, created: function() { @@ -81,6 +92,16 @@ export default { this.orientation = this.game.mycolor || "w"; //default orientation for observed games this.score = this.game.score || "*"; //mutable (if initially "*") this.moves = JSON.parse(JSON.stringify(this.game.moves || [])); + // Post-processing: decorate each move with color + current FEN: + // (to be able to jump to any position quickly) + this.moves.forEach(move => { + // NOTE: this is doing manually what play() function below achieve, + // but in a lighter "fast-forward" way + move.color = this.vr.turn; + move.notation = this.vr.getNotation(move); + this.vr.play(move); + move.fen = this.vr.getFen(); + }); const L = this.moves.length; this.cursor = L-1; this.lastMove = (L > 0 ? this.moves[L-1] : null); @@ -98,8 +119,8 @@ export default { pgn += '[Site "vchess.club"]\n'; pgn += '[Variant "' + this.game.vname + '"]\n'; pgn += '[Date "' + getDate(new Date()) + '"]\n'; - pgn += '[White "' + this.game.players[0] + '"]\n'; - pgn += '[Black "' + this.game.players[1] + '"]\n'; + pgn += '[White "' + this.game.players[0].name + '"]\n'; + pgn += '[Black "' + this.game.players[1].name + '"]\n'; pgn += '[Fen "' + this.game.fenStart + '"]\n'; pgn += '[Result "' + this.score + '"]\n\n'; let counter = 1; @@ -111,9 +132,9 @@ export default { { let move = ""; while (i < this.moves.length && this.moves[i].color == color) - move += this.moves[i++].notation[0] + ","; + move += this.moves[i++].notation + ","; move = move.slice(0,-1); //remove last comma - pgn += move + (i < this.moves.length-1 ? " " : ""); + pgn += move + (i < this.moves.length ? " " : ""); } } return pgn + "\n"; diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue index 27833815..f97a2c5a 100644 --- a/client/src/components/Board.vue +++ b/client/src/components/Board.vue @@ -157,7 +157,7 @@ export default { ); }) ); - const playingColor = userColor || "w"; //default for an observer + const playingColor = this.userColor || "w"; //default for an observer let elementArray = [choices, gameDiv]; if (!!this.vr.reserve) { diff --git a/client/src/utils/storage.js b/client/src/utils/storage.js index e5978ae3..2e7a84fb 100644 --- a/client/src/utils/storage.js +++ b/client/src/utils/storage.js @@ -51,8 +51,8 @@ function addGame(game, callback) // Clear current live game from localStorage function clear() { - localStorage.deleteItem("gameInfo"); - localStorage.deleteItem("gameState"); + localStorage.removeItem("gameInfo"); + localStorage.removeItem("gameState"); } // Current live game: @@ -140,20 +140,28 @@ export const GameStorage = // TODO: option for remote retrieval (third arg, or just "gameRef") getLocal: function(gameId, callback) { - let games = []; dbOperation((db) => { - // TODO: if gameId is provided, limit search to gameId (just .get(gameId). ...) let objectStore = db.transaction('games').objectStore('games'); - objectStore.openCursor().onsuccess = function(event) { - var cursor = event.target.result; - // if there is still another cursor to go, keep running this code - if (cursor) - { - games.push(cursor.value); - cursor.continue(); + if (!gameId) //retrieve all + { + let games = []; + objectStore.openCursor().onsuccess = function(event) { + let cursor = event.target.result; + // if there is still another cursor to go, keep running this code + if (cursor) + { + games.push(cursor.value); + cursor.continue(); + } + else + callback(games); + } + } + else //just one game + { + objectStore.get(gameId).onsuccess = function(event) { + callback(event.target.result); } - else - callback(games); } }); }, diff --git a/client/src/views/Game.vue b/client/src/views/Game.vue index 9d755df1..9be88069 100644 --- a/client/src/views/Game.vue +++ b/client/src/views/Game.vue @@ -11,7 +11,7 @@ button(@click="abortGame") {{ st.tr["Game is too boring"] }} BaseGame(:game="game" :vr="vr" ref="basegame" @newmove="processMove" @gameover="gameOver") - .button-group(v-if="game.mode!='analyze'") + .button-group(v-if="game.mode!='analyze' && game.score=='*'") button(@click="offerDraw") Draw button(@click="() => abortGame()") Abort button(@click="resign") Resign @@ -219,8 +219,10 @@ export default { else { console.log(event); + return; //const message = event. - this.gameOver("?"); + // Next line will trigger a "gameover" event, bubbling up till here + this.$refs["basegame"].endGame("?"); this.game.players.forEach(p => { if (!!p.sid && p.sid != this.st.user.sid) { @@ -255,25 +257,15 @@ export default { // - from remote peer (one live game I don't play, finished or not) loadGame: function() { GameStorage.get(this.gameRef, async (game) => { + const vModule = await import("@/variants/" + game.vname + ".js"); + window.V = vModule.VariantRules; + this.vr = new V(game.fenStart); this.game = Object.assign({}, game, // NOTE: assign mycolor here, since BaseGame could also bs VS computer {mycolor: [undefined,"w","b"][1 + game.players.findIndex( p => p.sid == this.st.user.sid)]}, ); - const vModule = await import("@/variants/" + game.vname + ".js"); - window.V = vModule.VariantRules; - this.vr = new V(game.fen); - // Post-processing: decorate each move with current FEN: - // (to be able to jump to any position quickly) - game.moves.forEach(move => { - // NOTE: this is doing manually what BaseGame.play() achieve... - // but in a lighter "fast-forward" way - move.color = this.vr.turn; - this.vr.play(move); - move.fen = this.vr.getFen(); - }); - this.vr.re_init(game.fen); }); // // Poll all players except me (if I'm playing) to know online status. // // --> Send ping to server (answer pong if players[s] are connected) diff --git a/server/sockets.js b/server/sockets.js index 274d70ad..d92778c0 100644 --- a/server/sockets.js +++ b/server/sockets.js @@ -31,6 +31,7 @@ module.exports = function(wss) { wss.on("connection", (socket, req) => { const query = getJsonFromUrl(req.url); const sid = query["sid"]; + // TODO: later, allow duplicate connections (shouldn't be much more complicated) // Ignore duplicate connections (on the same live game that we play): if (!!clients[sid]) return socket.send(JSON.stringify({code:"duplicate"}));