X-Git-Url: https://git.auder.net/?a=blobdiff_plain;f=public%2Fjavascripts%2Fcomponents%2Fgame.js;h=ded309186a15647eec972086ff08ed5b8008a7c7;hb=c794dbb87592782913af0a09784ed25e019e4d10;hp=d76ab0117d828a3722ac2568b409f9c0c6aaf372;hpb=32cfcea44bf00b0c6c4d172cca715823076ff490;p=vchess.git diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js index d76ab011..ded30918 100644 --- a/public/javascripts/components/game.js +++ b/public/javascripts/components/game.js @@ -1,5 +1,6 @@ // Game logic on a variant page Vue.component('my-game', { + props: ["problem"], data: function() { return { vr: null, //object to check moves, store them, FEN.. @@ -23,10 +24,18 @@ Vue.component('my-game', { sound: parseInt(getCookie("sound", "2")), }; }, + watch: { + problem: function(p, pp) { + // 'problem' prop changed: update board state + // TODO: FEN + turn + flags + rappel instructions / solution on click sous l'échiquier + // TODO: trouver moyen de passer la situation des reserves pour Crazyhouse, + // et l'état des captures pour Grand... bref compléter le descriptif de l'état. + this.newGame("problem", p.fen, p.fen.split(" ")[2]); + }, + }, render(h) { - const [sizeX,sizeY] = VariantRules.size; - console.log(sizeX + " " + sizeY); - const smallScreen = (screen.width <= 420); + const [sizeX,sizeY] = [V.size.x,V.size.y]; + const smallScreen = (window.innerWidth <= 420); // Precompute hints squares to facilitate rendering let hintSquares = doubleArray(sizeX, sizeY, false); this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; }); @@ -410,7 +419,7 @@ Vue.component('my-game', { }), h('div', { - attrs: { "role": "dialog", "aria-labelledby": "modal-eog" }, + attrs: { "role": "dialog", "aria-labelledby": "eogMessage" }, }, [ h('div', @@ -426,6 +435,7 @@ Vue.component('my-game', { ), h('h3', { + attrs: { "id": "eogMessage" }, "class": { "section": true }, domProps: { innerHTML: eogMessage }, } @@ -446,7 +456,7 @@ Vue.component('my-game', { }), h('div', { - attrs: { "role": "dialog", "aria-labelledby": "modal-newgame" }, + attrs: { "role": "dialog", "aria-labelledby": "newGameTxt" }, }, [ h('div', @@ -462,6 +472,7 @@ Vue.component('my-game', { ), h('h3', { + attrs: { "id": "newGameTxt" }, "class": { "section": true }, domProps: { innerHTML: "New game" }, } @@ -486,7 +497,7 @@ Vue.component('my-game', { }), h('div', { - attrs: { "role": "dialog", "aria-labelledby": "modal-fenedit" }, + attrs: { "role": "dialog", "aria-labelledby": "titleFenedit" }, }, [ h('div', @@ -502,6 +513,7 @@ Vue.component('my-game', { ), h('h3', { + attrs: { "id": "titleFenedit" }, "class": { "section": true }, domProps: { innerHTML: "Position + flags (FEN):" }, } @@ -552,7 +564,7 @@ Vue.component('my-game', { }), h('div', { - attrs: { "role": "dialog", "aria-labelledby": "modal-settings" }, + attrs: { "role": "dialog", "aria-labelledby": "settingsTitle" }, }, [ h('div', @@ -568,6 +580,7 @@ Vue.component('my-game', { ), h('h3', { + attrs: { "id": "settingsTitle" }, "class": { "section": true }, domProps: { innerHTML: "Preferences" }, } @@ -780,7 +793,7 @@ Vue.component('my-game', { created: function() { const url = socketUrl; const continuation = (localStorage.getItem("variant") === variant); - this.myid = continuation ? localStorage.getItem("myid") : getRandString(); + this.myid = (continuation ? localStorage.getItem("myid") : getRandString()); if (!continuation) { // HACK: play a small silent sound to allow "new game" sound later @@ -809,6 +822,12 @@ Vue.component('my-game', { const data = JSON.parse(msg.data); switch (data.code) { + case "duplicate": + // We opened another tab on the same game + this.mode = "idle"; + this.vr = null; + alert("Already playing a game in this variant on another tab!"); + break; case "newgame": //opponent found // oppid: opponent socket ID this.newGame("human", data.fen, data.color, data.oppid); @@ -1015,10 +1034,7 @@ Vue.component('my-game', { { const storageVariant = localStorage.getItem("variant"); if (!!storageVariant && storageVariant !== variant) - { - alert("Finish your " + storageVariant + " game first!"); - return; - } + return alert("Finish your " + storageVariant + " game first!"); // Send game request and wait.. localStorage["newgame"] = variant; this.seek = true; @@ -1052,7 +1068,7 @@ Vue.component('my-game', { document.getElementById("modal-newgame").checked = false; } this.oppid = oppId; - this.oppConnected = true; + this.oppConnected = !continuation; this.mycolor = color; this.seek = false; if (!!moves && moves.length > 0) //imply continuation @@ -1071,14 +1087,17 @@ Vue.component('my-game', { if (this.mycolor == 'b') setTimeout(this.playComputerMove, 500); } - //else: against a (IRL) friend: nothing more to do + //else: against a (IRL) friend or problem solving: nothing more to do }, playComputerMove: function() { const timeStart = Date.now(); const compMove = this.vr.getComputerMove(); // (first move) HACK: avoid selecting elements before they appear on page: const delay = Math.max(500-(Date.now()-timeStart), 0); - setTimeout(() => this.play(compMove, "animate"), delay); + setTimeout(() => { + if (this.mode == "computer") //Warning: mode could have changed! + this.play(compMove, "animate") + }, delay); }, // Get the identifier of a HTML table cell from its numeric coordinates o.x,o.y. getSquareId: function(o) { @@ -1121,8 +1140,9 @@ Vue.component('my-game', { this.selectedPiece.style.display = "inline-block"; this.selectedPiece.style.zIndex = 3000; let startSquare = this.getSquareFromId(e.target.parentNode.id); - const iCanPlay = this.mode!="idle" - && (this.mode=="friend" || this.vr.canIplay(this.mycolor,startSquare)); + const iCanPlay = this.mode!="idle" && + (["friend","problem"].includes(this.mode) || + this.vr.canIplay(this.mycolor,startSquare)); this.possibleMoves = iCanPlay ? this.vr.getPossibleMovesFrom(startSquare) : []; // Next line add moving piece just after current image // (required for Crazyhouse reserve)