diff options
| author | Maks Jopek <maksymilian.jopek@prym-soft.pl> | 2021-04-29 20:05:06 +0200 |
|---|---|---|
| committer | Maks Jopek <maksymilian.jopek@prym-soft.pl> | 2021-04-29 20:05:06 +0200 |
| commit | 040d5372c1033bb7c0580ad2c9b6b32f974a20c8 (patch) | |
| tree | e452aa8ad583607b87d47ef82eabf0bd7e3ab60a /frontend/ts | |
| parent | 6baaa14bde032afa363dbdd50119a20e9f47df1c (diff) | |
| download | fia-040d5372c1033bb7c0580ad2c9b6b32f974a20c8.tar.gz fia-040d5372c1033bb7c0580ad2c9b6b32f974a20c8.tar.zst fia-040d5372c1033bb7c0580ad2c9b6b32f974a20c8.zip | |
Version 1.0
Diffstat (limited to 'frontend/ts')
| -rw-r--r-- | frontend/ts/gameBoard.ts | 25 | ||||
| -rw-r--r-- | frontend/ts/gameTable.ts | 1 | ||||
| -rw-r--r-- | frontend/ts/ghost.ts | 25 | ||||
| -rw-r--r-- | frontend/ts/logic.ts | 213 | ||||
| -rw-r--r-- | frontend/ts/login.ts | 17 | ||||
| -rw-r--r-- | frontend/ts/startGame.ts | 113 | ||||
| -rw-r--r-- | frontend/ts/timer.ts | 1 |
7 files changed, 228 insertions, 167 deletions
diff --git a/frontend/ts/gameBoard.ts b/frontend/ts/gameBoard.ts index 14ccac6..fc8cec7 100644 --- a/frontend/ts/gameBoard.ts +++ b/frontend/ts/gameBoard.ts @@ -1,4 +1,4 @@ -import { Coordinates, GameBoard, HomesOrBases, tColors } from "../../helpers/helpersBack"; +import { Coordinates, GameBoard, HomesOrBases, OldTd, tColors } from "../../helpers/helpersBack"; import gameTable from "./gameTable.js"; import StartGame from "./startGame.js"; @@ -24,6 +24,7 @@ export default class gameBoardClass { } } } + static removeGameBoard(gameBoard: GameBoard): void { for (let square of gameBoard.map) { gameBoardClass.removeChequer({ x: square.x, y: square.y }, true); @@ -47,15 +48,19 @@ export default class gameBoardClass { td.onclick = () => null; } - static showChequer(coords: Coordinates, color: tColors): void { + static showChequer(coords: Coordinates, color: tColors, oldColor = 'void'): void { let td = gameTable.getTd(coords); if (td.dataset.count === undefined) throw new Error("td.dataset.count is undefined!!!") - - if(td.className === '') + + if (td.className === '') td.classList.add("chequer"); - - if (td.dataset.count === '0') { + + if (color === 4 && !td.className.includes(oldColor) && !td.className.includes('pink')) { + td.className = 'chequer chequer-' + StartGame.colors[color]; + td.innerHTML = ''; + td.dataset.count = '1'; + } else if (td.dataset.count === '0') { td.classList.add("chequer-" + StartGame.colors[color]); td.dataset.count = '1'; td.innerHTML = ''; @@ -64,13 +69,17 @@ export default class gameBoardClass { td.innerHTML = td.dataset.count === '1' ? '' : 'x' + td.dataset.count; } } - static hideChequer(coords: Coordinates, all = false) { + static hideChequer(coords: Coordinates, all = false, oldTd: OldTd = { className: '', innerHTML: '', count: '' }) { let td = gameTable.getTd(coords); if (td.dataset.count === undefined) throw new Error("td.dataset.count is undefined!!!") - if (all === true || ['0', '1'].includes(td.dataset.count)) { + if (oldTd.className !== '' && oldTd.count !== '') { + td.className = oldTd.className; + td.innerHTML = oldTd.innerHTML; + td.dataset.count = oldTd.count; + } else if (all === true || ['0', '1'].includes(td.dataset.count)) { td.className = 'chequer'; td.dataset.count = '0'; td.innerHTML = ''; diff --git a/frontend/ts/gameTable.ts b/frontend/ts/gameTable.ts index a0f9c6a..94051f8 100644 --- a/frontend/ts/gameTable.ts +++ b/frontend/ts/gameTable.ts @@ -16,6 +16,7 @@ export default class gameTable { gameTable.gameTable.appendChild(tr); } } + static getTd(coords: Coordinates): HTMLElement { return gameTable.gameTable.children[coords.y].children[coords.x] as HTMLElement; } diff --git a/frontend/ts/ghost.ts b/frontend/ts/ghost.ts index 208127d..9a6008a 100644 --- a/frontend/ts/ghost.ts +++ b/frontend/ts/ghost.ts @@ -1,25 +1,36 @@ -import { Chequer, GameBoard, HoBSquare, HomesOrBases, Square, tColors } from "../../helpers/helpersBack"; +import { Chequer, GameBoard, HoBSquare, HomesOrBases, OldTd, Square, tColors } from "../../helpers/helpersBack"; import gameBoardClass from "./gameBoard.js"; import gameTable from "./gameTable.js"; +import StartGame from "./startGame.js"; export default class ghost { static ghostsTds: Array<{ td: HTMLElement, class: string }> = []; static interval: any; static hide = true; + static oldTd: OldTd; + static showGhost(chequer: Chequer | HoBSquare, color: tColors) { if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { chequer.ghost?.coords === undefined ? console.log("showShost::chequer.ghost.coords === undefined", chequer.ghost?.coords === undefined) : ''; return; } - gameBoardClass.showChequer(chequer.ghost.coords, 4) + let td = gameTable.getTd(chequer.ghost.coords); + if (td.dataset.count === undefined) { + throw new Error("td.dataset.count === undefined"); + } + ghost.oldTd = { className: td.className, innerHTML: td.innerHTML, count: td.dataset.count }; + gameBoardClass.showChequer(chequer.ghost.coords, 4, StartGame.colors[color]) } + static hideGhost(chequer: Chequer | HoBSquare): void { if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { chequer.ghost?.coords === undefined ? console.log("hideGhost::chequer.ghost.coords === undefined", chequer.ghost?.coords === undefined) : ''; return; } - gameBoardClass.hideChequer(chequer.ghost.coords); + gameBoardClass.hideChequer(chequer.ghost.coords, false, ghost.oldTd); + ghost.oldTd = { className: '', innerHTML: '', count: '' }; } + static removeGhosts(gameBoard: GameBoard, color: tColors): void { for (let square of gameBoard.map) { for (let chequer of square.chequers) { @@ -33,6 +44,7 @@ export default class ghost { chequer.ghost = undefined; } } + static anyGhosts(gameBoard: GameBoard, color: tColors): boolean { for (let square of gameBoard.map) { for (let chequer of square.chequers) { @@ -50,6 +62,7 @@ export default class ghost { } return false; } + static allBlink(gameBoard: GameBoard, color: tColors) { for (let square of gameBoard.map) { if (square.chequers.some(el => el.ghost !== undefined) === true) @@ -64,18 +77,22 @@ export default class ghost { ghost.blink(chequer); } } + static blink(chequer: Square | HoBSquare) { if (ghost.interval === undefined) ghost.interval = setInterval(ghost.blinking, 700); let td = gameTable.getTd({ x: chequer.x, y: chequer.y }); ghost.ghostsTds.push({ td, class: td.className }); } + static blinking() { for (let td of ghost.ghostsTds) { - td.td.className = ghost.hide === true ? '' : td.class; + if (!td.td.className.includes("white")) + td.td.className = ghost.hide === true ? 'chequer chequer-pink' : td.class; } ghost.hide = !ghost.hide; } + static allStopBlink() { clearInterval(ghost.interval); ghost.interval = undefined; diff --git a/frontend/ts/logic.ts b/frontend/ts/logic.ts index 438bd8c..015226e 100644 --- a/frontend/ts/logic.ts +++ b/frontend/ts/logic.ts @@ -1,126 +1,119 @@ import { Coordinates, GameBoard, HomesOrBases, Square, tColors } from "../../helpers/helpersBack"; import Helpers from "../../helpers/helpers.js" export default class Logic { - static moveFromBase(gameBoard: GameBoard, color: tColors,) { - let start: Square, i: number; + static moveFromBase(gameBoard: GameBoard, color: tColors,) { + let start: Square, i: number; - gameBoard.map.forEach((square, j) => { - if (square.start === color) { - start = square; - i = j; - } - }) + gameBoard.map.forEach((square, j) => { + if (square.start === color) { + start = square; + i = j; + } + }) - gameBoard.bases[color as keyof HomesOrBases].forEach((chequer, j) => { - if (chequer.chequer > -1) { - chequer.ghost = { - where: { - from: "base", oldIndex: j, - to: "map", newIndex: i - }, - color: color, - coords: { x: start.x, y: start.y } - }; - } - }) + gameBoard.bases[color as keyof HomesOrBases].forEach((chequer, j) => { + if (chequer.chequer > -1) { + chequer.ghost = { + where: { + from: "base", oldIndex: j, + to: "map", newIndex: i + }, + color: color, + coords: { x: start.x, y: start.y } + }; + } + }) - return gameBoard; - } - static moveInMap(gameBoard: GameBoard, color: tColors, number: number) { - console.log("moveInMap::color ", color) - gameBoard.map.forEach((square, i) => { - if (square.chequers.length > 0 && square.chequers[0].color === color) { - for (let chequer of square.chequers) { - let x: number | undefined, y: number | undefined, coords: Coordinates | undefined, inMap: boolean, - homeIndex: number | undefined, befStart: number | undefined; + return gameBoard; + } + static moveInMap(gameBoard: GameBoard, color: tColors, number: number) { + gameBoard.map.forEach((square, i) => { + if (square.chequers.length > 0 && square.chequers[0].color === color) { + for (let chequer of square.chequers) { + let x: number | undefined, y: number | undefined, coords: Coordinates | undefined, inMap: boolean, + homeIndex: number | undefined, befStart: number | undefined; - if (color !== Helpers.Color.red) { - gameBoard.map.forEach((square, i) => { - if (square.start === color) - befStart = i - 1; - }); - } else { - befStart = gameBoard.map.length - 1; - } - if (befStart === undefined) - throw new Error("before start doesnt exist"); + if (color !== Helpers.Color.red) { + gameBoard.map.forEach((square, i) => { + if (square.start === color) + befStart = i - 1; + }); + } else { + befStart = gameBoard.map.length - 1; + } + if (befStart === undefined) + throw new Error("before start doesnt exist"); - let range = (start: number, end: number) => Array.from(Array(end + 1).keys()).slice(start); - console.log("range ", range(i, i + number)); - console.log("homeIndex ", befStart); - // if(i >= befStart && i + number <= befStart) { - if (range(i, i + number).includes(befStart)) { - // debugger; - // homeIndex = gameBoard.map.length - i - 1 - number - 1; - homeIndex = number - befStart + i - 1; - inMap = false; + let range = (start: number, end: number) => Array.from(Array(end + 1).keys()).slice(start); + // if(i >= befStart && i + number <= befStart) { + if (range(i, i + number).includes(befStart)) { + homeIndex = number - befStart + i - 1; + inMap = false; - if (homeIndex < gameBoard.homes[0].length) { - x = gameBoard.homes[color as keyof HomesOrBases][homeIndex].x; - y = gameBoard.homes[color as keyof HomesOrBases][homeIndex].y; - } - else { - x = y = undefined; - } - console.log("toHome check ", { x, y, homeIndex, befStart }); - } else { - if (i + number >= gameBoard.map.length) { - // debugger; - number += i - gameBoard.map.length - i; //* -$i 'cause adding $i on 62 && 63 - }// i += number - gameBoard.map.length - 1 - number; //* -$number 'cause adding $number on 62 && 63 - console.log("newIndex: ", i + number) - x = gameBoard.map[i + number].x; - y = gameBoard.map[i + number].y; - inMap = true; - } + if (homeIndex < gameBoard.homes[0].length) { + x = gameBoard.homes[color as keyof HomesOrBases][homeIndex].x; + y = gameBoard.homes[color as keyof HomesOrBases][homeIndex].y; + } + else { + x = y = undefined; + } + } else { + if (i + number >= gameBoard.map.length) + number += i - gameBoard.map.length - i; //* -$i 'cause adding $i on 62 && 63 - if (x === undefined || y === undefined) - coords = undefined; - else - coords = { x, y }; + x = gameBoard.map[i + number].x; + y = gameBoard.map[i + number].y; + inMap = true; + } - chequer.ghost = { - where: { - from: "map", oldIndex: i, - to: (inMap === true ? "map" : "home"), newIndex: homeIndex || i + number - }, - color: color, - coords, - } - } - } - }) - return gameBoard; - } - static moveInHome(gameBoard: GameBoard, color: tColors, number: number) { - let home = gameBoard.homes[color as keyof HomesOrBases]; + if (x === undefined || y === undefined) + coords = undefined; + else + coords = { x, y }; - home.forEach((chequer, i) => { - if (chequer.chequer > -1) { - let x: number | undefined, y: number | undefined, coords: Coordinates | undefined; - if (home[i + number] !== undefined) { - x = home[i + number].x; - y = home[i + number].y; - } else { - x = y = undefined; - } + chequer.ghost = { + where: { + from: "map", oldIndex: i, + to: (inMap === true ? "map" : "home"), + newIndex: homeIndex || i + number + }, + color: color, + coords, + } + } + } + }) + return gameBoard; + } + static moveInHome(gameBoard: GameBoard, color: tColors, number: number) { + let home = gameBoard.homes[color as keyof HomesOrBases]; - if (x === undefined || y === undefined) - coords = undefined; - else - coords = { x, y }; + home.forEach((chequer, i) => { + if (chequer.chequer > -1) { + let x: number | undefined, y: number | undefined, coords: Coordinates | undefined; + if (home[i + number] !== undefined) { + x = home[i + number].x; + y = home[i + number].y; + } else { + x = y = undefined; + } - chequer.ghost = { - where: { - from: "home", oldIndex: i, - to: "home", newIndex: i + number - }, - color: color, - coords, - }; - } - }); + if (x === undefined || y === undefined) + coords = undefined; + else + coords = { x, y }; + + chequer.ghost = { + where: { + from: "home", oldIndex: i, + to: "home", newIndex: i + number + }, + color: color, + coords, + }; + } + }); - return gameBoard; - } + return gameBoard; + } }
\ No newline at end of file diff --git a/frontend/ts/login.ts b/frontend/ts/login.ts index 2e50884..c02aafd 100644 --- a/frontend/ts/login.ts +++ b/frontend/ts/login.ts @@ -4,11 +4,12 @@ import Helpers from "../../helpers/helpers.js"; class Login { static html = /* html */ ` <div class="container text-center fs-1" style="margin-top: 45vh;"> - <label for="username">Vad heter du?</label> - <input type="text" name="username" required> - <button type="button" class="btn btn-light btn-lg" onclick="Login.login">Starta spelet</button> + <label for="username">Vad heter du?</label> + <input type="text" name="username" required> + <button type="button" class="btn btn-light btn-lg" onclick="Login.login">Starta spelet</button> </div> `; + static clicked = false; static async start() { let res = await (await fetch("/startPoint")).json(); @@ -19,13 +20,17 @@ class Login { document.getElementsByTagName("button")[0].onclick = () => Login.login(); // !! - document.getElementsByTagName("input")[0].value = "maks " + Helpers.getRandomInt(1, 100); - document.title = document.getElementsByTagName("input")[0].value; - document.getElementsByTagName("button")[0].click(); + // document.getElementsByTagName("input")[0].value = "maks " + Helpers.getRandomInt(1, 100); + // document.title = document.getElementsByTagName("input")[0].value; + // document.getElementsByTagName("button")[0].click(); } } static async login(username = "") { + if(Login.clicked === true) + return; + + Login.clicked = true; if (username === "") username = document.getElementsByTagName("input")[0].value; diff --git a/frontend/ts/startGame.ts b/frontend/ts/startGame.ts index d73b846..883d648 100644 --- a/frontend/ts/startGame.ts +++ b/frontend/ts/startGame.ts @@ -29,6 +29,8 @@ export default class StartGame { btnRollDice!: HTMLButtonElement; divDice!: HTMLDivElement; + voices!: Array<SpeechSynthesisVoice>; + mineTurn = false; gameStarted = false; toggleStop = false; @@ -40,6 +42,10 @@ export default class StartGame { async init(data: { data: Data, uid: string }) { document.body.innerHTML = await (await fetch("/map.html")).text(); + if (speechSynthesis.onvoiceschanged !== undefined) + speechSynthesis.onvoiceschanged = () => this.voices = speechSynthesis.getVoices(); + this.voices = speechSynthesis.getVoices(); + this.uid = data.uid; this.data = data.data; this.index = data.data.filter(el => el.id === this.uid)[0].index; @@ -69,8 +75,9 @@ export default class StartGame { if (player.ready === true || this.gameStarted === true) { tds[i].classList.add("bg-" + this.bgColors[player.color]); - if (this.uid === player.id) - this.inpStateToggle.checked = true; + if (this.uid === player.id) { + this.blockInpStateToggle() + } } else tds[i].classList.add("bg-secondary"); @@ -87,7 +94,7 @@ export default class StartGame { } readyStateToggle = async (e: MouseEvent): Promise<void> => { - if (this.toggleStop) { + if (this.toggleStop === true) { this.inpStateToggle.checked = true; return; } @@ -104,15 +111,50 @@ export default class StartGame { this.startInterval(); } + blockInpStateToggle() { + this.inpStateToggle.checked = true; + this.toggleStop = true; + } rollDice = async (e: MouseEvent): Promise<void> => { this.btnRollDice.style.display = "none"; - // ! let number = Helpers.getRandomInt(1, 7); - let number = 6; + let number = Helpers.getRandomInt(1, 7); + + if((window as any).number !== undefined) + number = (window as any).number; + + this.say(number.toString()); this.diceHash; this.divDice.classList.add(`dice-${number}`); this.calcMoves(number); } + async say(text: string) { + if (!("speechSynthesis" in window)) { + // console.log("Client does not support SpeechSynthesis") + return; + } + let utterance = new SpeechSynthesisUtterance(), + voice: SpeechSynthesisVoice | undefined = undefined, + preferredVoices = ["sv-SE", "se-SE"]; + + for (let prefVoice of preferredVoices) { + voice = this.voices.find(el => el.lang === prefVoice); + if (voice !== undefined) + break; + } + if (voice === undefined) + voice = this.voices.find(el => el.default === true); + + if (voice === undefined) { + // console.log("Client does not have any voices in SpeechSynthesis"); + return; + } + + utterance.voice = voice; + utterance.text = text; + speechSynthesis.speak(utterance); + } + calcMoves(number: number) { if ([1, 6].includes(number)) Logic.moveFromBase(this.gameBoard, this.color); @@ -127,13 +169,13 @@ export default class StartGame { ghost.allBlink(this.gameBoard, this.color); } - doTurn(chequer: Chequer | HoBSquare, redraw = true): void { + doTurn(chequer: Chequer | HoBSquare): void { if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { return; } this.mineTurn = false; let where = chequer.ghost.where; - let olderGameBoard = JSON.stringify(this.gameBoard); + if (where.from === "map") { this.gameBoard.map[where.oldIndex].chequers.pop(); } else if (where.from === "base") { @@ -145,23 +187,15 @@ export default class StartGame { if (where.to === "map") { let enemyColor = this.gameBoard.map[where.newIndex].chequers[0]?.color; if (enemyColor !== this.color && enemyColor !== undefined) { - let enemyBase = this.gameBoard.bases[enemyColor as keyof HomesOrBases]; - for (let chequer of this.gameBoard.map[where.newIndex].chequers) { - let i = 0; - for (let c of enemyBase) { - if (c.chequer < 0) break; - i++; - } - chequer.ghost = { - color: enemyColor, coords: { x: this.gameBoard.map[where.newIndex].x, y: this.gameBoard.map[where.newIndex].y }, - where: { - from: "map", oldIndex: where.newIndex, - to: "base", newIndex: i - } - } - this.doTurn(chequer, true); + let enemyBase = this.gameBoard.bases[enemyColor as keyof HomesOrBases], + square = this.gameBoard.map[where.newIndex]; + + for (let i = 0, j = 0; i < square.chequers.length; i++, j = 0) { + while(enemyBase[j].chequer >= 0) + j++; + enemyBase[j].chequer = enemyColor; } - this.gameBoard.map[where.newIndex].chequers = []; + square.chequers = []; } this.gameBoard.map[where.newIndex].chequers.push({ color: this.color }); } else if (where.to === "base") { @@ -170,17 +204,18 @@ export default class StartGame { this.gameBoard.homes[this.color as keyof HomesOrBases][where.newIndex].chequer = this.color; } - if (redraw === true) { - (window as any).clicked = true; - let won = this.gameHasBeenWon(); - ghost.allStopBlink(); - ghost.removeGhosts(this.gameBoard, this.color); - gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); - this.sendGameBoard(false); - // (window as any).clicked = false; + (window as any).clicked = true; + let won = this.gameHasBeenWon(); + if (won === true) { + alert("WON!WON!WON!WON!WON!WON!"); + throw new Error("WON!WON!WON!WON!WON!WON!"); } - } + ghost.allStopBlink(); + ghost.removeGhosts(this.gameBoard, this.color); + gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); + this.sendGameBoard(false); + } async hideDice(wait: boolean) { let diceHash = this._diceHash; wait === true ? await Helpers.sleep(2000) : ''; @@ -190,14 +225,15 @@ export default class StartGame { gameHasBeenWon(): boolean { let home = this.gameBoard.homes[this.color as keyof HomesOrBases]; - for(let square of home) { - if(square.chequer < 0) - return false; + for (let square of home) { + if (square.chequer < 0) + return false; } return true; } async sendGameBoard(diceWait: boolean) { + this.btnRollDice.style.display = "none"; ghost.allStopBlink(); ghost.removeGhosts(this.gameBoard, this.color); this.timer.stop(); @@ -221,6 +257,7 @@ export default class StartGame { if (this.gameWasStopped !== true) this.sendGameBoard(false); } + _diceHash = 0; get diceHash(): number { if (this._diceHash >= Number.MAX_SAFE_INTEGER) @@ -230,19 +267,18 @@ export default class StartGame { } async getData() { - console.log("gettingData"); let data: { gameBoard: GameBoard, currentPlayer: number, started: number, data: Data, timeTillTurnEnd: number } = await Helpers.mFetch("/getCurrentGameState", {}); + if (data.started === 1) { this.gameStarted = true; if (this.oldIndex !== data.currentPlayer) { this.oldIndex = data.currentPlayer; - if (data.currentPlayer === this.index/* && this.mineTurn === false */) { + if (data.currentPlayer === this.index) { this.mineTurn = true; this.gameWasStopped = false; this.btnRollDice.style.display = "block"; } /* else if (StartGame.waitForNewTurn === false) { */ - console.log("Redrawing gameBoard - newer from server"); this.gameBoard = data.gameBoard; gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); // } @@ -255,7 +291,6 @@ export default class StartGame { this.setOpponents(this.data, false); } - // TODO: Check zbijanie // TODO: Check gameHasBeenWon() } } diff --git a/frontend/ts/timer.ts b/frontend/ts/timer.ts index db70356..013d498 100644 --- a/frontend/ts/timer.ts +++ b/frontend/ts/timer.ts @@ -25,6 +25,7 @@ export default class Timer { this.divTimer.innerHTML = secondsElapsed.toString(); } } + stop(): void { this.divTimer.innerHTML = ''; clearInterval(this.interval); |
