<script>
import BaseGame from "@/components/BaseGame.vue";
import { store } from "@/store";
+import { CompgameStorage } from "@/utils/compgameStorage";
import Worker from "worker-loader!@/playCompMove";
export default {
name: "my-computer-game",
compWorker: null
};
},
- watch: {
- "gameInfo.fen": function() {
- this.launchGame();
- },
- },
created: function() {
// Computer moves web worker logic:
this.compWorker = new Worker();
let moveIdx = 0;
let self = this;
(function executeMove() {
+ // NOTE: BaseGame::play() will trigger processMove() here
self.$refs["basegame"].play(compMove[moveIdx++], "received");
if (moveIdx >= compMove.length) {
self.compThink = false;
if (self.game.score != "*")
- //user action
+ // User action
self.$emit("game-stopped");
} else setTimeout(executeMove, 500 + animDelay);
})();
}, delay);
};
- if (this.gameInfo.fen) this.launchGame();
},
methods: {
- launchGame: function() {
+ launchGame: function(game) {
this.compWorker.postMessage(["scripts", this.gameInfo.vname]);
- this.compWorker.postMessage(["init", this.gameInfo.fen]);
- this.vr = new V(this.gameInfo.fen);
- const mycolor = Math.random() < 0.5 ? "w" : "b";
- let players = [{ name: "Myself" }, { name: "Computer" }];
- if (mycolor == "b") players = players.reverse();
+ if (!game) {
+ game = {
+ vname: this.gameInfo.vname,
+ fenStart: V.GenRandInitFen(),
+ mycolor: Math.random() < 0.5 ? "w" : "b",
+ moves: []
+ };
+ game.fen = game.fenStart;
+ if (this.gameInfo.mode == "versus")
+ CompgameStorage.add(game);
+ }
+ this.compWorker.postMessage(["init", game.fen]);
+ this.vr = new V(game.fen);
+ game.players = [{ name: "Myself" }, { name: "Computer" }];
+ if (game.myColor == "b") game.players = game.players.reverse();
+ game.score = "*"; //finished games are removed
this.currentUrl = document.location.href; //to avoid playing outside page
- // NOTE: fen and fenStart are redundant in game object
- this.game = Object.assign({}, this.gameInfo, {
- fenStart: this.gameInfo.fen,
- players: players,
- mycolor: mycolor,
- score: "*"
- });
- this.compWorker.postMessage(["init", this.gameInfo.fen]);
- if (mycolor != "w" || this.gameInfo.mode == "auto")
+ this.game = game;
+ this.compWorker.postMessage(["init", game.fen]);
+ if (this.gameInfo.mode == "auto" || game.mycolor != this.vr.turn)
this.playComputerMove();
},
// NOTE: a "goto" action could lead to an error when comp is thinking,
) {
this.playComputerMove();
}
+ // Finally, update storage:
+ if (this.gameInfo.mode == "versus") {
+ const allowed_fields = ["appear", "vanish", "start", "end"];
+ const filtered_move = Object.keys(move)
+ .filter(key => allowed_fields.includes(key))
+ .reduce((obj, key) => {
+ obj[key] = move[key];
+ return obj;
+ }, {});
+ CompgameStorage.update(this.gameInfo.vname, {
+ move: filtered_move,
+ fen: move.fen
+ });
+ }
},
gameOver: function(score, scoreMsg) {
this.game.score = score;
h3 Histoire
p.
- Ce site est né à la suite d'une discussion avec Patrick bernier, qui m'avait
+ Ce site est né à la suite d'une discussion avec Patrick Bernier, qui m'avait
parlé d'une variante de son invention : l'Échiqueté ('Checkered' ici),
impliquant des pièces pouvant être jouées par les deux camps.
À l'époque en 2012, j'ai développé un premier petit site
--- /dev/null
+// (Comp)Game object: {
+// // Static informations:
+// vname: string (this is the ID)
+// fenStart: string,
+// mycolor: "w" or "b"
+// // Game (dynamic) state:
+// fen: string,
+// moves: array of Move objects,
+// }
+
+import { store } from "@/store";
+
+function dbOperation(callback) {
+ let db = null;
+ let DBOpenRequest = window.indexedDB.open("vchess_comp", 4);
+
+ DBOpenRequest.onerror = function(event) {
+ alert(store.state.tr["Database error: stop private browsing, or update your browser"]);
+ callback("error",null);
+ };
+
+ DBOpenRequest.onsuccess = function(event) {
+ db = DBOpenRequest.result;
+ callback(null,db);
+ db.close();
+ };
+
+ DBOpenRequest.onupgradeneeded = function(event) {
+ let db = event.target.result;
+ let objectStore = db.createObjectStore("compgames", { keyPath: "vname" });
+ };
+}
+
+export const CompgameStorage = {
+ add: function(game) {
+ dbOperation((err,db) => {
+ if (err)
+ return;
+ let transaction = db.transaction("compgames", "readwrite");
+ let objectStore = transaction.objectStore("compgames");
+ objectStore.add(game);
+ });
+ },
+
+ // obj: move and/or fen
+ update: function(gameId, obj) {
+ dbOperation((err,db) => {
+ let objectStore = db
+ .transaction("compgames", "readwrite")
+ .objectStore("compgames");
+ objectStore.get(gameId).onsuccess = function(event) {
+ // Ignoring error silently: shouldn't happen now. TODO?
+ if (event.target.result) {
+ const game = event.target.result;
+ Object.keys(obj).forEach(k => {
+ if (k == "move") game.moves.push(obj[k]);
+ else game[k] = obj[k];
+ });
+ objectStore.put(game); //save updated data
+ }
+ };
+ });
+ },
+
+ // Retrieve any game from its identifier (variant name)
+ // NOTE: need callback because result is obtained asynchronously
+ get: function(gameId, callback) {
+ dbOperation((err,db) => {
+ let objectStore = db.transaction("compgames").objectStore("compgames");
+ objectStore.get(gameId).onsuccess = function(event) {
+ callback(event.target.result);
+ };
+ });
+ },
+
+ // Delete a game in indexedDB
+ remove: function(gameId) {
+ dbOperation((err,db) => {
+ if (!err) {
+ let transaction = db.transaction(["compgames"], "readwrite");
+ transaction.objectStore("compgames").delete(gameId);
+ }
+ });
+ }
+};
// cadence: string,
// increment: integer (seconds),
// type: string ("live" or "corr")
-// imported: boolean (optional, default false)
// // Game (dynamic) state:
// fen: string,
// moves: array of Move objects,
import ComputerGame from "@/components/ComputerGame.vue";
import { store } from "@/store";
import { getDiagram } from "@/utils/printDiagram";
+import { CompgameStorage } from "@/utils/compgameStorage";
export default {
name: "my-rules",
components: {
gameInfo: {
vname: "",
mode: "versus",
- fen: ""
}
};
},
this.gameInProgress = true;
this.display = "computer";
this.gameInfo.mode = mode;
- this.$set(this.gameInfo, "fen", V.GenRandInitFen());
+ if (this.gameInfo.mode == "versus") {
+ CompgameStorage.get(this.gameInfo.vname, (game) => {
+ // NOTE: game might be null
+ this.$refs["compgame"].launchGame(game);
+ });
+ } else {
+ this.$refs["compgame"].launchGame();
+ }
},
- // user is willing to stop the game:
+ // user wants to stop the game:
stopGame: function() {
this.$refs["compgame"].gameOver("?", "Undetermined result");
},
// The game is effectively stopped:
gameStopped: function() {
this.gameInProgress = false;
+ if (this.gameInfo.mode == "versus")
+ CompgameStorage.remove(this.gameInfo.vname);
},
gotoAnalyze: function() {
this.$router.push(