From 013319d7a4651d1708280f556e39c2f03839426a Mon Sep 17 00:00:00 2001 From: Maks Jopek Date: Sun, 25 Apr 2021 12:07:36 +0200 Subject: Almost going in a circle --- frontend/ts/startGame.ts | 345 ++++++++++++----------------------------------- 1 file changed, 88 insertions(+), 257 deletions(-) (limited to 'frontend/ts/startGame.ts') diff --git a/frontend/ts/startGame.ts b/frontend/ts/startGame.ts index 71a9abf..0afbb7d 100644 --- a/frontend/ts/startGame.ts +++ b/frontend/ts/startGame.ts @@ -2,27 +2,30 @@ import { Data, Coordinates, tColors, HomesOrBases, Square, HoBSquare, Ghost, mFe import Helpers from "../../helpers/helpers.js"; import { Chequer, GameBoard } from "../../helpers/helpersBack.js"; import Timer from "./timer.js"; +import Logic from "./logic.js"; +import gameTable from "./gameTable.js"; +import ghost from "./ghost.js"; +import gameBoardClass from "./gameBoard.js"; export default class StartGame { bgColors = ["primary", "danger", "success", "warning"]; - colors = ["blue", "red", "green", "yellow"]; + static colors = ["blue", "red", "green", "yellow"]; + colors = StartGame.colors; radius = 20; - numberOfSquaresOnGameBoard = 11; startInterval = () => { this.getData(); this.interval = setInterval(() => this.getData(), 2000); } uid!: string; color!: tColors; data!: Data; - timeTillTurnEnd!: number; gameBoard!: GameBoard; index!: number; oldIndex!: number; interval!: any; timer!: Timer; + gameWasStopped!: boolean; - btnStateToggle!: HTMLInputElement; - gameTable!: HTMLTableElement; + inpStateToggle!: HTMLInputElement; btnRollDice!: HTMLButtonElement; divDice!: HTMLDivElement; @@ -42,18 +45,17 @@ export default class StartGame { this.index = data.data.filter(el => el.id === this.uid)[0].index; this.color = data.data.filter(el => el.id === this.uid)[0].color; - this.setOpponents(data.data, true); - - this.gameTable = document.getElementsByTagName("table")[1]; - this.btnStateToggle = document.getElementsByTagName("input")[0]; + this.inpStateToggle = document.getElementsByTagName("input")[0]; this.btnRollDice = document.getElementsByTagName("button")[0]; this.divDice = document.getElementById("dice") as HTMLDivElement; + gameTable.gameTable = document.getElementsByTagName("table")[1]; this.timer = new Timer(); - this.btnStateToggle.onclick = this.readyStateToggle; + this.inpStateToggle.onclick = this.readyStateToggle; this.btnRollDice.onclick = this.rollDice; - this.drawGameTable(); + this.setOpponents(data.data, true); + gameTable.drawGameTable(); this.startInterval(); } @@ -65,10 +67,10 @@ export default class StartGame { for (let player of data) { tds[i].className = tds[i].className.replace(/\bbg-.*\b/, ''); - if (player.ready === true) { + if (player.ready === true || this.gameStarted === true) { tds[i].classList.add("bg-" + this.bgColors[player.color]); if (this.uid === player.id) - document.getElementsByTagName("input")[0].checked = true; + this.inpStateToggle.checked = true; } else tds[i].classList.add("bg-secondary"); @@ -86,12 +88,12 @@ export default class StartGame { readyStateToggle = async (e: MouseEvent): Promise => { if (this.toggleStop) { - this.btnStateToggle.checked = true; + this.inpStateToggle.checked = true; return; } this.toggleStop = true; let res = await Helpers.mFetch("/readyStateToggle", { - state: this.btnStateToggle.checked + state: this.inpStateToggle.checked }); if (res.started === true) this.toggleStop = true; @@ -104,6 +106,7 @@ export default class StartGame { rollDice = async (e: MouseEvent): Promise => { let number = Helpers.getRandomInt(1, 7); + this.diceHash; this.divDice.classList.add(`dice-${number}`); this.btnRollDice.style.display = "none"; this.calcMoves(number); @@ -111,131 +114,20 @@ export default class StartGame { calcMoves(number: number) { if ([1, 6].includes(number)) - this.moveFromBase(); + Logic.moveFromBase(this.gameBoard, this.color); - this.moveInMap(number); - this.moveInHome(number); + Logic.moveInMap(this.gameBoard, this.color, number); + Logic.moveInHome(this.gameBoard, this.color, number); - this.drawGameBoard(); - console.log("checking for ghosts"); - if (this.anyGhosts() === false) - this.sendGameBoard(); + gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); + if (ghost.anyGhosts(this.gameBoard, this.color) === false) + this.sendGameBoard(true); else - console.log("ghost were created"); - } - moveFromBase() { - let start: Square, i: number; - - this.gameBoard.map.forEach((square, j) => { - if (square.start === this.color) { - start = square; - i = j; - } - }) - - this.gameBoard.bases[this.color as keyof HomesOrBases].forEach((chequer, j) => { - if (chequer.chequer > -1) { - chequer.ghost = { - where: { - from: "base", oldIndex: j, - to: "map", newIndex: i - }, - color: this.color, - coords: { x: start.x, y: start.y } - }; - } - }) - } - moveInMap(number: number) { - this.gameBoard.map.forEach((square, i) => { - if (square.chequers.length > 0 && square.chequers[0].color === this.color) { - - for (let chequer of square.chequers) { - let x: number | undefined, y: number | undefined, coords: Coordinates | undefined, inMap: boolean, - homeIndex: number | undefined; - - if (i + number < this.gameBoard.map.length) { - x = this.gameBoard.map[i + number].x; - y = this.gameBoard.map[i + number].y; - inMap = true; - } - else { - homeIndex = this.gameBoard.map.length - i - 1 - number - 1; - inMap = true; - - if (homeIndex < this.gameBoard.homes[0].length) { - x = this.gameBoard.homes[this.color as keyof HomesOrBases][homeIndex].x; - y = this.gameBoard.homes[this.color as keyof HomesOrBases][homeIndex].y; - } - else { - x = y = undefined; - } - } - - if (x === undefined || y === undefined) - coords = undefined; - else - coords = { x, y }; - - chequer.ghost = { - where: { - from: "map", oldIndex: i, - to: (inMap === true ? "map" : "home"), newIndex: homeIndex || i + number - }, - color: this.color, - coords, - } - } - } - }) + ghost.allBlink(this.gameBoard, this.color); } - moveInHome(number: number) { - let home = this.gameBoard.homes[this.color as keyof HomesOrBases]; - - 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; - } - if (x === undefined || y === undefined) - coords = undefined; - else - coords = { x, y }; - - chequer.ghost = { - where: { - from: "home", oldIndex: i, - to: "home", newIndex: i + number - }, - color: this.color, - coords, - }; - } - }); - } - - showGhost(chequer: Chequer | HoBSquare) { - if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { - console.log("showChequer::chequer.ghost.coords === undefined", chequer.ghost?.coords === undefined); - return; - } - this.showChequer(chequer.ghost.coords, this.color) - } - hideGhost(chequer: Chequer | HoBSquare): void { + doTurn(chequer: Chequer | HoBSquare, redraw = true): void { if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { - console.log("hideChequer::chequer.ghost.coords === undefined", chequer.ghost?.coords === undefined); - return; - } - this.hideChequer(chequer.ghost.coords); - } - doTurn(chequer: Chequer | HoBSquare): void { - if (chequer.ghost === undefined || chequer.ghost.coords === undefined) { - console.log("hideChequer::chequer.ghost.coords === undefined", chequer.ghost?.coords === undefined); return; } this.mineTurn = false; @@ -250,169 +142,108 @@ export default class StartGame { } if (where.to === "map") { - this.gameBoard.map[where.newIndex].chequers.push({ color: this.color }); + let mapIndex = this.gameBoard.map[where.newIndex], + enemyColor = mapIndex.chequers[0]?.color; + if (enemyColor !== this.color && enemyColor !== undefined) { + let enemyBase = this.gameBoard.bases[enemyColor as keyof HomesOrBases]; + for (let chequer of mapIndex.chequers) { + let i = 0; + for (let c of enemyBase) { + if (c.chequer < 0) break; + i++; + } + chequer.ghost = { + color: enemyColor, coords: { x: mapIndex.x, y: mapIndex.y }, + where: { + from: "map", oldIndex: where.newIndex, + to: "base", newIndex: i + } + } + this.doTurn(chequer, true); + } + mapIndex.chequers = []; + } + + mapIndex.chequers.push({ color: this.color }); } else if (where.to === "base") { this.gameBoard.bases[this.color as keyof HomesOrBases][where.newIndex].chequer = this.color; } else { this.gameBoard.homes[this.color as keyof HomesOrBases][where.newIndex].chequer = this.color; } - this.sendGameBoard(); - } - removeGhosts(): void { - for (let square of this.gameBoard.map) { - for (let chequer of square.chequers) { - chequer.ghost = undefined; - } - } - for (let chequer of this.gameBoard.bases[this.color as keyof HomesOrBases]) { - chequer.ghost = undefined; - } - for (let chequer of this.gameBoard.homes[this.color as keyof HomesOrBases]) { - chequer.ghost = undefined; - } - } - anyGhosts(): boolean { - for (let square of this.gameBoard.map) { - for (let chequer of square.chequers) { - if (chequer.ghost !== undefined) - return true; - } - } - for (let chequer of this.gameBoard.bases[this.color as keyof HomesOrBases]) { - if (chequer.ghost !== undefined) - return true; - } - for (let chequer of this.gameBoard.homes[this.color as keyof HomesOrBases]) { - if (chequer.ghost !== undefined) - return true; - } - return false; - } - - drawGameBoard(): void { - - for (let square of this.gameBoard.map) { - if (square.chequers.length !== 0) { - for (let chequer of square.chequers) - this.drawChequer({ x: square.x, y: square.y }, chequer.color, chequer); - } - } - for (let baseOfColor in this.gameBoard.bases) { - for (let square of this.gameBoard.bases[baseOfColor as unknown as keyof HomesOrBases]) { - if (square.chequer > -1) - this.drawChequer({ x: square.x, y: square.y }, square.chequer, square); - } - } - for (let baseOfColor in this.gameBoard.homes) { - for (let square of this.gameBoard.homes[baseOfColor as unknown as keyof HomesOrBases]) { - if (square.chequer > -1) - this.drawChequer({ x: square.x, y: square.y }, square.chequer, square); - } + if (redraw === true) { + gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); + this.sendGameBoard(false); } } - drawGameTable(): void { - for (let i = 0; i < this.numberOfSquaresOnGameBoard; i++) { - let tr = document.createElement("tr"); - for (let j = 0; j < this.numberOfSquaresOnGameBoard; j++) { - let td = document.createElement("td"); - td.classList.add("chequer"); - td.dataset.count = '0'; - tr.appendChild(td); - } - this.gameTable.appendChild(tr); - } + async hideDice(wait: boolean) { + let diceHash = this._diceHash; + wait === true ? await Helpers.sleep(5000) : ''; + if (diceHash === this.diceHash) + this.divDice.className = this.divDice.className.replace(/dice.*/, ''); } - async sendGameBoard() { - this.divDice.className.replace(/dice.*/, ''); - this.removeGhosts(); + async sendGameBoard(diceWait: boolean) { + ghost.allStopBlink(); + ghost.removeGhosts(this.gameBoard, this.color); + this.timer.stop(); + this.gameWasStopped = true; + this.hideDice(diceWait); await Helpers.mFetch("/saveGameBoard", { gameBoard: this.gameBoard }); } - getTd(coords: Coordinates): HTMLElement { - return this.gameTable.children[coords.y].children[coords.x] as HTMLElement; - } - showChequer(coords: Coordinates, color: tColors): void { - let td = this.getTd(coords); - if (td.dataset.count === undefined) - throw new Error("td.dataset.count is undefined!!!") - - if (td.dataset.count === '0') { - td.classList.add("chequer-" + this.colors[color]); - td.dataset.count = "1"; - } else { - td.dataset.count = (parseInt(td.dataset.count) + 1).toString(); - td.innerHTML = 'x' + td.dataset.count; - } - } - hideChequer(coords: Coordinates, all = false) { - let td = this.getTd(coords); - if (td.dataset.count === undefined) - throw new Error("td.dataset.count is undefined!!!") - - if (td.dataset.count === '0') - throw new Error("Cannot remove from empty td!!!"); - - if (td.dataset.count === '1' || all === true) { - td.className = td.className.replace(/chequer-.*/, ''); - td.innerHTML = 'x' + td.dataset.count; - } else { - td.dataset.count = (parseInt(td.dataset.count) - 1).toString(); - td.innerHTML = 'x' + td.dataset.count; - } - } - - drawChequer(coords: Coordinates, color: tColors, chequer: Chequer | HoBSquare): void { - let td = this.getTd(coords); - this.showChequer(coords, color); + drawChequer = (coords: Coordinates, color: tColors, chequer: Chequer | HoBSquare): void => { + let td = gameTable.getTd(coords); + gameBoardClass.showChequer(coords, color); if (this.mineTurn === true && chequer.ghost !== undefined) { - td.onmouseenter = () => { console.log("mouseenter"); this.showGhost(chequer); } - td.onmouseleave = () => { console.log("mouseleave"); this.hideGhost(chequer); } - td.onclick = () => { console.log("mouseclick"); this.doTurn(chequer); } + td.onmouseenter = () => ghost.showGhost(chequer, this.color); + td.onmouseleave = () => ghost.hideGhost(chequer); + td.onclick = () => this.doTurn(chequer); } } - removeChequer(coords: Coordinates) { - let td = this.getTd(coords); - this.hideChequer(coords, true); - td.onmouseenter = () => null; - td.onmouseleave = () => null; - td.onclick = () => null; + + async startTimer(currentPlayer: number, timeTillTurnEnd: number) { + await this.timer.start(currentPlayer, timeTillTurnEnd); + if (this.gameWasStopped !== true) + this.sendGameBoard(false); } + _diceHash = 0; + get diceHash(): number { + if (this._diceHash >= Number.MAX_SAFE_INTEGER) + this._diceHash = 0; - async startTimer(currentPlayer: number) { - await this.timer.start(currentPlayer, this.timeTillTurnEnd); - this.sendGameBoard(); + return this._diceHash++; } async getData() { 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 === false */) { this.mineTurn = true; + this.gameWasStopped = false; this.btnRollDice.style.display = "block"; }// else if (JSON.stringify(data.gameBoard) !== JSON.stringify(this.gameBoard)) { this.gameBoard = data.gameBoard; - this.drawGameBoard(); + gameBoardClass.drawGameBoard(this.gameBoard, this.drawChequer); // } - this.timeTillTurnEnd = data.timeTillTurnEnd; - this.startTimer(data.currentPlayer); + this.startTimer(data.currentPlayer, data.timeTillTurnEnd); } } if (JSON.stringify(data.data) !== JSON.stringify(this.data)) { - console.log("startGame::getData::data", data.data); this.data = data.data; this.setOpponents(this.data, false); } - // TODO: Animation: blinking of chequers with ghosts + // TODO: Going to home + // TODO: Check stacking + // TODO: Check zbijanie + // TODO: Going from [40] -> [0] // TODO: Ending turn - // TODO: Ghost not working - // TODO: Moving not working } } -- cgit v1.3.1