X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fcomponents%2FBaseGame.vue;h=3d8e7eb9d26465dab61785ecbfdd6e0f919b4ac7;hb=c1e3a8fd50e2ea1cf6652478744e354e812ec1bd;hp=a0bcef0a37e9c6c597a20aa795d122f721b66c01;hpb=07052665845283c65b50a76537669d0602ba436b;p=vchess.git diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index a0bcef0a..3d8e7eb9 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -40,7 +40,7 @@ div#baseGame img.inline(src="/images/icons/play.svg") button(@click="gotoEnd()") img.inline(src="/images/icons/fast-forward.svg") - p(v-show="showFen") {{ (!!vr ? vr.getFen() : "") }} + p#fenAnalyze(v-show="showFen") {{ (!!vr ? vr.getFen() : "") }} #movesList MoveList( :show="showMoves" @@ -94,7 +94,6 @@ export default { incheck: [], //for Board inMultimove: false, autoplay: false, - autoplayLoop: null, inPlay: false, stackToPlay: [] }; @@ -164,7 +163,8 @@ export default { .addEventListener("click", processModalClick); }, beforeDestroy: function() { - if (!!this.autoplayLoop) clearInterval(this.autoplayLoop); + // TODO: probably not required + this.autoplay = false; }, methods: { focusBg: function() { @@ -216,6 +216,10 @@ export default { const firstMoveColor = parsedFen.turn; this.firstMoveNumber = Math.floor(parsedFen.movesCount / 2) + 1; let L = this.moves.length; + if (L == 0) { + this.incheck = []; + this.score = "*"; + } this.moves.forEach((move,idx) => { // Strategy working also for multi-moves: if (!Array.isArray(move)) move = [move]; @@ -229,8 +233,8 @@ export default { if (idxM == Lm - 1) m.fen = this.vr.getFen(); if (idx == L - 1 && idxM == Lm - 1) { this.incheck = checkSquares; - const score = this.vr.getCurrentScore(); - if (["1-0", "0-1"].includes(score)) m.notation += "#"; + this.score = this.vr.getCurrentScore(); + if (["1-0", "0-1"].includes(this.score)) m.notation += "#"; } }); }); @@ -274,6 +278,9 @@ export default { fen = mv[mv.length-1].fen; } this.vr = new V(fen); + this.incheck = this.vr.getCheckSquares(); + if (this.cursor >= 0) this.lastMove = this.moves[this.cursor]; + else this.lastMove = null; document.getElementById("analyzeBtn").classList.remove("active"); } }, @@ -330,32 +337,15 @@ export default { document.getElementById("modalEog").checked = true; }, runAutoplay: function() { - const infinitePlay = () => { - if (this.cursor == this.moves.length - 1) { - clearInterval(this.autoplayLoop); - this.autoplayLoop = null; - this.autoplay = false; - return; - } - if (this.inPlay || this.inMultimove) - // Wait next tick - return; - this.play(); - }; if (this.autoplay) { this.autoplay = false; - clearInterval(this.autoplayLoop); - this.autoplayLoop = null; - } else { + if (this.stackToPlay.length > 0) + // Move(s) arrived in-between + this.play(this.stackToPlay.pop(), "received"); + } + else if (this.cursor < this.moves.length - 1) { this.autoplay = true; - setTimeout( - () => { - infinitePlay(); - this.autoplayLoop = setInterval(infinitePlay, 1500); - }, - // Small delay otherwise the first move is played too fast - 500 - ); + this.play(null, null, null, "autoplay"); } }, // Animate an elementary move @@ -414,20 +404,37 @@ export default { if (!!move) this.play(move); }, // "light": if gotoMove() or gotoEnd() - play: function(move, received, light, noemit) { + play: function(move, received, light, autoplay) { // Freeze while choices are shown: if (this.$refs["board"].choices.length > 0) return; - // The board may show some the possible moves: (TODO: bad solution) - this.$refs["board"].resetCurrentAttempt(); - if (!!noemit) { - if (this.inPlay) { - // Received moves in observed games can arrive too fast: + const navigate = !move; + // Forbid navigation during autoplay: + if (navigate && this.autoplay && !autoplay) return; + // Forbid playing outside analyze mode, except if move is received. + // Sufficient condition because Board already knows which turn it is. + if ( + this.mode != "analyze" && + !navigate && + !received && + (this.game.score != "*" || this.cursor < this.moves.length - 1) + ) { + return; + } + if (!!received) { + if (this.autoplay || this.inPlay) { + // Received moves while autoplaying are stacked, + // and in observed games they could arrive too fast: this.stackToPlay.unshift(move); return; } this.inPlay = true; + if (this.mode == "analyze") this.toggleAnalyze(); + if (this.cursor < this.moves.length - 1) + // To play a received move, cursor must be at the end of the game: + this.gotoEnd(); } - const navigate = !move; + // The board may show some the possible moves: (TODO: bad solution) + this.$refs["board"].resetCurrentAttempt(); const playSubmove = (smove) => { smove.notation = this.vr.getNotation(smove); smove.unambiguous = V.GetUnambiguousNotation(smove); @@ -475,8 +482,7 @@ export default { if (animate && smove.start.x >= 0) { self.animateMove(smove, () => { playSubmove(smove); - if (moveIdx < move.length) - setTimeout(executeMove, 500); + if (moveIdx < move.length) setTimeout(executeMove, 500); else afterMove(smove, initurn); }); } else { @@ -489,7 +495,7 @@ export default { const computeScore = () => { const score = this.vr.getCurrentScore(); if (!navigate) { - if (["1-0","0-1"].includes(score)) { + if (["1-0", "0-1"].includes(score)) { if (Array.isArray(this.lastMove)) { const L = this.lastMove.length; this.lastMove[L - 1].notation += "#"; @@ -497,9 +503,9 @@ export default { else this.lastMove.notation += "#"; } } - if (score != "*" && this.mode == "analyze") { + if (score != "*" && ["analyze", "versus"].includes(this.mode)) { const message = getScoreMessage(score); - // Just show score on screen (allow undo) + // Show score on screen this.showEndgameMsg(score + " . " + this.st.tr[message]); } return score; @@ -513,18 +519,27 @@ export default { this.emitFenIfAnalyze(); this.inMultimove = false; this.score = computeScore(); + if (this.autoplay) { + if (this.cursor < this.moves.length - 1) + setTimeout(() => this.play(null, null, null, "autoplay"), 1000); + else { + this.autoplay = false; + if (this.stackToPlay.length > 0) + // Move(s) arrived in-between + this.play(this.stackToPlay.pop(), "received"); + } + } if (this.mode != "analyze" && !navigate) { - if (!noemit) { + if (!received) { // Post-processing (e.g. computer play). const L = this.moves.length; - // NOTE: always emit the score, even in unfinished, - // to tell Game::processMove() that it's not a received move. + // NOTE: always emit the score, even in unfinished this.$emit("newmove", this.moves[L-1], { score: this.score }); } else { this.inPlay = false; if (this.stackToPlay.length > 0) // Move(s) arrived in-between - this.play(this.stackToPlay.pop(), received, light, noemit); + this.play(this.stackToPlay.pop(), "received"); } } } @@ -548,22 +563,6 @@ export default { return; } } - // Forbid playing outside analyze mode, except if move is received. - // Sufficient condition because Board already knows which turn it is. - if ( - this.mode != "analyze" && - !navigate && - !received && - (this.game.score != "*" || this.cursor < this.moves.length - 1) - ) { - return; - } - if (!!received) { - if (this.mode == "analyze") this.toggleAnalyze(); - if (this.cursor < this.moves.length - 1) - // To play a received move, cursor must be at the end of the game: - this.gotoEnd(); - } playMove(); }, cancelCurrentMultimove: function() { @@ -583,7 +582,7 @@ export default { // "light": if gotoMove() or gotoBegin() undo: function(move, light) { // Freeze while choices are shown: - if (this.$refs["board"].choices.length > 0) return; + if (this.$refs["board"].choices.length > 0 || this.autoplay) return; this.$refs["board"].resetCurrentAttempt(); if (this.inMultimove) { this.cancelCurrentMultimove(); @@ -608,7 +607,7 @@ export default { } }, gotoMove: function(index) { - if (this.$refs["board"].choices.length > 0) return; + if (this.$refs["board"].choices.length > 0 || this.autoplay) return; this.$refs["board"].resetCurrentAttempt(); if (this.inMultimove) this.cancelCurrentMultimove(); if (index == this.cursor) return; @@ -627,7 +626,7 @@ export default { this.emitFenIfAnalyze(); }, gotoBegin: function() { - if (this.$refs["board"].choices.length > 0) return; + if (this.$refs["board"].choices.length > 0 || this.autoplay) return; this.$refs["board"].resetCurrentAttempt(); if (this.inMultimove) this.cancelCurrentMultimove(); const minCursor = @@ -640,7 +639,7 @@ export default { this.emitFenIfAnalyze(); }, gotoEnd: function() { - if (this.$refs["board"].choices.length > 0) return; + if (this.$refs["board"].choices.length > 0 || this.autoplay) return; this.$refs["board"].resetCurrentAttempt(); if (this.cursor == this.moves.length - 1) return; this.gotoMove(this.moves.length - 1); @@ -657,6 +656,7 @@ export default {