:firstNum="firstMoveNumber"
:moves="moves"
:cursor="cursor"
+ :vname="game.vname"
@download="download"
@showrules="showRules"
@analyze="toggleAnalyze"
endgameMessage: "",
orientation: "w",
mode: "",
+ gameMode: "",
score: "*", //'*' means 'unfinished'
moves: [],
cursor: -1, //index of the move just played
lastMove: null,
+ touchLastClick: "",
firstMoveNumber: 0, //for printing
incheck: [], //for Board
inMultimove: false,
},
canAnalyze: function() {
return (
- !!this.game.mode && this.game.mode != "analyze" &&
+ (!this.game.mode || this.game.mode != "analyze") &&
!!this.vr && this.vr.canAnalyze
);
},
baseGameDiv.tabIndex = 0;
baseGameDiv.addEventListener("click", this.focusBg);
baseGameDiv.addEventListener("keydown", this.handleKeys);
- baseGameDiv.addEventListener("wheel", this.handleScroll);
+ if (this.st.settings.scrollmove)
+ baseGameDiv.addEventListener("wheel", this.handleScroll);
}
document.getElementById("eogDiv")
.addEventListener("click", processModalClick);
const firstMoveColor = parsedFen.turn;
this.firstMoveNumber = Math.floor(parsedFen.movesCount / 2) + 1;
let L = this.moves.length;
- if (L == 0) {
- // Could be started on a random position in analysis mode:
- this.incheck = this.vr.getCheckSquares();
- this.score = this.vr.getCurrentScore();
- if (this.score != '*') {
- // Show score on screen
- const message = getScoreMessage(this.score);
- this.showEndgameMsg(this.score + " . " + this.st.tr[message]);
- }
- }
- else {
- this.moves.forEach((move,idx) => {
- // Strategy working also for multi-moves:
- if (!Array.isArray(move)) move = [move];
- const Lm = move.length;
- move.forEach((m,idxM) => {
- m.notation = this.vr.getNotation(m);
- m.unambiguous = V.GetUnambiguousNotation(m);
- this.vr.play(m);
- const checkSquares = this.vr.getCheckSquares();
- if (checkSquares.length > 0) m.notation += "+";
- if (idxM == Lm - 1) m.fen = this.vr.getFen();
- if (idx == L - 1 && idxM == Lm - 1) {
- this.incheck = checkSquares;
- this.score = this.vr.getCurrentScore();
- if (["1-0", "0-1"].includes(this.score)) m.notation += "#";
- }
- });
+ this.moves.forEach((move,idx) => {
+ // Strategy working also for multi-moves:
+ if (!Array.isArray(move)) move = [move];
+ move.forEach(m => {
+ m.notation = this.vr.getNotation(m);
+ m.unambiguous = V.GetUnambiguousNotation(m);
+ this.vr.play(m);
});
+ const Lm = move.length;
+ move[Lm - 1].fen = this.vr.getFen();
+ if (idx < L - 1 && this.vr.getCheckSquares().length > 0)
+ move[Lm - 1].notation += "+";
+ });
+ this.incheck = this.vr.getCheckSquares();
+ this.score = this.vr.getCurrentScore();
+ if (L >= 1) {
+ const move =
+ !Array.isArray(this.moves[L - 1])
+ ? [this.moves[L - 1]]
+ : this.moves[L - 1];
+ const Lm = move.length;
+ if (["1-0", "0-1"].includes(this.score)) move[Lm - 1].notation += "#";
+ else if (this.incheck.length > 0) move[Lm - 1].notation += "+";
+ }
+ if (this.score != '*') {
+ // Show score on screen
+ const message = getScoreMessage(this.score);
+ this.showEndgameMsg(this.score + " . " + this.st.tr[message]);
}
if (firstMoveColor == "b") {
// 'start' & 'end' is required for Board component
}
if (this.mode != "analyze") {
// Enter analyze mode:
+ this.gameMode = this.mode; //was not 'analyze'
this.mode = "analyze";
if (this.inMultimove) this.cancelCurrentMultimove();
- this.gameMode = this.mode; //was not 'analyze'
this.gameCursor = this.cursor;
this.gameMoves = JSON.parse(JSON.stringify(this.moves));
document.getElementById("analyzeBtn").classList.add("active");
}
else {
// Exit analyze mode:
- this.mode = this.gameMode ;
+ this.mode = this.gameMode;
this.cursor = this.gameCursor;
this.moves = this.gameMoves;
let fen = this.game.fenStart;
pgn += '[Url "' + params.serverUrl + '/game/' + this.game.id + '"]\n';
if (!!this.game.cadence)
pgn += '[Cadence "' + this.game.cadence + '"]\n';
+ pgn += '[Options "' + JSON.stringify(this.game.options) + '"]\n';
pgn += '\n';
for (let i = 0; i < this.moves.length; i += 2) {
if (i > 0) pgn += " ";
},
clickSquare: function(square) {
// Some variants make use of a single click at specific times:
- const move = this.vr.doClick(square);
- if (!!move) this.play(move);
+ const move_s = this.vr.doClick(square);
+ if (!!move_s) {
+ const playMove = () => {
+ if (!Array.isArray(move_s)) this.play(move_s);
+ else this.$refs["board"].choices = move_s;
+ }
+ if ("ontouchstart" in window) {
+ const squareId = "sq-" + square[0] + "-" + square[1];
+ const highlight = function(on, sq) {
+ let elt = document.getElementById(sq);
+ if (!!elt) {
+ if (on) elt.classList.add("touch-hover");
+ else elt.classList.remove("touch-hover");
+ }
+ }
+ // Touch screen (smartphone): require confirmation
+ const squareStr = square[0] + "_" + square[1]
+ if (this.touchLastClick == squareId) {
+ highlight(false, squareId);
+ playMove();
+ }
+ else {
+ highlight(true, squareId);
+ highlight(false, this.touchLastClick);
+ }
+ this.touchLastClick = squareId;
+ }
+ else playMove();
+ }
},
// "light": if gotoMove() or gotoEnd()
play: function(move, received, light, autoplay) {
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();
+ this.inPlay = true;
}
// The board may show some possible moves: (TODO: bad solution)
this.$refs["board"].resetCurrentAttempt();
this.lastMove = [this.lastMove, smove];
else this.lastMove.push(smove);
}
- // Is opponent (or me) in check?
- this.incheck = this.vr.getCheckSquares();
- if (this.incheck.length > 0) smove.notation += "+";
if (!this.inMultimove) {
// First sub-move:
this.lastMove = smove;
}
this.inMultimove = true; //potentially
this.cursor++;
- } else if (!navigate) {
+ }
+ else if (!navigate) {
// Already in the middle of a multi-move
const L = this.moves.length;
if (!Array.isArray(this.moves[L-1]))
(function executeMove() {
const smove = move[moveIdx++];
// NOTE: condition "smove.start.x >= 0" required for Dynamo,
- // because second move may be empty.
- if (animate && smove.start.x >= 0) {
+ // because second move may be empty. noHighlight condition
+ // is used at least for Chakart.
+ if (animate && smove.start.x >= 0 && !smove.end.noHighlight) {
self.animateMove(smove, () => {
playSubmove(smove);
if (moveIdx < move.length) setTimeout(executeMove, 500);
else afterMove(smove, initurn);
});
- } else {
+ }
+ else {
playSubmove(smove);
if (moveIdx < move.length) executeMove();
else afterMove(smove, initurn);
}
}
if (score != "*" && ["analyze", "versus"].includes(this.mode)) {
- const message = getScoreMessage(score);
+ const message = getScoreMessage(score, V.ReverseColors);
// Show score on screen
this.showEndgameMsg(score + " . " + this.st.tr[message]);
}
smove.fen = this.vr.getFen();
this.emitFenIfAnalyze();
this.inMultimove = false;
+ this.incheck = this.vr.getCheckSquares();
+ if (this.incheck.length > 0) smove.notation += "+";
this.score = computeScore();
if (this.autoplay) {
if (this.cursor < this.moves.length - 1)
const L = this.moves.length;
// NOTE: always emit the score, even in unfinished
this.$emit("newmove", this.moves[L-1], { score: this.score });
- } else {
+ }
+ else {
this.inPlay = false;
if (this.stackToPlay.length > 0)
// Move(s) arrived in-between
this.incheck = this.vr.getCheckSquares();
if (this.cursor >= 0) this.lastMove = this.moves[this.cursor];
else this.lastMove = null;
- } else {
+ }
+ else {
if (!move) {
const minCursor =
this.moves.length > 0 && this.moves[0].notation == "..."