X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=client%2Fsrc%2Fcomponents%2FBaseGame.vue;h=d9540eb38b83b8bdf91beffe258e2d422fc0c3a2;hb=57d9b2c4f08948bd5a5fc4a01a0b62d4c80523e2;hp=e86c551e6bee8d282c2874d7327f97eef63b9dfa;hpb=3f22c2c3939dfd6bd66da26e6d6d9848c6da86d2;p=vchess.git diff --git a/client/src/components/BaseGame.vue b/client/src/components/BaseGame.vue index e86c551e..d9540eb3 100644 --- a/client/src/components/BaseGame.vue +++ b/client/src/components/BaseGame.vue @@ -30,6 +30,11 @@ div#baseGame img.inline(src="/images/icons/play_rev.svg") button(v-if="canFlip" @click="flip()") img.inline(src="/images/icons/flip.svg") + button( + @click="runAutoplay()" + :class="{'in-autoplay': autoplay}" + ) + img.inline(src="/images/icons/autoplay.svg") button(@click="play()") img.inline(src="/images/icons/play.svg") button(@click="gotoEnd()") @@ -83,41 +88,53 @@ export default { firstMoveNumber: 0, //for printing incheck: [], //for Board inMultimove: false, + autoplay: false, + autoplayLoop: null, inPlay: false, stackToPlay: [] }; }, computed: { + turn: function() { + if (!this.vr) return ""; + if (this.vr.showMoves != "all") { + return this.st.tr[ + (this.vr.turn == 'w' ? "White" : "Black") + " to move"]; + } + // Cannot flip: racing king or circular chess + return ( + this.vr.movesCount == 0 && this.game.mycolor == "w" + ? this.st.tr["It's your turn!"] + : "" + ); + }, + // TODO: is it OK to pass "computed" as propoerties? + // Also, some are seemingly not recomputed when vr is initialized. showMoves: function() { return this.game.score != "*" ? "all" - : (this.vr ? this.vr.showMoves : "none"); + : (!!this.vr ? this.vr.showMoves : "none"); }, showTurn: function() { return ( this.game.score == '*' && - this.vr && - (this.vr.showMoves != "all" || !this.vr.canFlip) + !!this.vr && (this.vr.showMoves != "all" || !this.vr.canFlip) ); }, - turn: function() { - if (!this.vr) - return ""; - if (this.vr.showMoves != "all") - return this.st.tr[(this.vr.turn == 'w' ? "White" : "Black") + " to move"] - // Cannot flip: racing king or circular chess - return this.vr.movesCount == 0 && this.game.mycolor == "w" - ? this.st.tr["It's your turn!"] - : ""; - }, canAnalyze: function() { - return this.game.mode != "analyze" && this.vr && this.vr.canAnalyze; + return ( + this.game.mode != "analyze" && + !!this.vr && this.vr.canAnalyze + ); }, canFlip: function() { - return this.vr && this.vr.canFlip; + return !!this.vr && this.vr.canFlip; }, allowDownloadPGN: function() { - return this.game.score != "*" || (this.vr && this.vr.showMoves == "all"); + return ( + this.game.score != "*" || + (!!this.vr && this.vr.showMoves == "all") + ); } }, created: function() { @@ -135,6 +152,9 @@ export default { document.getElementById("eogDiv") .addEventListener("click", processModalClick); }, + beforeDestroy: function() { + if (!!this.autoplayLoop) clearInterval(this.autoplayLoop); + }, methods: { focusBg: function() { document.getElementById("baseGame").focus(); @@ -263,6 +283,29 @@ export default { this.endgameMessage = message; 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 { + this.autoplay = true; + infinitePlay(); + this.autoplayLoop = setInterval(infinitePlay, 1500); + } + }, // Animate an elementary move animateMove: function(move, callback) { let startSquare = document.getElementById(getSquareId(move.start)); @@ -325,12 +368,15 @@ export default { this.vr.play(smove); this.lastMove = smove; if (!this.inMultimove) { - if (this.cursor < this.moves.length - 1) - this.moves = this.moves.slice(0, this.cursor + 1); - this.moves.push(smove); + // Condition is "!navigate" but we mean "!this.autoplay" + if (!navigate) { + if (this.cursor < this.moves.length - 1) + this.moves = this.moves.slice(0, this.cursor + 1); + this.moves.push(smove); + } this.inMultimove = true; //potentially this.cursor++; - } else { + } else if (!navigate) { // Already in the middle of a multi-move const L = this.moves.length; if (!Array.isArray(this.moves[L-1])) @@ -340,7 +386,10 @@ export default { } }; const playMove = () => { - const animate = (V.ShowMoves == "all" && !!received); + const animate = ( + ["all", "highlight"].includes(V.ShowMoves) && + (this.autoplay || !!received) + ); if (!Array.isArray(move)) move = [move]; let moveIdx = 0; let self = this; @@ -387,7 +436,7 @@ export default { this.emitFenIfAnalyze(); this.inMultimove = false; this.score = computeScore(); - if (this.game.mode != "analyze") { + if (this.game.mode != "analyze" && !navigate) { if (!noemit) { // Post-processing (e.g. computer play). const L = this.moves.length; @@ -408,22 +457,25 @@ export default { // The move to navigate to is necessarily full: if (this.cursor == this.moves.length - 1) return; //no more moves move = this.moves[this.cursor + 1]; - // Just play the move: - if (!Array.isArray(move)) move = [move]; - for (let i=0; i < move.length; i++) this.vr.play(move[i]); - if (!light) { - this.lastMove = move[move.length-1]; - this.incheck = this.vr.getCheckSquares(this.vr.turn); - this.score = computeScore(); - this.emitFenIfAnalyze(); + if (!this.autoplay) { + // Just play the move: + if (!Array.isArray(move)) move = [move]; + for (let i=0; i < move.length; i++) this.vr.play(move[i]); + if (!light) { + this.lastMove = move[move.length-1]; + this.incheck = this.vr.getCheckSquares(this.vr.turn); + this.score = computeScore(); + this.emitFenIfAnalyze(); + } + this.cursor++; + return; } - this.cursor++; - return; } // Forbid playing outside analyze mode, except if move is received. // Sufficient condition because Board already knows which turn it is. if ( this.game.mode != "analyze" && + !navigate && !received && (this.game.score != "*" || this.cursor < this.moves.length - 1) ) { @@ -541,8 +593,11 @@ export default { padding-top: 5px padding-bottom: 5px +.in-autoplay + background-color: #FACF8C + img.inline - height: 24px + height: 22px padding-top: 5px @media screen and (max-width: 767px) height: 18px