aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaks Jopek <maksymilian.jopek@prym-soft.pl>2021-04-24 00:34:07 +0200
committerMaks Jopek <maksymilian.jopek@prym-soft.pl>2021-04-24 00:34:07 +0200
commit13dcc2c8fc1d11e3b94432fffc4c4f186bd94d29 (patch)
tree077a963bae31729dffa6c7c678af112680bb6d38
parent457ee1d7caa899bbe86bf7a1390f940b5b3176b7 (diff)
downloadfia-13dcc2c8fc1d11e3b94432fffc4c4f186bd94d29.tar.gz
fia-13dcc2c8fc1d11e3b94432fffc4c4f186bd94d29.tar.zst
fia-13dcc2c8fc1d11e3b94432fffc4c4f186bd94d29.zip
Playing almost working
-rw-r--r--backend/ts/api/getCurrentGameState.ts25
-rw-r--r--backend/ts/api/login.ts46
-rw-r--r--backend/ts/api/readyStateToggle.ts46
-rw-r--r--backend/ts/api/saveGameBoard.ts16
-rw-r--r--backend/ts/api/startPoint.ts12
-rw-r--r--backend/ts/gameBoard.ts99
-rw-r--r--backend/ts/index.ts4
-rw-r--r--backend/ts/startGame.ts41
-rw-r--r--frontend/ts/login.ts10
-rw-r--r--frontend/ts/startGame.ts451
-rw-r--r--frontend/ts/timer.ts30
-rw-r--r--helpers/helpers.ts33
-rw-r--r--helpers/helpersBack.ts92
-rw-r--r--package.json2
-rw-r--r--public/css/fia.css77
-rw-r--r--public/index.html1
-rw-r--r--public/map.html21
17 files changed, 820 insertions, 186 deletions
diff --git a/backend/ts/api/getCurrentGameState.ts b/backend/ts/api/getCurrentGameState.ts
index 7efa009..028cf04 100644
--- a/backend/ts/api/getCurrentGameState.ts
+++ b/backend/ts/api/getCurrentGameState.ts
@@ -1,16 +1,25 @@
import { Request, Response } from "express";
-import { Data, makeQuery } from "../../../helpers/helpersBack";
+import { Data, makeQuery, getData, API_RES, GameBoard } from "../../../helpers/helpersBack";
export default async function getCurrentGameState(req: Request, res: Response) {
- if (req.session === undefined /* || req.body.state === undefined */) {
- res.status(500);
- res.send("");
+ // console.log("request.session", req.session)
+ if (req.session === undefined || req.session.gid === undefined) {
+ res.status(400);
+ res.send(API_RES.failure);
return;
}
- let dbRes: {gameBoard: Data, currentPlayer: number}
- = (await makeQuery("SELECT `gameBoard`, `currentPlayer` FROM `fia` WHERE `id` = ?", [req.session.gid]))[0],
- currentPlayer = dbRes.currentPlayer === req.session.index;
+ let dbRes: { gameBoard: GameBoard, currentPlayer: number, started: number, data: Data, timeTillTurnEnd: number }
+ = (await makeQuery("SELECT `gameBoard`, `currentPlayer`, `started`, `data`, `timeTillTurnEnd`"
+ + " FROM `fia` WHERE `id` = ?",
+ [req.session.gid]))[0];
+
+
+ if (dbRes.started === 0) {
+ res.send(JSON.stringify({ data: dbRes.data }));
+ } else {
+ res.send(JSON.stringify(dbRes));
+ }
+
- res.send(JSON.stringify({gameBoard: dbRes.gameBoard, currentPlayer}));
} \ No newline at end of file
diff --git a/backend/ts/api/login.ts b/backend/ts/api/login.ts
index 0c6ef75..b21a506 100644
--- a/backend/ts/api/login.ts
+++ b/backend/ts/api/login.ts
@@ -1,6 +1,7 @@
import { Request, Response } from "express";
-import { fiaTable, dbRes, Color, Colors, Helpers, makeQuery, Chequer, tColors } from "../../../helpers/helpersBack";
+import { fiaTable, dbRes, Color, Colors, Helpers, makeQuery, Chequer, tColors, waitForQueue } from "../../../helpers/helpersBack";
import startGame from "../startGame";
+import { global } from "../index";
export default async function apiLogin(req: Request, res: Response) {
if (req.session === undefined) {
@@ -11,27 +12,39 @@ export default async function apiLogin(req: Request, res: Response) {
req.session.uid = req.session.id;
req.session.name = req.body.name;
- let dbRes = (await makeQuery("SELECT * FROM `fia` WHERE `started`= 0 LIMIT 1", [])) as Array<dbRes>,
+ if (global.stop === true) {
+ await waitForQueue();
+ }
+ global.stop = true;
+
+ let dbRes = (await makeQuery("SELECT * FROM `fia` WHERE `started`= 0 LIMIT 1", [])) as Array<fiaTable>,
row: fiaTable;
- if (dbRes.length === 0) {
- let color = Helpers.getRandomInt(0, 5);
+ if (dbRes[0] === undefined) {
+ let color = Helpers.getRandomInt(0, 4);
row = {} as fiaTable;
row.data = [{
id: req.session.uid,
index: 0,
- color: Color[color as keyof Colors],
+ ready: false,
+ color: color,
name: req.body.name,
}];
- req.session.color = Color.blue;
+ req.session.color = color;
- await makeQuery('INSERT INTO `fia`(`data`, `started`) VALUES (?, ?)', [JSON.stringify(row.data), 0]);
- req.session.gid = (await makeQuery('SELECT `id` FROM `fia` WHERE `data`= ?', [JSON.stringify(row.data)]) as any)[0].id;
+ await makeQuery('INSERT INTO `fia`(`data`) VALUES (?)', [row.data]);
+ req.session.gid = (await makeQuery('SELECT `id` FROM `fia` WHERE `data`= ?', [row.data]) as any)[0].id;
} else {
- row = Helpers.dbResToFiaTable(dbRes[0]);
+ // row = Helpers.dbResToFiaTable(dbRes[0]);
+ row = dbRes[0];
let playersColors: Array<tColors> = [],
colors = [...Array(4).keys()];
+ if (row.data.filter(el => el.id !== req.session?.uid).length === 0) {
+ res.send(JSON.stringify({ data: row.data, uid: req.session.uid }));
+ return;
+ }
+
for (let playerData of row.data)
playersColors.push(playerData.color);
@@ -42,6 +55,7 @@ export default async function apiLogin(req: Request, res: Response) {
row.data.push({
id: req.session.uid,
index: index,
+ ready: false,
color: color,
name: req.body.name,
});
@@ -49,12 +63,14 @@ export default async function apiLogin(req: Request, res: Response) {
req.session.gid = row.id;
req.session.index = index;
- makeQuery('UPDATE `fia` SET `data`= ? WHERE `id`= ?', [JSON.stringify(row.data), row.id]);
+ await makeQuery('UPDATE `fia` SET `data`= ? WHERE `id`= ?', [row.data, row.id]);
+
+ if (row.data.length >= 4)
+ startGame(req.session.gid);
- if (row.data.length === 4) {
- startGame(req, res);
- }
}
- makeQuery("UPDATE `fia` SET `playersCount`=`playersCount`+1 WHERE `id`= ?", [req.session.gid]);
- res.send(JSON.stringify(row.data));
+
+ await makeQuery("UPDATE `fia` SET `playersCount`=`playersCount`+1 WHERE `id`= ?", [req.session.gid]);
+ global.stop = false;
+ res.send(JSON.stringify({ data: row.data, uid: req.session.uid }));
}
diff --git a/backend/ts/api/readyStateToggle.ts b/backend/ts/api/readyStateToggle.ts
index 6bca5b2..e1b08b2 100644
--- a/backend/ts/api/readyStateToggle.ts
+++ b/backend/ts/api/readyStateToggle.ts
@@ -1,19 +1,43 @@
import { Request, Response } from "express";
-import { makeQuery } from "../../../helpers/helpersBack";
+import { makeQuery, Data, getData, API_RES, waitForQueue } from "../../../helpers/helpersBack";
import startGame from "../startGame";
+import {global} from "../index";
export default async function (req: Request, res: Response) {
- if (req.session === undefined || req.body.state === undefined) {
+ if (req.session === undefined || req.body.state === undefined || req.session.gid === undefined) {
res.status(500);
- res.send("");
+ res.send(API_RES.failure);
return;
}
- await makeQuery("UPDATE `fia` SET `playersAreReady`=`playersAreReady`+" + (req.body.state ? 1 : -1)
- + " WHERE `id`=" + req.session.gid, []);
- let start = (
- await makeQuery('SELECT playersAreReady=playersCount and playersCount > 1 "start" FROM `fia` WHERE `id`= ?',
- [req.session.gid])
- )[0].start;
- if(start === 1)
- startGame(req, res);
+
+ if(global.stop === true) {
+ await waitForQueue();
+ }
+ global.stop = true;
+
+ let data: { data: Data, started: number } =
+ (await makeQuery("SELECT `data`, `started` FROM `fia` WHERE `id` = ?", [req.session.gid]))[0],
+ i = 1,
+ started = false;
+
+ if (data.started === 0) {
+
+ for (let player of data.data) {
+ if (player.id === req.session.uid)
+ player.ready = req.body.state ? true : false;
+ else if (player.ready === true)
+ i++;
+ }
+
+ await makeQuery("UPDATE `fia` SET `data` = ?, `playersAreReady`=`playersAreReady`+ ? WHERE `id`= ?",
+ [data.data, (req.body.state ? 1 : -1), req.session.gid]);
+
+ if (data.data.length > 1 && data.data.length === i) {
+ startGame(req.session.gid);
+ started = true;
+ }
+
+ }
+ global.stop = false;
+ res.send(`{"success": true, "started": ${started}}`);
}
diff --git a/backend/ts/api/saveGameBoard.ts b/backend/ts/api/saveGameBoard.ts
new file mode 100644
index 0000000..551c185
--- /dev/null
+++ b/backend/ts/api/saveGameBoard.ts
@@ -0,0 +1,16 @@
+import { Request, Response } from "express";
+import { API_RES, makeQuery } from "../../../helpers/helpersBack";
+
+export default async function saveGameBoard(req: Request, res: Response) {
+ if(req.session === undefined || req.body.gameBoard === undefined) {
+ res.status(400);
+ res.send(API_RES.failure);
+ return;
+ }
+
+ await makeQuery("UPDATE `fia` SET `gameBoard` = ? WHERE `id` = ? ", [
+ req.body.gameBoard, req.session.gid
+ ]);
+
+ res.send(API_RES.success);
+} \ No newline at end of file
diff --git a/backend/ts/api/startPoint.ts b/backend/ts/api/startPoint.ts
index d635622..20d7b79 100644
--- a/backend/ts/api/startPoint.ts
+++ b/backend/ts/api/startPoint.ts
@@ -2,16 +2,12 @@ import { Request, Response } from "express";
import { makeQuery } from "../../../helpers/helpersBack";
export default async function (req: Request, res: Response) {
- if (req.session === undefined) {
- res.send(/* html */ `<script>alert("Something went wrong, try to reload the page")</script>`);
- return;
- }
- // console.log("uid:", req.session.uid, "gid:", req.session.gid);
- if (req.session.uid !== undefined) {
- let data = await makeQuery('SELECT `data` FROM `fia` WHERE `id`=?', [req.session.gid]);
+ if (req.session !== undefined && req.session.gid !== undefined) {
+ let data = (await makeQuery('SELECT `data` FROM `fia` WHERE `id`=?', [req.session.gid]))[0];
res.send(JSON.stringify({
status: true,
- data: data
+ data: data,
+ uid: req.session.uid
}))
}
else {
diff --git a/backend/ts/gameBoard.ts b/backend/ts/gameBoard.ts
new file mode 100644
index 0000000..89a8902
--- /dev/null
+++ b/backend/ts/gameBoard.ts
@@ -0,0 +1,99 @@
+import { Color, GameBoard } from '../../helpers/helpersBack';
+export const gameBoard: GameBoard = {
+ map: [
+ { y: 0, x: 4, chequers: [], start: Color.red },
+ { y: 1, x: 4, chequers: [], start: -1 },
+ { y: 2, x: 4, chequers: [], start: -1 },
+ { y: 3, x: 4, chequers: [], start: -1 },
+ { y: 4, x: 4, chequers: [], start: -1 },
+ { y: 4, x: 3, chequers: [], start: -1 },
+ { y: 4, x: 2, chequers: [], start: -1 },
+ { y: 4, x: 1, chequers: [], start: -1 },
+ { y: 4, x: 0, chequers: [], start: -1 },
+ { y: 5, x: 0, chequers: [], start: -1 },
+ { y: 6, x: 0, chequers: [], start: Color.blue },
+ { y: 6, x: 1, chequers: [], start: -1 },
+ { y: 6, x: 2, chequers: [], start: -1 },
+ { y: 6, x: 3, chequers: [], start: -1 },
+ { y: 6, x: 4, chequers: [], start: -1 },
+ { y: 7, x: 4, chequers: [], start: -1 },
+ { y: 8, x: 4, chequers: [], start: -1 },
+ { y: 9, x: 4, chequers: [], start: -1 },
+ { y: 10, x: 4, chequers: [], start: -1 },
+ { y: 10, x: 5, chequers: [], start: -1 },
+ { y: 10, x: 6, chequers: [], start: Color.green },
+ { y: 9, x: 6, chequers: [], start: -1 },
+ { y: 8, x: 6, chequers: [], start: -1 },
+ { y: 7, x: 6, chequers: [], start: -1 },
+ { y: 6, x: 6, chequers: [], start: -1 },
+ { y: 6, x: 7, chequers: [], start: -1 },
+ { y: 6, x: 8, chequers: [], start: -1 },
+ { y: 6, x: 9, chequers: [], start: -1 },
+ { y: 6, x: 10, chequers: [], start: -1 },
+ { y: 5, x: 10, chequers: [], start: -1 },
+ { y: 4, x: 10, chequers: [], start: Color.yellow },
+ { y: 4, x: 9, chequers: [], start: -1 },
+ { y: 4, x: 8, chequers: [], start: -1 },
+ { y: 4, x: 7, chequers: [], start: -1 },
+ { y: 4, x: 6, chequers: [], start: -1 },
+ { y: 3, x: 6, chequers: [], start: -1 },
+ { y: 2, x: 6, chequers: [], start: -1 },
+ { y: 1, x: 6, chequers: [], start: -1 },
+ { y: 0, x: 6, chequers: [], start: -1 },
+ { y: 0, x: 5, chequers: [], start: -1 },
+ ],
+ // @ts-ignore
+ bases: {
+ [Color.red]: [
+ { x: 1, y: 1, chequer: -1 },
+ { x: 1, y: 2, chequer: -1 },
+ { x: 2, y: 2, chequer: -1 },
+ { x: 2, y: 1, chequer: -1 },
+ ],
+ [Color.blue]: [
+ { x: 8, y: 1, chequer: -1 },
+ { x: 9, y: 1, chequer: -1 },
+ { x: 9, y: 2, chequer: -1 },
+ { x: 8, y: 2, chequer: -1 },
+ ],
+ [Color.green]: [
+ { x: 8, y: 8, chequer: -1 },
+ { x: 9, y: 8, chequer: -1 },
+ { x: 9, y: 9, chequer: -1 },
+ { x: 8, y: 9, chequer: -1 },
+ ],
+ [Color.yellow]: [
+ { x: 1, y: 8, chequer: -1 },
+ { x: 2, y: 8, chequer: -1 },
+ { x: 2, y: 9, chequer: -1 },
+ { x: 1, y: 9, chequer: -1 },
+ ],
+ },
+ // @ts-ignore
+ homes: {
+ [Color.red]: [
+ { x: 5, y: 1, chequer: -1 },
+ { x: 5, y: 2, chequer: -1 },
+ { x: 5, y: 3, chequer: -1 },
+ { x: 5, y: 4, chequer: -1 },
+ ],
+ [Color.blue]: [
+ { x: 1, y: 5, chequer: -1 },
+ { x: 2, y: 5, chequer: -1 },
+ { x: 3, y: 5, chequer: -1 },
+ { x: 4, y: 5, chequer: -1 },
+ ],
+ [Color.green]: [
+ { x: 5, y: 9, chequer: -1 },
+ { x: 5, y: 8, chequer: -1 },
+ { x: 5, y: 7, chequer: -1 },
+ { x: 5, y: 6, chequer: -1 },
+ ],
+ [Color.yellow]: [
+ { x: 9, y: 5, chequer: -1 },
+ { x: 8, y: 5, chequer: -1 },
+ { x: 7, y: 5, chequer: -1 },
+ { x: 6, y: 5, chequer: -1 },
+ ],
+ }
+} \ No newline at end of file
diff --git a/backend/ts/index.ts b/backend/ts/index.ts
index d0899dd..e4ec5ee 100644
--- a/backend/ts/index.ts
+++ b/backend/ts/index.ts
@@ -6,6 +6,9 @@ import login from "./api/login";
import startPoint from "./api/startPoint";
import readyStateToggle from "./api/readyStateToggle";
import getCurrentGameState from "./api/getCurrentGameState";
+import saveGameBoard from "./api/saveGameBoard";
+
+export const global = { stop: false };
dotenv.config();
const app = express();
@@ -25,6 +28,7 @@ app.get("/startPoint", startPoint)
app.post("/login", login);
app.post("/readyStateToggle", readyStateToggle);
app.post("/getCurrentGameState", getCurrentGameState);
+app.post("/saveGameBoard", saveGameBoard);
app.listen(PORT, () => {
diff --git a/backend/ts/startGame.ts b/backend/ts/startGame.ts
index 4188d29..eb19bc0 100644
--- a/backend/ts/startGame.ts
+++ b/backend/ts/startGame.ts
@@ -1,41 +1,16 @@
import { } from "../../helpers/helpers";
-import { makeQuery, Color, GameBoard, Chequer, Coordinates, Data } from "../../helpers/helpersBack";
-import { Request, Response } from "express";
+import { makeQuery, nextTurnEndsAt, Color, GameBoard, Chequer, Coordinates, Data, getData, HomesOrBases, Square, tColors } from "../../helpers/helpersBack";
-export default async function startGame(req: Request, res: Response) {
- if (req.session === undefined) {
- res.status(500);
- res.send("");
- return;
- }
-
- makeQuery("UPDATE `fia` SET `started` = 1 WHERE `id`= ?", [req.session.gid]);
- let dbRes: {gameBoard: GameBoard, data: Data}
- = (await makeQuery("SELECT `gameBoard`, `playersCount` FROM `fia` WHERE `id` = ?", [req.session.gid]))[0];
+export default async function startGame(gid: number) {
+ let dbRes: {gameBoard: GameBoard, data: Data} =
+ (await makeQuery("SELECT `gameBoard`, `data` FROM `fia` WHERE `id` = ?", [gid]))[0];
for (let player of dbRes.data) {
- let chequer: Chequer = { color: player.color, x: 1, y: 1 },
- start: Coordinates;
-
- switch (player.color) {
- case Color.red: start = { x: 1, y: 1 }; break;
- case Color.blue: start = { x: 8, y: 1 }; break;
- case Color.yellow: start = { x: 1, y: 8 }; break;
- default /* Color.green */: start = { x: 8, y: 8 }; break;
- // case Color.green: start = { x: 8, y: 8 }; break;
+ for(let square of dbRes.gameBoard.bases[player.color as keyof HomesOrBases]) {
+ square.chequer = player.color;
}
-
- for (let i = 0; i < 2; i++) {
- for (let j = 0; j < 2; j++) {
- //@ts-ignore - 8 + 1 <= 11 which is max of Coordinates
- [chequer.x, chequer.y] = [start.x + i, start.y + j];
- }
- }
-
- dbRes.gameBoard.push(chequer);
}
- await makeQuery("UPDATE `fia` SET `gameBoard` = ? WHERE `id`= ?", [dbRes.gameBoard, req.session.gid]);
-
- res.send("");
+ await makeQuery("UPDATE `fia` SET `gameBoard` = ?, `started` = 1, `timeTillTurnEnd` = ? WHERE `id`= ?",
+ [dbRes.gameBoard, nextTurnEndsAt(), gid]);
} \ No newline at end of file
diff --git a/frontend/ts/login.ts b/frontend/ts/login.ts
index ec4defa..2e50884 100644
--- a/frontend/ts/login.ts
+++ b/frontend/ts/login.ts
@@ -5,7 +5,7 @@ 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" value="maks" required>
+ <input type="text" name="username" required>
<button type="button" class="btn btn-light btn-lg" onclick="Login.login">Starta spelet</button>
</div>
`;
@@ -13,12 +13,14 @@ class Login {
static async start() {
let res = await (await fetch("/startPoint")).json();
if (res.status === true) {
- new StartGame(JSON.parse(res.data[0].data));
+ new StartGame({ data: res.data.data, uid: res.uid });
} else {
document.body.innerHTML = Login.html;
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();
}
}
@@ -26,9 +28,9 @@ class Login {
static async login(username = "") {
if (username === "")
username = document.getElementsByTagName("input")[0].value;
-
+
let res = await Helpers.mFetch("/login", { name: username });
- new StartGame(await res.json());
+ new StartGame(res);
}
}
Login.start(); \ No newline at end of file
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
+}
diff --git a/frontend/ts/timer.ts b/frontend/ts/timer.ts
new file mode 100644
index 0000000..f8dab25
--- /dev/null
+++ b/frontend/ts/timer.ts
@@ -0,0 +1,30 @@
+export default class Timer {
+ divTimer!: HTMLElement;
+
+ interval!: any;
+ async start(playerIndex: number, finishTime: number): Promise<void> {
+ return new Promise(resolve => {
+ let divTimer = document.getElementById(`${playerIndex}-player-time`);
+ if (divTimer === null)
+ throw new Error("divTimer doesn't Exist");
+ else
+ this.divTimer = divTimer;
+
+ this.interval = setInterval(() => {
+ this.updateDisplay(finishTime - Date.now(), resolve);
+ }, 1000);
+ })
+ }
+
+ updateDisplay(time: number, resolve: Function): void {
+ let secondsElapsed = Math.floor(time / 1000);
+ this.divTimer.innerHTML = secondsElapsed.toString();
+ if (secondsElapsed === 0) {
+ resolve();
+ clearInterval(this.interval);
+ }
+ }
+ stop(): void {
+ clearInterval(this.interval);
+ }
+} \ No newline at end of file
diff --git a/helpers/helpers.ts b/helpers/helpers.ts
index 03bc7d7..80fb5ab 100644
--- a/helpers/helpers.ts
+++ b/helpers/helpers.ts
@@ -23,8 +23,11 @@ export default class Helpers {
}
static dbResToFiaTable(dbRes: dbRes): fiaTable {
- if (typeof dbRes.data === "string")
+ if (typeof dbRes.data === "string") {
+ console.log("dbRes.data: ", dbRes.data);
+ console.log("dbRes.data as string: ", JSON.stringify(dbRes.data));
dbRes.data = JSON.parse(dbRes.data);
+ }
else
throw new Error("dbResToFiaTable : wrong $1 type; ");
@@ -32,11 +35,11 @@ export default class Helpers {
return dbRes;
}
- static checkApiRes(res: any, nRes = {} as Response): any {
- if (res.api === false) {
+ static checkApiRes(res: any, nRes = {} as Response): boolean {
+ if (res.success === false) {
if (Object.keys(nRes).length === 0) {
// @ts-ignore - here error is because backend tsc is checking this file, where lib: DOM is not present
- alert("API Error!");
+ // alert("API Error!");
throw new Error("API Error!");
} else {
nRes.status(500);
@@ -46,19 +49,24 @@ export default class Helpers {
}
if (Object.keys(nRes).length !== 0)
nRes.status(200);
- return res;
+ return true;
}
static async mFetch(url: string, body: object): Promise<any> {
//@ts-ignore - this doesn't exist for backend, but its never used there
- return fetch(url, {
+ let res: any = await (await fetch(url, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify(body)
- }).then(Helpers.checkApiRes);
+ })).json();
+ if (this.checkApiRes(res) == true)
+ return res;
+ else
+ throw new Error("API Error!");;
+
}
static getRandomInt(min: number, max: number) {
@@ -66,4 +74,15 @@ export default class Helpers {
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min); //The maximum is exclusive and the minimum is inclusive
}
+
+ static Color: Colors = {
+ blue: 0,
+ red: 1,
+ green: 2,
+ yellow: 3,
+ 0: 0,
+ 1: 1,
+ 2: 2,
+ 3: 3
+ };
} \ No newline at end of file
diff --git a/helpers/helpersBack.ts b/helpers/helpersBack.ts
index d594c03..5aaae77 100644
--- a/helpers/helpersBack.ts
+++ b/helpers/helpersBack.ts
@@ -1,10 +1,20 @@
import fetch from "node-fetch";
import { Response } from "express";
import Helpers from "./helpers";
+import { global } from "../backend/ts/index";
export { Helpers };
-export async function makeQuery(query: string, params: Array<any>): Promise<any> {
- let t = await (
+export const API_RES = {
+ success: '{"success": true}',
+ failure: '{"success": false}',
+};
+export async function makeQuery(query: string, params: Array<any>): Promise<Array<any>> {
+ // console.log("params are ", JSON.stringify({
+ // apiKey: process.env.API_KEY,
+ // query: query,
+ // params: params
+ // }));
+ let t: any = await (
await fetch("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.php", {
method: "POST",
headers: {
@@ -18,8 +28,28 @@ export async function makeQuery(query: string, params: Array<any>): Promise<any>
})
})
).text();
- // console.log(t);
- return JSON.parse(t);
+ try {
+ t = JSON.parse(t)[0];
+ } catch (e) {
+ console.log(`dbResposnse to "${query}"`, ` is '${t}' (typeof res ${typeof t})`);
+ console.log(`dbResposnse as object as string: '${JSON.stringify(t)}'`);
+ }
+ for (const p in t) {
+ if (["data", "gameBoard"].includes(p))
+ t[p] = JSON.parse(t[p]);
+ }
+ return [t];
+}
+
+export async function getData(gid: number): Promise<Data> {
+ let data = (await makeQuery("SELECT `data` FROM `fia` WHERE `id` = ?", [gid]))[0].data;
+ if (typeof data === "string") {
+ data = JSON.parse(data) as Data;
+ return data;
+ } else {
+ console.log(data);
+ throw new Error("Data is not a object");
+ }
}
export async function mFetch(url: string, body: object, res: Response): Promise<Response> {
@@ -33,6 +63,19 @@ export async function mFetch(url: string, body: object, res: Response): Promise<
}).then(fRes => Helpers.checkApiRes(fRes, res)) as Promise<Response>;
}
+export function nextTurnEndsAt(): number {
+ return Date.now() + (60 * 1000);
+}
+
+export async function sleep(ms: number) {
+ return new Promise(resolve => setTimeout(resolve, ms));
+}
+export async function waitForQueue(): Promise<void> {
+ while(global.stop === true) {
+ await sleep(200);
+ }
+}
+
export interface Colors {
blue: number;
red: number;
@@ -60,18 +103,49 @@ export type Data = Array<DataObject>;
export interface DataObject {
id: any;
index: number;
+ ready: boolean;
color: tColors;
name: string;
}
-export interface Chequer extends Coordinates {
+export interface GhostWhere {
+ from: "base" | "map" | "home";
+ oldIndex: number;
+ to: "base" | "map" | "home";
+ newIndex: number;
+}
+export interface Ghost {
+ where: GhostWhere;
color: tColors;
+ coords?: Coordinates;
+}
+export interface Chequer {
+ color: tColors;
+ ghost?: Ghost; // number; // 1 | 2 | 3 | 4 | 5 | 6;
};
-
export interface Coordinates {
- x: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
- y: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
+ x: number; //0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
+ y: number; //0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
+}
+export interface Square extends Coordinates {
+ chequers: Array<Chequer>;
+ start: -1 | tColors;
}
-export type GameBoard = Array<Chequer>;
+export interface HoBSquare extends Coordinates {
+ chequer: tColors;
+ ghost?: Ghost; // number; // 1 | 2 | 3 | 4 | 5 | 6;
+}
+export interface HomesOrBases {
+ 0: Array<HoBSquare>;
+ 1: Array<HoBSquare>;
+ 2: Array<HoBSquare>;
+ 3: Array<HoBSquare>;
+}
+
+export interface GameBoard {
+ map: Array<Square>;
+ homes: HomesOrBases;
+ bases: HomesOrBases;
+};
export interface fiaTable {
id: number;
data: Data;
diff --git a/package.json b/package.json
index eb707c4..7836d62 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"start:build-front": "tsc -p ./frontend/tsconfig.json -w",
"start:build-back": "tsc -p ./backend/tsconfig.json -w",
"start:start": "nodemon ./backend/js/backend/ts/index.js",
- "start": "concurrently \"yarn:start:*\""
+ "start": "concurrently yarn:start:*"
},
"dependencies": {
"dotenv": "^8.2.0",
diff --git a/public/css/fia.css b/public/css/fia.css
new file mode 100644
index 0000000..fc660aa
--- /dev/null
+++ b/public/css/fia.css
@@ -0,0 +1,77 @@
+.game-table {
+ width: 660px;
+ height: 660px;
+ margin: 0 auto;
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/fia.png");
+ background-size: contain;
+ border-collapse: separate;
+ padding: 0;
+ border-spacing: 0;
+}
+.game-table tr {
+ padding: 0;
+ margin: 0;
+}
+.game-table td {
+ margin: 0;
+ padding: 0;
+ width: 60px;
+ height: 60px;
+ border-collapse: separate;
+}
+#timer {
+ height: 80px;
+ width: 160px;
+ border: 2px solid red;
+}
+#dice {
+ margin: 50px auto;
+ height: 100px;
+ width: 100px;
+ border: 2px solid blue;
+ background-size: contain;
+}
+.dice-1 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-1.png");
+}
+.dice-2 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-2.png");
+}
+.dice-3 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-3.png");
+}
+.dice-4 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-4.png");
+}
+.dice-5 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-5.png");
+}
+.dice-6 {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/dice-6.png");
+}
+
+.player-name :nth-child(even) {
+ float: right;
+}
+
+.chequer {
+ background-size: contain;
+ border-radius: 50%;
+ color: palevioletred;
+}
+.chequer-red {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/chequer-red.png");
+ border: 4px solid black;
+}
+.chequer-blue {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/chequer-blue.png");
+ border: 4px solid black;
+}
+.chequer-green {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/chequer-green.png");
+ border: 4px solid black;
+}
+.chequer-yellow {
+ background-image: url("https://jopek.eu/maks/szkola/apkKli/fiaFiles/chequer-yellow.png");
+ border: 4px solid black;
+}
diff --git a/public/index.html b/public/index.html
index d7ea523..a5b174a 100644
--- a/public/index.html
+++ b/public/index.html
@@ -7,6 +7,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Fia</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
+ <link rel="stylesheet" href="css/fia.css">
</head>
<body class="bg-dark text-white">
diff --git a/public/map.html b/public/map.html
index 23ef7de..980cebe 100644
--- a/public/map.html
+++ b/public/map.html
@@ -2,13 +2,13 @@
<table class="table table-dark table-sm">
<tbody>
<tr>
- <td class="player-name rounded-pill text-center"></td>
+ <td class="player-name rounded-pill text-center"><span></span><span id="0-player-time"></span></td>
<td></td>
- <td class="player-name rounded-pill text-center"></td>
+ <td class="player-name rounded-pill text-center"><span></span><span id="1-player-time"></span></td>
<td></td>
- <td class="player-name rounded-pill text-center"></td>
+ <td class="player-name rounded-pill text-center"><span></span><span id="2-player-time"></span></td>
<td></td>
- <td class="player-name rounded-pill text-center"></td>
+ <td class="player-name rounded-pill text-center"><span></span><span id="3-player-time"></span></td>
<td></td>
<td class="text-center rounded-pill">
<input class="form-check-input" type="checkbox" />
@@ -18,9 +18,14 @@
</tbody>
</table>
<div class="container-flex text-center">
- <canvas id="map" width="660" height="660ZZZZ" class="border border-danger">
- Din webbläsare stöder inte canvas, vilket betyder att du inte kan spela
- fia
- </canvas>
+ <div class="row">
+ <div class="col-8">
+ <table class="game-table" id="map"></table>
+ </div>
+ <div class="col-2">
+ <div id="dice"></div>
+ <button type="button" class="btn btn-light" style="display: none;">Kasta tärning</button>
+ </div>
+ </div>
</div>
</div>