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