Add debug trace for Hiddenqueen
[vchess.git] / client / src / components / ComputerGame.vue
index a5e03b3..605b3b1 100644 (file)
@@ -2,15 +2,16 @@
 BaseGame(
   ref="basegame"
   :game="game"
-  :vr="vr"
   @newmove="processMove"
-  @gameover="gameOver"
 )
 </template>
 
 <script>
 import BaseGame from "@/components/BaseGame.vue";
 import { store } from "@/store";
+import { CompgameStorage } from "@/utils/compgameStorage";
+import { getScoreMessage } from "@/utils/scoring";
+import { playMove, getFilteredMove } from "@/utils/playUndo";
 import Worker from "worker-loader!@/playCompMove";
 export default {
   name: "my-computer-game",
@@ -31,62 +32,63 @@ export default {
       compWorker: null
     };
   },
-  watch: {
-    "gameInfo.fen": function() {
-      this.launchGame();
-    },
-  },
   created: function() {
     // Computer moves web worker logic:
     this.compWorker = new Worker();
     this.compWorker.onmessage = e => {
       let compMove = e.data;
-      if (!compMove) {
-        this.compThink = false;
-        this.$emit("game-stopped"); //no more moves: mate or stalemate
-        return; //after game ends, no more moves, nothing to do
-      }
-      if (!Array.isArray(compMove)) compMove = [compMove]; //potential multi-move
       // Small delay for the bot to appear "more human"
-      const delay = Math.max(500 - (Date.now() - this.timeStart), 0);
+      const minDelay = this.gameInfo.mode == "versus" ? 500 : 1000;
+      const delay = Math.max(minDelay - (Date.now() - this.timeStart), 0);
+      let self = this;
       setTimeout(() => {
         if (this.currentUrl != document.location.href) return; //page change
-        // NOTE: do not animate move if special display (ShowMoves != "all")
-        const animate = V.ShowMoves == "all";
-        const animDelay = animate ? 250 : 0;
-        let moveIdx = 0;
-        let self = this;
-        (function executeMove() {
-          self.$refs["basegame"].play(compMove[moveIdx++], "received");
-          if (moveIdx >= compMove.length) {
+        self.$refs["basegame"].play(compMove, "received");
+        const animationLength =
+          // 250 = length of animation, 500 = delay between sub-moves
+          // TODO: a callback would be cleaner.
+          250 + (Array.isArray(compMove) ? (compMove.length - 1) * 750 : 0);
+        setTimeout(
+          () => {
             self.compThink = false;
-            if (self.game.score != "*")
-              //user action
-              self.$emit("game-stopped");
-          } else setTimeout(executeMove, 500 + animDelay);
-        })();
+            self.processMove(compMove);
+          },
+          animationLength
+        );
       }, 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(this.st.settings.randomness),
+          moves: []
+        };
+        game.fen = game.fenStart;
+        if (this.gameInfo.mode == "versus") CompgameStorage.add(game);
+      }
+
+// TODO: debug Hiddenqueen
+//game.fen = "rbnqbknr/pppptppp/8/8/8/8/TPPPPPPP/RBNQBKNR w 0 ahah -";
+//game.fenStart = "rbnqbknr/pppptppp/8/8/8/8/TPPPPPPP/RBNQBKNR w 0 ahah -";
+//game.mycolor = 'w';
+
+      if (!game.mycolor) game.mycolor = (Math.random() < 0.5 ? "w" : "b");
+      this.compWorker.postMessage(["init", game.fen]);
+      this.vr = new V(game.fen);
+      game.players = [{ name: "Computer" }, { name: "Computer" }];
+      if (this.gameInfo.mode == "versus")
+        game.players[game.mycolor == 'w' ? 0 : 1] = { name: "Myself" };
+      game.score = "*"; //finished games are removed
+      game.mode = this.gameInfo.mode;
       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.$refs["basegame"].re_setVariables(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,
@@ -96,22 +98,36 @@ export default {
       this.compThink = true;
       this.compWorker.postMessage(["askmove"]);
     },
-    processMove: function(move) {
-      if (this.game.score != "*") return;
+    processMove: function(move, scoreObj) {
+      playMove(move, this.vr);
+      // Maybe the user stopped the game:
+      if (this.game.score != "*") {
+        this.$emit("game-stopped");
+        return;
+      }
+      // This move could have ended the game
+      if (!scoreObj) scoreObj = { score: this.vr.getCurrentScore() };
+      if (scoreObj.score != "*") {
+        this.gameOver(scoreObj.score);
+        return;
+      }
       // Send the move to web worker (including his own moves)
       this.compWorker.postMessage(["newmove", move]);
-      // subTurn condition for Marseille (and Avalanche) rules
-      if (
-        (!this.vr.subTurn || this.vr.subTurn <= 1) &&
-        (this.gameInfo.mode == "auto" || this.vr.turn != this.game.mycolor)
-      ) {
+      if (this.gameInfo.mode == "auto" || this.vr.turn != this.game.mycolor)
         this.playComputerMove();
+      // Finally, update storage:
+      if (this.gameInfo.mode == "versus") {
+        CompgameStorage.update(this.gameInfo.vname, {
+          move: getFilteredMove(move),
+          fen: this.vr.getFen()
+        });
       }
     },
-    gameOver: function(score, scoreMsg) {
+    gameOver: function(score) {
       this.game.score = score;
-      this.game.scoreMsg = scoreMsg;
-      if (!this.compThink) this.$emit("game-stopped"); //otherwise wait for comp
+      this.game.scoreMsg = getScoreMessage(score);
+      // If comp is thinking, let him finish:
+      if (!this.compThink) this.$emit("game-stopped");
     }
   }
 };