From: Benjamin Auder <benjamin.auder@somewhere> Date: Wed, 22 Jan 2020 11:33:57 +0000 (+0100) Subject: Some changes to the logic in Rules.vue: weird behavior, TODO X-Git-Url: https://git.auder.net/doc/html/scripts/img/current/index.css?a=commitdiff_plain;h=41cb9b940084d6f56351a772f0340ebf0bc8d1bc;p=vchess.git Some changes to the logic in Rules.vue: weird behavior, TODO --- diff --git a/client/src/App.vue b/client/src/App.vue index e06a2fef..84f4b51e 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -22,8 +22,7 @@ | {{ st.tr["Variants"] }} router-link(to="/mygames") | {{ st.tr["My games"] }} - // TODO: parametric URL, "forumURL" - a(href="https://forum.vchess.club") + a(href="https://groups.google.com/forum/#!forum/vchess-club") | {{ st.tr["Forum"] }} #rightMenu .clickable(onClick="doClick('modalUser')") diff --git a/client/src/base_rules.js b/client/src/base_rules.js index 5fb00277..169fb2d9 100644 --- a/client/src/base_rules.js +++ b/client/src/base_rules.js @@ -192,7 +192,7 @@ export const ChessRules = class ChessRules // Argument is a move: const move = moveOrSquare; const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x]; - // TODO: next conditions are first for Atomic, and last for Checkered + // NOTE: next conditions are first for Atomic, and last for Checkered if (move.appear.length > 0 && Math.abs(sx - ex) == 2 && move.appear[0].p == V.PAWN && ["w","b"].includes(move.appear[0].c)) { @@ -1128,7 +1128,6 @@ export const ChessRules = class ChessRules // Search depth: 2 for high branching factor, 4 for small (Loser chess, eg.) static get SEARCH_DEPTH() { return 3; } - // Assumption: at least one legal move // NOTE: works also for extinction chess because depth is 3... getComputerMove() { @@ -1137,6 +1136,8 @@ export const ChessRules = class ChessRules // Some variants may show a bigger moves list to the human (Switching), // thus the argument "computer" below (which is generally ignored) let moves1 = this.getAllValidMoves("computer"); + if (moves1.length == 0) //TODO: this situation should not happen + return null; // Can I mate in 1 ? (for Magnetic & Extinction) for (let i of shuffle(ArrayFun.range(moves1.length))) diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index 3b15742d..f10420d7 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -59,6 +59,9 @@ export default { "game.fenStart": function() { this.re_setVariables(); }, + "game.score": function() { + this.score = this.game.score; + }, }, computed: { showMoves: function() { @@ -69,7 +72,7 @@ export default { return this.game.vname != "Dark" || this.score != "*"; }, analyze: function() { - return this.game.mode == "analyze" || this.game.score != "*"; + return this.game.mode == "analyze" || this.score != "*"; }, }, created: function() { diff --git a/client/src/components/Board.vue b/client/src/components/Board.vue index f97a2c5a..4da64271 100644 --- a/client/src/components/Board.vue +++ b/client/src/components/Board.vue @@ -370,6 +370,8 @@ export default { .reserve-row-1 margin-bottom: 15px +// NOTE: no variants with reserve of size != 8 + div.board float: left height: 0 @@ -388,8 +390,6 @@ div.board11 width: 9.09% padding-bottom: 9.1% -// NOTE: no variants with reserve of size != 8 - .game width: 80vh margin: 0 auto diff --git a/client/src/components/ComputerGame.vue b/client/src/components/ComputerGame.vue index 9f8e1a30..5b04cd8c 100644 --- a/client/src/components/ComputerGame.vue +++ b/client/src/components/ComputerGame.vue @@ -8,10 +8,10 @@ <script> import BaseGame from "@/components/BaseGame.vue"; import { store } from "@/store"; -import Worker from 'worker-loader!@/playCompMove'; +import Worker from "worker-loader!@/playCompMove"; export default { - name: 'my-computer-game', + name: "my-computer-game", components: { BaseGame, }, @@ -21,47 +21,64 @@ export default { data: function() { return { st: store.state, - game: { }, + game: {}, vr: null, // Web worker to play computer moves without freezing interface: timeStart: undefined, //time when computer starts thinking - lockCompThink: false, //to avoid some ghost moves + compThink: false, //avoid asking a new move while one is being searched compWorker: null, }; }, watch: { "gameInfo.fen": function() { - // (Security) No effect if a computer move is in progress: - if (this.lockCompThink) - return this.$emit("computer-think"); this.launchGame(); }, - "gameInfo.userStop": function() { - if (this.gameInfo.userStop) + "gameInfo.score": function(newScore) { + if (newScore != "*") { - // User stopped the game: unknown result + this.game.score = newScore; //user action this.game.mode = "analyze"; + if (!this.compThink) + this.$emit("game-stopped"); //otherwise wait for comp } }, }, // Modal end of game, and then sub-components created: function() { - // Computer moves web worker logic: (TODO: also for observers in HH games ?) - this.compWorker = new Worker(); //'/javascripts/playCompMove.js'), + // Computer moves web worker logic: + this.compWorker = new Worker(); this.compWorker.onmessage = e => { - this.lockCompThink = true; //to avoid some ghost moves let compMove = e.data; + if (!compMove) + return; //after game ends, no more moves, nothing to do if (!Array.isArray(compMove)) compMove = [compMove]; //to deal with MarseilleRules // Small delay for the bot to appear "more human" - const delay = Math.max(500-(Date.now()-this.timeStart), 0); +// TODO: debug delay, 2000 --> 0 + const delay = 2000 + Math.max(500-(Date.now()-this.timeStart), 0); +console.log("GOT MOVE: " + this.compThink); setTimeout(() => { + // NOTE: Dark and 2-moves are incompatible const animate = (this.gameInfo.vname != "Dark"); this.$refs.basegame.play(compMove[0], animate); + const waitEndOfAnimation = () => { + // 250ms = length of animation (TODO: some constant somewhere) + setTimeout( () => { +console.log("RESET: " + this.compThink); + this.compThink = false; + if (this.game.score != "*") //user action + this.$emit("game-stopped"); + }, animate ? 250 : 0); + }; if (compMove.length == 2) - setTimeout( () => { this.$refs.basegame.play(compMove[1], animate); }, 750); - else //250 == length of animation (TODO: should be a constant somewhere) - setTimeout( () => this.lockCompThink = false, 250); + { + setTimeout( () => { + this.$refs.basegame.play(compMove[1], animate); + waitEndOfAnimation(); + }, 750); + } + else + waitEndOfAnimation(); }, delay); } if (!!this.gameInfo.fen) @@ -77,10 +94,10 @@ export default { this.compWorker.postMessage(["init",this.gameInfo.fen]); this.vr = new V(this.gameInfo.fen); const mycolor = (Math.random() < 0.5 ? "w" : "b"); - let players = ["Myself","Computer"]; + let players = [{name:"Myself"},{name:"Computer"}]; if (mycolor == "b") players = players.reverse(); - // NOTE: (TODO?) fen and fenStart are redundant in game object + // NOTE: fen and fenStart are redundant in game object this.game = Object.assign({}, this.gameInfo, { @@ -95,9 +112,10 @@ export default { }, playComputerMove: function() { this.timeStart = Date.now(); + this.compThink = true; +console.log("ASK MOVE (SET TRUE): " + this.compThink); this.compWorker.postMessage(["askmove"]); }, - // TODO: do not process if game is over (check score ?) processMove: function(move) { // Send the move to web worker (including his own moves) this.compWorker.postMessage(["newmove",move]); @@ -109,8 +127,9 @@ export default { } }, gameOver: function(score) { - // Just switch to analyze mode: no user action can set score + this.game.score = score; this.game.mode = "analyze"; + this.$emit("game-over", score); //bubble up to Rules.vue }, }, }; diff --git a/client/src/components/GameList.vue b/client/src/components/GameList.vue index 2b7f6573..bf9c8ffc 100644 --- a/client/src/components/GameList.vue +++ b/client/src/components/GameList.vue @@ -6,6 +6,7 @@ table th Black th Time control th(v-if="showResult") Result + // TODO: show my games first (st.user.id or sid) tr(v-for="g in games" @click="$emit('show-game',g)") td {{ g.vname }} td {{ g.players[0].name || "@nonymous" }} diff --git a/client/src/router.js b/client/src/router.js index 26bdee94..a4d32369 100644 --- a/client/src/router.js +++ b/client/src/router.js @@ -86,9 +86,6 @@ router.beforeEach((to, from, next) => { store.state.conn.send(JSON.stringify({code: "pagechange", page: to.path})); } next(); - // TODO?: redirect to current game (through GameStorage.getCurrent()) if any? - // (and if the URL doesn't already match it) (use next("/game/GID")) - //https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards }); export default router; diff --git a/client/src/views/Rules.vue b/client/src/views/Rules.vue index f196e355..c77294ff 100644 --- a/client/src/views/Rules.vue +++ b/client/src/views/Rules.vue @@ -2,16 +2,17 @@ .row .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 .button-group - button(@click="display='rules'") Read the rules + button(@click="clickReadRules") Read the rules button(v-show="!gameInProgress" @click="() => startGame('auto')") | Observe a sample game button(v-show="!gameInProgress" @click="() => startGame('versus')") | Beat the computer! - button(v-show="gameInProgress" @click="stopGame") + button(v-show="gameInProgress" @click="() => stopGame()") | Stop game .section-content(v-show="display=='rules'" v-html="content") ComputerGame(v-show="display=='computer'" :game-info="gameInfo" - @computer-think="gameInProgress=false" @game-over="stopGame") + @computer-think="gameInProgress=false" @game-over="stopGame" + @game-stopped="gameStopped") </template> <script> @@ -35,7 +36,7 @@ export default { vname: "_unknown", mode: "versus", fen: "", - userStop: false, + score: "*", } }; }, @@ -49,6 +50,12 @@ export default { this.tryChangeVariant(this.$route.params["vname"]); }, methods: { + clickReadRules: function() { + if (this.display != "rules") + this.display = "rules"; + else if (this.gameInProgress) + this.display = "computer"; + }, parseFen(fen) { const fenParts = fen.split(" "); return { @@ -83,14 +90,18 @@ export default { this.gameInProgress = true; this.display = "computer"; this.gameInfo.mode = mode; - this.gameInfo.userStop = false; + this.gameInfo.score = "*"; this.gameInfo.fen = V.GenRandInitFen(); }, - stopGame: function() { - this.gameInProgress = false; - this.gameInfo.userStop = true; + // user is willing to stop the game: + stopGame: function(score) { + this.gameInfo.score = score || "?"; this.gameInfo.mode = "analyze"; }, + // The game is effectively stopped: + gameStopped: function() { + this.gameInProgress = false; + }, }, }; </script>