| 1 | <template lang="pug"> |
| 2 | .row |
| 3 | .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2 |
| 4 | BaseGame(:vname="vname" :analyze="analyze" |
| 5 | :vr="vr" :fen-start="fenStart" :players="players" :mycolor="mycolor" |
| 6 | ref="basegame" @newmove="processMove") |
| 7 | </template> |
| 8 | |
| 9 | <script> |
| 10 | import BaseGame from "@/components/BaseGame.vue"; |
| 11 | import { store } from "@/store"; |
| 12 | import Worker from 'worker-loader!@/playCompMove'; |
| 13 | |
| 14 | export default { |
| 15 | name: 'my-computer-game', |
| 16 | components: { |
| 17 | BaseGame, |
| 18 | }, |
| 19 | // mode: "auto" (game comp vs comp), "versus" (normal) or "analyze" |
| 20 | props: ["fen","mode","vname"], |
| 21 | data: function() { |
| 22 | return { |
| 23 | st: store.state, |
| 24 | // variables passed to BaseGame: |
| 25 | fenStart: "", |
| 26 | vr: null, |
| 27 | players: ["Myself","Computer"], //always playing white for now |
| 28 | mycolor: "w", |
| 29 | // Web worker to play computer moves without freezing interface: |
| 30 | timeStart: undefined, //time when computer starts thinking |
| 31 | lockCompThink: false, //to avoid some ghost moves |
| 32 | compWorker: null, |
| 33 | }; |
| 34 | }, |
| 35 | computed: { |
| 36 | analyze: function() { |
| 37 | return this.mode == "analyze"; |
| 38 | }, |
| 39 | }, |
| 40 | watch: { |
| 41 | fen: function() { |
| 42 | // (Security) No effect if a computer move is in progress: |
| 43 | if (this.lockCompThink) |
| 44 | return this.$emit("computer-think"); |
| 45 | this.launchGame(); |
| 46 | }, |
| 47 | }, |
| 48 | // Modal end of game, and then sub-components |
| 49 | created: function() { |
| 50 | // Computer moves web worker logic: (TODO: also for observers in HH games ?) |
| 51 | this.compWorker = new Worker(); //'/javascripts/playCompMove.js'), |
| 52 | this.compWorker.onmessage = e => { |
| 53 | this.lockCompThink = true; //to avoid some ghost moves |
| 54 | let compMove = e.data; |
| 55 | if (!Array.isArray(compMove)) |
| 56 | compMove = [compMove]; //to deal with MarseilleRules |
| 57 | // Small delay for the bot to appear "more human" |
| 58 | const delay = Math.max(500-(Date.now()-this.timeStart), 0); |
| 59 | setTimeout(() => { |
| 60 | const animate = (this.vname != "Dark"); |
| 61 | this.$refs.basegame.play(compMove[0], animate); |
| 62 | if (compMove.length == 2) |
| 63 | setTimeout( () => { this.$refs.basegame.play(compMove[1], animate); }, 750); |
| 64 | else //250 == length of animation (TODO: should be a constant somewhere) |
| 65 | setTimeout( () => this.lockCompThink = false, 250); |
| 66 | }, delay); |
| 67 | } |
| 68 | if (!!this.fen) |
| 69 | this.launchGame(); |
| 70 | }, |
| 71 | // dans variant.js (plutôt room.js) conn gère aussi les challenges |
| 72 | // et les chats dans chat.js. Puis en webRTC, repenser tout ça. |
| 73 | methods: { |
| 74 | launchGame: async function() { |
| 75 | const vModule = await import("@/variants/" + this.vname + ".js"); |
| 76 | window.V = vModule.VariantRules; |
| 77 | this.compWorker.postMessage(["scripts",this.vname]); |
| 78 | this.compWorker.postMessage(["init",this.fen]); |
| 79 | this.newGameFromFen(this.fen); |
| 80 | }, |
| 81 | newGameFromFen: function(fen) { |
| 82 | this.vr = new V(fen); |
| 83 | this.moves = []; |
| 84 | this.cursor = -1; |
| 85 | this.fenStart = fen; |
| 86 | this.score = "*"; |
| 87 | if (this.mode == "analyze") |
| 88 | { |
| 89 | this.mycolor = V.ParseFen(fen).turn; |
| 90 | this.orientation = this.mycolor; |
| 91 | } |
| 92 | else if (this.mode == "computer") //only other alternative (HH with gameId) |
| 93 | { |
| 94 | this.mycolor = (Math.random() < 0.5 ? "w" : "b"); |
| 95 | this.orientation = this.mycolor; |
| 96 | this.compWorker.postMessage(["init",fen]); |
| 97 | if (this.mycolor != "w" || this.mode == "auto") |
| 98 | this.playComputerMove(); |
| 99 | } |
| 100 | }, |
| 101 | playComputerMove: function() { |
| 102 | this.timeStart = Date.now(); |
| 103 | this.compWorker.postMessage(["askmove"]); |
| 104 | }, |
| 105 | // TODO: do not process if game is over (check score ?) |
| 106 | processMove: function(move) { |
| 107 | // Send the move to web worker (including his own moves) |
| 108 | this.compWorker.postMessage(["newmove",move]); |
| 109 | // subTurn condition for Marseille (and Avalanche) rules |
| 110 | if ((!this.vr.subTurn || this.vr.subTurn <= 1) |
| 111 | && (this.mode == "auto" || this.vr.turn != this.mycolor)) |
| 112 | { |
| 113 | this.playComputerMove(); |
| 114 | } |
| 115 | }, |
| 116 | }, |
| 117 | }; |
| 118 | </script> |