.card.smallpad.small-modal.text-center
label.modal-close(for="modalEog")
h3#eogMessage.section {{ endgameMessage }}
- Board(:vr="vr" :last-move="lastMove" :analyze="analyze"
- :user-color="gameInfo.mycolor" :orientation="orientation"
- :vname="vname" @play-move="play")
+ Board(:vr="vr" :last-move="lastMove" :analyze="game.mode=='analyze'"
+ :user-color="game.mycolor" :orientation="orientation"
+ :vname="game.vname" @play-move="play")
.button-group
button(@click="() => play()") Play
button(@click="() => undo()") Undo
//MoveList,
},
// "vr": VariantRules object, describing the game state + rules
- // fenStart, players, mycolor
- props: ["vname","analyze","vr","gameInfo"],
+ props: ["vr","game"],
data: function() {
return {
st: store.state,
};
},
watch: {
- // gameInfo (immutable once set) changes when a new game starts
- "gameInfo": function() {
+ // game initial FEN changes when a new game starts
+ "game.fenStart": function() {
// Reset all variables
this.endgameMessage = "";
- this.orientation = this.gameInfo.mycolor || "w"; //default orientation for observed games
- this.score = this.gameInfo.score; //mutable (if initially "*")
- this.moves = this.gameInfo.moves; //TODO: this is mutable; make a copy instead
+ 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 || []));
const L = this.moves.length;
this.cursor = L-1;
this.lastMove = (L > 0 ? this.moves[L-1] : null);
},
- analyze: function() {
- if (this.analyze)
- {
- // Switched to analyze mode: game is over
- this.endGame("*");
- }
- },
},
computed: {
showMoves: function() {
//return window.innerWidth >= 768;
},
showFen: function() {
- return this.vname != "Dark" || this.score != "*";
+ return this.game.vname != "Dark" || this.score != "*";
+ },
+ analyze: function() {
+ return this.game.mode == "analyze";
},
},
methods: {
getPgn: function() {
let pgn = "";
pgn += '[Site "vchess.club"]\n';
- pgn += '[Variant "' + this.vname + '"]\n';
+ pgn += '[Variant "' + this.game.vname + '"]\n';
pgn += '[Date "' + getDate(new Date()) + '"]\n';
- pgn += '[White "' + this.gameInfo.players[0] + '"]\n';
- pgn += '[Black "' + this.gameInfo.players[1] + '"]\n';
- pgn += '[Fen "' + this.gameInfo.fenStart + '"]\n';
+ pgn += '[White "' + this.game.players[0] + '"]\n';
+ pgn += '[Black "' + this.game.players[1] + '"]\n';
+ pgn += '[Fen "' + this.game.fenStart + '"]\n';
pgn += '[Result "' + this.score + '"]\n\n';
let counter = 1;
let i = 0;
endGame: function(score) {
this.score = score;
this.showScoreMsg(score);
- this.$emit("game-over");
+ this.$emit("gameover"); //score not required (TODO?)
},
animateMove: function(move) {
let startSquare = document.getElementById(getSquareId(move.start));
this.lastMove = this.moves[index];
},
gotoBegin: function() {
- this.vr.re_init(this.fenStart);
+ this.vr.re_init(this.game.fenStart);
this.cursor = -1;
this.lastMove = null;
},
<template lang="pug">
.row
.col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
- BaseGame(:game="game" :vr="vr" ref="basegame" @newmove="processMove")
+ BaseGame(:game="game" :vr="vr" ref="basegame"
+ @newmove="processMove" @gameover="gameOver")
</template>
<script>
data: function() {
return {
st: store.state,
- // variables passed to BaseGame:
- fenStart: "",
- players: ["Myself","Computer"], //playing as white
- mycolor: "w",
+ game: { },
vr: null,
// Web worker to play computer moves without freezing interface:
timeStart: undefined, //time when computer starts thinking
compWorker: null,
};
},
- computed: {
- game: function() {
- return Object.assign({},
- this.gameInfo,
- {
- fenStart: this.fenStart,
- players: this.players,
- mycolor: this.mycolor,
- });
- },
- },
watch: {
- gameInfo: function() {
+ "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)
+ {
+ // User stopped the game: unknown result
+ this.game.mode = "analyze";
+ }
+ },
},
// Modal end of game, and then sub-components
created: function() {
setTimeout( () => this.lockCompThink = false, 250);
}, delay);
}
- if (!!this.fen)
+ if (!!this.gameInfo.fen)
this.launchGame();
},
// dans variant.js (plutôt room.js) conn gère aussi les challenges
const vModule = await import("@/variants/" + this.gameInfo.vname + ".js");
window.V = vModule.VariantRules;
this.compWorker.postMessage(["scripts",this.gameInfo.vname]);
- this.compWorker.postMessage(["init",this.gameInfo.fenStart]);
- this.newGameFromFen(this.gameInfo.fenStart);
- },
- newGameFromFen: function(fen) {
- this.vr = new V(fen);
- this.mycolor = (Math.random() < 0.5 ? "w" : "b");
- this.players = ["Myself","Computer"];
- if (this.mycolor == "b")
- this.players = this.players.reverse();
- this.compWorker.postMessage(["init",fen]);
- if (this.mycolor != "w" || this.gameInfo.mode == "auto")
+ 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"];
+ if (mycolor == "b")
+ players = players.reverse();
+ // NOTE: (TODO?) fen and fenStart are redundant in game object
+ this.game = Object.assign({},
+ this.gameInfo,
+ {
+ fenStart: this.gameInfo.fen,
+ players: players,
+ mycolor: mycolor,
+ });
+ this.compWorker.postMessage(["init",this.gameInfo.fen]);
+ if (mycolor != "w" || this.gameInfo.mode == "auto")
this.playComputerMove();
},
playComputerMove: function() {
this.compWorker.postMessage(["newmove",move]);
// subTurn condition for Marseille (and Avalanche) rules
if ((!this.vr.subTurn || this.vr.subTurn <= 1)
- && (this.mode == "auto" || this.vr.turn != this.mycolor))
+ && (this.gameInfo.mode == "auto" || this.vr.turn != this.game.mycolor))
{
this.playComputerMove();
}
},
+ // When game ends normally, just switch to analyze mode
+ gameOver: function() {
+ this.game.mode = "analyze";
+ },
},
};
</script>
.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(v-show="!gameInProgress" @click="watchComputerGame")
+ button(v-show="!gameInProgress" @click="() => startGame('auto')")
| Observe a sample game
- button(v-show="!gameInProgress" @click="playAgainstComputer")
+ button(v-show="!gameInProgress" @click="() => startGame('versus')")
| Beat the computer!
button(v-show="gameInProgress" @click="stopGame")
| Stop game
display: "rules",
gameInProgress: false,
// variables passed to ComputerGame:
- vname: "_unknown",
- mode: "versus",
- fen: "",
+ gameInfo: {
+ vname: "_unknown",
+ mode: "versus",
+ fen: "",
+ userStop: false,
+ }
};
},
- computed: {
- gameInfo: function() {
- return {
- fen: this.fen,
- mode: this.mode,
- vname: this.vname,
- };
- },
- },
watch: {
"$route": function(newRoute) {
this.tryChangeVariant(newRoute.params["vname"]);
tryChangeVariant: async function(vname) {
if (!vname || vname == "_unknown")
return;
- this.vname = vname;
+ this.gameInfo.vname = vname;
const vModule = await import("@/variants/" + vname + ".js");
window.V = vModule.VariantRules;
// Method to replace diagrams in loaded HTML
require("raw-loader!@/rules/" + vname + "/" + this.st.lang + ".pug")
.replace(/(fen:)([^:]*):/g, replaceByDiag);
},
- startGame: function() {
+ startGame: function(mode) {
if (this.gameInProgress)
return;
this.gameInProgress = true;
this.display = "computer";
- this.fen = V.GenRandInitFen();
+ this.gameInfo.mode = mode;
+ this.gameInfo.userStop = false;
+ this.gameInfo.fen = V.GenRandInitFen();
},
stopGame: function() {
this.gameInProgress = false;
- this.mode = "analyze";
- },
- playAgainstComputer: function() {
- this.mode = "versus";
- this.startGame();
- },
- watchComputerGame: function() {
- this.mode = "auto";
- this.startGame();
+ this.gameInfo.userStop = true;
+ this.gameInfo.mode = "analyze";
},
},
};