aboutsummaryrefslogtreecommitdiffstats
path: root/frontend/ts/startGame.ts
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/ts/startGame.ts')
-rw-r--r--frontend/ts/startGame.ts451
1 files changed, 369 insertions, 82 deletions
diff --git a/frontend/ts/startGame.ts b/frontend/ts/startGame.ts
index e97f4ea..71a9abf 100644
--- a/frontend/ts/startGame.ts
+++ b/frontend/ts/startGame.ts
@@ -1,131 +1,418 @@
-import { Data } from "../../helpers/helpersBack";
+import { Data, Coordinates, tColors, HomesOrBases, Square, HoBSquare, Ghost, mFetch } from "../../helpers/helpersBack";
import Helpers from "../../helpers/helpers.js";
import { Chequer, GameBoard } from "../../helpers/helpersBack.js";
+import Timer from "./timer.js";
export default class StartGame {
- colors = ["primary", "danger", "success", "warning"];
+ bgColors = ["primary", "danger", "success", "warning"];
+ colors = ["blue", "red", "green", "yellow"];
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;
- ctx!: CanvasRenderingContext2D;
- canvas!: HTMLCanvasElement;
interval!: any;
- img!: HTMLImageElement;
-
- chequers: Array<Chequer> = [];
- gameBoard: GameBoard = [];
- gmString = "[\n";
+ timer!: Timer;
+
+ btnStateToggle!: HTMLInputElement;
+ gameTable!: HTMLTableElement;
+ btnRollDice!: HTMLButtonElement;
+ divDice!: HTMLDivElement;
+
+ mineTurn = false;
+ gameStarted = false;
+ toggleStop = false;
- constructor(data: Data) {
+ constructor(data: { data: Data, uid: string }) {
this.init(data);
}
- async init(data: Data) {
+ async init(data: { data: Data, uid: string }) {
document.body.innerHTML = await (await fetch("/map.html")).text();
- document.getElementsByTagName("input")[0].onclick = this.readyStateToggle;
- [this.canvas, this.ctx] = this.getCanvasAndCtx();
- this.setOpponents(data);
+ this.uid = data.uid;
+ this.data = data.data;
+ 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.canvas.onclick = e => this.canvasClickHandler(e);
+ this.setOpponents(data.data, true);
- this.img = await this.loadImage("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.png");
-
- await this.getData();
- this.ctx.drawImage(this.img, 0, 0, this.img.width, this.img.height, 0, 0, this.canvas.width, this.canvas.height);
- this.drawChequer({ x: 4, y: 1, color: 1 });
+ this.gameTable = document.getElementsByTagName("table")[1];
+ this.btnStateToggle = document.getElementsByTagName("input")[0];
+ this.btnRollDice = document.getElementsByTagName("button")[0];
+ this.divDice = document.getElementById("dice") as HTMLDivElement;
+ this.timer = new Timer();
- // this.interval = setInterval(this.getData, 2000);
- }
+ this.btnStateToggle.onclick = this.readyStateToggle;
+ this.btnRollDice.onclick = this.rollDice;
+
+ this.drawGameTable();
- getCanvasAndCtx(): [HTMLCanvasElement, CanvasRenderingContext2D] {
- let canvas = document.getElementsByTagName("canvas")[0],
- ctx = canvas.getContext("2d");
- if (ctx === null) {
- document.write("stop using IE ...");
- throw new Error("Player is using browser older than ...");
- } else return [canvas, ctx];
+ this.startInterval();
}
- async setOpponents(data: Data): Promise<void> {
+ async setOpponents(data: Data, firstTime: boolean): Promise<void> {
let tds = (document.getElementsByClassName("player-name") as HTMLCollectionOf<HTMLElement>),
i = 0;
-
+
for (let player of data) {
- if (player.ready === true)
- tds[i].classList.add("bg-" + this.colors[player.color]);
+ tds[i].className = tds[i].className.replace(/\bbg-.*\b/, '');
+
+ if (player.ready === true) {
+ tds[i].classList.add("bg-" + this.bgColors[player.color]);
+ if (this.uid === player.id)
+ document.getElementsByTagName("input")[0].checked = true;
+ }
else
tds[i].classList.add("bg-secondary");
- tds[i].innerText = player.name;
- console.log("player, i", player, i);
+ (tds[i].children[0] as HTMLElement).innerText = player.name;
i++;
}
- for (; i < 4; i++) {
- console.log("i", i);
- tds[i].classList.add("bg-secondary");
- tds[i].innerText = "?";
+ if (firstTime === true) {
+ for (; i < 4; i++) {
+ tds[i].classList.add("bg-secondary");
+ (tds[i].children[0] as HTMLElement).innerText = "?";
+ }
+ }
+ }
+
+ readyStateToggle = async (e: MouseEvent): Promise<void> => {
+ if (this.toggleStop) {
+ this.btnStateToggle.checked = true;
+ return;
}
+ this.toggleStop = true;
+ let res = await Helpers.mFetch("/readyStateToggle", {
+ state: this.btnStateToggle.checked
+ });
+ if (res.started === true)
+ this.toggleStop = true;
+ else
+ this.toggleStop = false;
+ clearInterval(this.interval);
+ this.getData();
+ this.startInterval();
}
- isIntersect(point: { x: number, y: number }, circle: Chequer) {
- return Math.sqrt((point.x - circle.x) ** 2 + (point.y - circle.y) ** 2) < this.radius;
+ rollDice = async (e: MouseEvent): Promise<void> => {
+ let number = Helpers.getRandomInt(1, 7);
+ this.divDice.classList.add(`dice-${number}`);
+ this.btnRollDice.style.display = "none";
+ this.calcMoves(number);
}
- canvasClickHandler(e: MouseEvent) {
- const mousePos = {
- x: e.clientX - this.canvas.offsetLeft,
- y: e.clientY - this.canvas.offsetTop
- };
+ calcMoves(number: number) {
+ if ([1, 6].includes(number))
+ this.moveFromBase();
- if (Math.round((mousePos.x - 30) / 60) == 0 && Math.round((mousePos.y - 28) / 60) == 0) {
- console.log(this.gmString + "]");
- this.gmString = "[\n"
- }
+ this.moveInMap(number);
+ this.moveInHome(number);
+
+ this.drawGameBoard();
+ console.log("checking for ghosts");
+ if (this.anyGhosts() === false)
+ this.sendGameBoard();
else
- this.gmString += JSON.stringify({ x: Math.round((mousePos.x - 30) / 60), y: Math.round((mousePos.y - 28) / 60) }) + ",\n";
+ console.log("ghost were created");
+ }
+ moveFromBase() {
+ let start: Square, i: number;
- this.chequers.forEach(chequer => {
- if (this.isIntersect(mousePos, chequer)) {
- alert('click on circle: ' + chequer);
+ 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,
+ }
+ }
+ }
+ })
+ }
+ 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 };
- readyStateToggle(e: MouseEvent): void {
- Helpers.mFetch("/readyStateToggle", {
- state: (e.target as HTMLInputElement).checked
+ chequer.ghost = {
+ where: {
+ from: "home", oldIndex: i,
+ to: "home", newIndex: i + number
+ },
+ color: this.color,
+ coords,
+ };
+ }
});
}
- async loadImage(src: string): Promise<HTMLImageElement> {
- return new Promise(resolve => {
- let img = new Image()
- img.src = src
- img.onload = () => resolve(img)
- })
+ 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 {
+ 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;
+ let where = chequer.ghost.where;
+
+ if (where.from === "map") {
+ this.gameBoard.map[where.oldIndex].chequers.pop();
+ } else if (where.from === "base") {
+ this.gameBoard.bases[this.color as keyof HomesOrBases][where.oldIndex].chequer = -1;
+ } else {
+ this.gameBoard.homes[this.color as keyof HomesOrBases][where.oldIndex].chequer = -1;
+ }
+
+ if (where.to === "map") {
+ this.gameBoard.map[where.newIndex].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;
}
- drawChequer(chequer: Chequer): void {
- let x = chequer.x * 60 + 30,
- y = chequer.y * 60 + 28;
+ drawGameBoard(): void {
- this.ctx.beginPath();
- this.ctx.arc(x, y, this.radius, 0, 2 * Math.PI);
- this.ctx.fillStyle = this.colors[chequer.color];
- this.ctx.fill();
- this.ctx.lineWidth = 5;
- this.ctx.strokeStyle = 'grey';
- this.ctx.closePath();
- this.ctx.stroke();
+ 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);
+ }
+ }
+ }
- this.chequers.push(chequer);
+ 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 sendGameBoard() {
+ this.divDice.className.replace(/dice.*/, '');
+ this.removeGhosts();
+ 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);
+ 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); }
+ }
+ }
+ 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) {
+ await this.timer.start(currentPlayer, this.timeTillTurnEnd);
+ this.sendGameBoard();
}
async getData() {
- let data = await Helpers.mFetch("/getCurrentGameState", {});
- // this.setOpponents(JSON.parse(data.data));
- // TODO: assign data to this.gameBoard and draw it
- // TODO: add D6 dice
- // TODO: if currentPLayer === true, call to logic or calc logic here
+ let data: { gameBoard: GameBoard, currentPlayer: number, started: number, data: Data, timeTillTurnEnd: number }
+ = await Helpers.mFetch("/getCurrentGameState", {});
+ if (data.started === 1) {
+ if (this.oldIndex !== data.currentPlayer) {
+ this.oldIndex = data.currentPlayer;
+ if (data.currentPlayer === this.index && this.mineTurn === false) {
+ this.mineTurn = true;
+ this.btnRollDice.style.display = "block";
+ }// else if (JSON.stringify(data.gameBoard) !== JSON.stringify(this.gameBoard)) {
+ this.gameBoard = data.gameBoard;
+ this.drawGameBoard();
+ // }
+ this.timeTillTurnEnd = data.timeTillTurnEnd;
+ this.startTimer(data.currentPlayer);
+ }
+ }
+
+ 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: Ending turn
+ // TODO: Ghost not working
+ // TODO: Moving not working
}
-} \ No newline at end of file
+}