From 06d6cf87acfd4582beb6beb314c6f1d7c3fe9675 Mon Sep 17 00:00:00 2001 From: Karan Jayachandra Date: Fri, 14 Nov 2025 17:46:28 +0100 Subject: Simplified the file even more though longer --- src/main.js | 116 +++++++++++++++++++++++-------------- src/manage.js | 130 +++++++++++++++++++++++++++-------------- src/timer.js | 89 ++++++++++++++++++++++++++++ src/utils.js | 182 ---------------------------------------------------------- 4 files changed, 248 insertions(+), 269 deletions(-) create mode 100644 src/timer.js delete mode 100644 src/utils.js diff --git a/src/main.js b/src/main.js index a0ec6bc..7e9f988 100644 --- a/src/main.js +++ b/src/main.js @@ -2,14 +2,24 @@ import "notyf/notyf.min.css"; import "bulma/css/bulma.css"; import "@fortawesome/fontawesome-free/css/all.css"; import "./style.css"; -import { Manager, Timer } from "./utils"; -import { CourtManager, PlayerManager } from "./manage"; +import { Notyf } from "notyf"; +import { Timer } from "./utils"; import { Team, Game } from "./data"; +import { Manager, CourtManager, PlayerManager, GuestManager } from "./manage"; + +export function getNotifier(seconds) { + return new Notyf({ + duration: seconds * milliSecond, + position: { x: "center", y: "top" }, + dismissible: true, + }); +} export class GameManager extends Manager { - t = new Timer(); + timer = new Timer(); courts = new CourtManager(); players = new PlayerManager(); + guests = new GuestManager(); constructor() { super("Game", 12); @@ -32,30 +42,23 @@ export class GameManager extends Manager { return new Game(id, status, teamOne, teamTwo); } addBehaviour() { - let description = this.isConfirmed() ? "Round " + this.round : "Proposal"; + let confirmedStatus = this.data[0].status; + let description = confirmedStatus ? "Round " + this.round : "Proposal"; document.getElementById("Game_description").innerHTML = description; } - isConfirmed() { - return this.data[0].status; - } - getBlockedGames() { + addBlockedGames() { const inactiveCourts = this.courts.inactive(); console.log("Total reserved courts are " + inactiveCourts.length + "."); - let games = []; for (let court of inactiveCourts) { - games.push(this.createItem(court.id, "RESERVED")); + this.data.push(this.createItem(court.id, "RESERVED")); } - return games; } - inactive(courts) { - let games = []; + addInactiveGames(courts) { for (let court of courts) { - games.push(this.createItem(court.id)); + this.data.push(this.createItem(court.id)); } - return games; } - active(courts, players) { - let games = []; + addActiveGames(courts, players) { for (let index = 0; index < courts.length; index++) { const startIndex = 4 * index; const endIndex = startIndex + 4; @@ -64,33 +67,67 @@ export class GameManager extends Manager { const team_2 = new Team(courtPlayers[1].name, courtPlayers[2].name); const game = new Game(courts[index].id, false, team_1, team_2); game.print(); - games.push(game); + this.data.push(game); } - return games; + } + getPossibleGameCount() { + let activeRegularCount = this.players.active().length; + let activeGuestCount = this.guests.active().length; + let activePlayerCount = activeRegularCount + activeGuestCount; + console.log("There are a total of " + activePlayerCount + " players available."); + let activeCourtCount = this.courts.active().length; + console.log("There are a total of " + activeCourtCount + " courts available."); + let possibleMatches = Math.min(Math.floor(activePlayerCount / 4), activeCourtCount); + return possibleMatches; + } + selectPlayers(count) { + console.log("Required players are " + count); + let activePlayers = this.players.active(); + const activeGuests = this.guests.active(); + activePlayers = activePlayers.concat(activeGuests); + console.log("Active players are:"); + console.log( + activePlayers + .map((i) => { + return i.name; + }) + .join(",") + ); + const shuffledPlayers = shuffle(activePlayers); + shuffledPlayers.sort((a, b) => a.totalPlayed - b.totalPlayed); + const selectedPlayers = shuffledPlayers.slice(0, count); + selectedPlayers.sort((a, b) => a.level - b.level); + console.log("Selected players are:"); + console.log( + selectedPlayers + .map((i) => { + return i.name; + }) + .join(",") + ); + return selectedPlayers; } propose() { console.log("Proposing new games!"); - let possibleMatches = getMatchCount( - this.players.data.concat(this.players.g.data), - this.courts.data - ); + let possibleMatches = this.getPossibleGameCount(); console.log("Total possible matches are " + possibleMatches + "."); - this.data = this.getBlockedGames(); + this.data = []; + this.addBlockedGames(); const activeCourts = this.courts.active(); const unusedCourts = activeCourts.slice(possibleMatches + 1); - this.data = this.data.concat(this.inactive(unusedCourts)); + this.addInactiveGames(unusedCourts); const usedCourts = activeCourts.slice(0, possibleMatches); let requiredPlayerCount = possibleMatches * 4; - const selectedPlayers = this.players.propose(requiredPlayerCount); + const selectedPlayers = this.selectPlayers(requiredPlayerCount); console.log("The matches are:"); - this.data = this.data.concat(this.active(usedCourts, selectedPlayers)); + this.addActiveGames(usedCourts, selectedPlayers); this.data.sort((a, b) => a.id - b.id); this.render(); } confirm() { - if (this.isConfirmed()) { - const notification = new Notyf(); - notification.error("Create a proposal first!"); + let confirmedStatus = this.data[0].status; + if (confirmedStatus) { + getNotifier().error("Create a proposal first!"); return; } console.log("Confirm the proposal for round " + this.round + "."); @@ -116,19 +153,12 @@ export class GameManager extends Manager { } } -function getMatchCount(players, courts) { - courts = courts.filter(function (c) { - return c.status; - }); - console.log("There are a total of " + courts.length + " courts available."); - console.log(players); - players = players.filter(function (p) { - return p.status; - }); - console.log("There are a total of " + players.length + " players available."); - var possibleMatches = Math.floor(players.length / 4); - possibleMatches = Math.min(possibleMatches, courts.length); - return possibleMatches; +function shuffle(array) { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; } function addGameBehaviour(g) { diff --git a/src/manage.js b/src/manage.js index 31e828d..ef48f8e 100644 --- a/src/manage.js +++ b/src/manage.js @@ -1,5 +1,70 @@ import { Court, Guest, Player } from "./data"; -import { shuffle, Manager, randomLevel, randomStatus } from "./utils"; + +export class Manager { + constructor(description, maxCount) { + this.description = description; + this.maxCount = maxCount; + this.data = []; + this.count = this.data.length; + let data = JSON.parse(localStorage.getItem(this.description)); + if (data === null || data.length === 0) { + this.generate(); + return; + } + this.load(data); + } + generate() { + for (let i = 0; i < this.maxCount; i++) { + this.data.push(this.createItem(i)); + } + console.log("Generated " + this.data.length + " " + this.description); + this.store(); + this.render(); + } + load(data) { + for (let i = 0; i < data.length; i++) { + this.data.push(this.loadItem(data[i])); + } + console.log("Loaded " + this.data.length + " " + this.description); + this.render(); + } + store() { + let stringData = JSON.stringify(this.data); + localStorage.setItem(this.data[0].description, stringData); + } + render() { + let renderedHTML = this.data + .map((i) => { + return i.render(); + }) + .join(""); + let elementId = this.data[0].description + "_list"; + document.getElementById(elementId).innerHTML = renderedHTML; + this.addBehaviour(); + } + addBehaviour() { + for (let idx = 0; idx < this.data.length; ++idx) { + const elementId = this.data[0].description + "_" + this.data[idx].id; + const p = document.getElementById(elementId); + p.addEventListener("click", () => { + this.data[idx].toggle(); + this.store(); + p.classList.toggle("is-success"); + p.classList.toggle("is-danger"); + }); + } + } + active() { + return this.data.filter(function (c) { + return c.status; + }); + } + inactive() { + return this.data.filter(function (c) { + return !c.status; + }); + } +} export class CourtManager extends Manager { constructor() { @@ -15,6 +80,19 @@ export class CourtManager extends Manager { } } +export function randomStatus() { + return Math.random() < 0.5; +} + +function normalize(data) { + let factor = Number(document.getElementById("skill").value); + console.log("Normalize skill by a factor of " + factor + "."); + return data.map(function (p) { + p.skill = Math.ceil(p.skill / factor); + return p; + }); +} + export class GuestManager extends Manager { constructor() { super("Guest", 12); @@ -30,16 +108,15 @@ export class GuestManager extends Manager { } active(factor) { factor = typeof factor !== "undefined" ? factor : 1; - let data = super.active(); - console.log("Normalize skill by a factor of " + factor + "."); - let players = data.map(function (p) { - p.skill = Math.ceil(p.skill / factor); - return p; - }); - return players; + return normalize(super.active()); } } +export function randomLevel() { + const max_level = 10; + return Math.floor(Math.random() * max_level + 1); +} + export class PlayerManager extends Manager { constructor() { super("Regular", 71); @@ -76,42 +153,7 @@ export class PlayerManager extends Manager { } active(factor) { factor = typeof factor !== "undefined" ? factor : 1; - let data = super.active(); - console.log("Normalize skill by a factor of " + factor + "."); - let players = data.map(function (p) { - p.skill = Math.ceil(p.skill / factor); - return p; - }); - return players; - } - propose(count) { - console.log("Required players are " + count); - let factor = Number(document.getElementById("skill").value); - console.log("Skill normalized by a factor of " + factor + "."); - let activePlayers = this.active(factor); - const activeGuests = this.g.active(factor); - activePlayers = activePlayers.concat(activeGuests); - console.log("Active players are:"); - console.log( - activePlayers - .map((i) => { - return i.name; - }) - .join(",") - ); - const shuffledPlayers = shuffle(activePlayers); - shuffledPlayers.sort((a, b) => a.totalPlayed - b.totalPlayed); - const selectedPlayers = shuffledPlayers.slice(0, count); - selectedPlayers.sort((a, b) => a.level - b.level); - console.log("Selected players are:"); - console.log( - selectedPlayers - .map((i) => { - return i.name; - }) - .join(",") - ); - return selectedPlayers; + return normalize(super.active()); } } diff --git a/src/timer.js b/src/timer.js new file mode 100644 index 0000000..7c70550 --- /dev/null +++ b/src/timer.js @@ -0,0 +1,89 @@ +const milliSecond = 1000; + +export class Timer { + pointer = 0; + + constructor() { + this.mins = Number(sessionStorage.getItem("mins")) || 12; + this.running = Boolean(Number(sessionStorage.getItem("running"))) || false; + this.deadline = + Number(sessionStorage.getItem("deadline")) || new Date().getTime(); + if (this.running) { + this.start(false); + } else { + this.reset(); + } + addTimerBehaviour(this); + } + store() { + sessionStorage.setItem("mins", this.mins); + sessionStorage.setItem("running", Number(this.running)); + sessionStorage.setItem("deadline", this.deadline); + } + set(m, s) { + const timer = document.getElementById("timer-display"); + m = m < 10 ? "0" + m : m; + s = s < 10 ? "0" + s : s; + timer.value = `${m}:${s}`; + } + reset() { + clearInterval(this.pointer); + const mins = Math.floor(this.mins); + const secs = (this.mins - mins) * 60; + this.set(mins, secs); + this.running = false; + this.store(); + } + update(ms) { + const m = Math.floor((ms % (milliSecond * 60 * 60)) / (milliSecond * 60)); + const s = Math.floor((ms % (milliSecond * 60)) / milliSecond); + this.set(m, s); + } + refresh(p) { + const now = new Date().getTime(); + const msToDeadline = p.deadline - now; + if (msToDeadline > 0) { + p.update(msToDeadline); + return; + } + p.reset(); + getNotifier().error("Round completed"); + } + start(fresh) { + if (fresh) { + const now = new Date().getTime(); + const msToDeadline = this.mins * 60 * 1000; + this.deadline = now + msToDeadline; + } + this.running = true; + this.store(); + this.pointer = setInterval(this.refresh, 1000, this); + } + change(value) { + this.mins += value; + if (this.mins < 0.5) { + this.mins = 0.5; + } + this.reset(); + } +} + +function addTimerBehaviour(t) { + document.getElementById("timer-start").addEventListener("click", () => { + if (t.running) return; + t.start(1); + }); + document.getElementById("timer-stop").addEventListener("click", () => { + t.reset(); + }); + document.getElementById("timer-inc").addEventListener("click", () => { + if (!t.running) { + t.change(0.5); + } + }); + document.getElementById("timer-dec").addEventListener("click", () => { + if (!t.running) { + t.change(-0.5); + } + }); +} diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index a8d4f07..0000000 --- a/src/utils.js +++ /dev/null @@ -1,182 +0,0 @@ -import { Notyf } from "notyf"; - -const milliSecond = 1000; - -export class Timer { - pointer = 0; - - constructor() { - this.mins = Number(sessionStorage.getItem("mins")) || 12; - this.running = Boolean(Number(sessionStorage.getItem("running"))) || false; - this.deadline = - Number(sessionStorage.getItem("deadline")) || new Date().getTime(); - if (this.running) { - this.start(false); - } else { - this.reset(); - } - addTimerBehaviour(this); - } - store() { - sessionStorage.setItem("mins", this.mins); - sessionStorage.setItem("running", Number(this.running)); - sessionStorage.setItem("deadline", this.deadline); - } - set(m, s) { - const timer = document.getElementById("timer-display"); - m = m < 10 ? "0" + m : m; - s = s < 10 ? "0" + s : s; - timer.value = `${m}:${s}`; - } - reset() { - clearInterval(this.pointer); - const mins = Math.floor(this.mins); - const secs = (this.mins - mins) * 60; - this.set(mins, secs); - this.running = false; - this.store(); - } - update(ms) { - const m = Math.floor((ms % (milliSecond * 60 * 60)) / (milliSecond * 60)); - const s = Math.floor((ms % (milliSecond * 60)) / milliSecond); - this.set(m, s); - } - refresh(p) { - const now = new Date().getTime(); - const msToDeadline = p.deadline - now; - if (msToDeadline > 0) { - p.update(msToDeadline); - return; - } - p.reset(); - getNotifier().error("Round completed"); - } - start(fresh) { - if (fresh) { - const now = new Date().getTime(); - const msToDeadline = this.mins * 60 * 1000; - this.deadline = now + msToDeadline; - } - this.running = true; - this.store(); - this.pointer = setInterval(this.refresh, 1000, this); - } - change(value) { - this.mins += value; - if (this.mins < 0.5) { - this.mins = 0.5; - } - this.reset(); - } -} - -function addTimerBehaviour(t) { - document.getElementById("timer-start").addEventListener("click", () => { - if (t.running) return; - t.start(1); - }); - document.getElementById("timer-stop").addEventListener("click", () => { - t.reset(); - }); - document.getElementById("timer-inc").addEventListener("click", () => { - if (!t.running) { - t.change(0.5); - } - }); - document.getElementById("timer-dec").addEventListener("click", () => { - if (!t.running) { - t.change(-0.5); - } - }); -} - -export class Manager { - constructor(description, maxCount) { - this.description = description; - this.maxCount = maxCount; - this.data = []; - this.count = this.data.length; - let data = JSON.parse(localStorage.getItem(this.description)); - if (data === null || data.length === 0) { - this.generate(); - return; - } - this.load(data); - } - generate() { - for (let i = 0; i < this.maxCount; i++) { - this.data.push(this.createItem(i)); - } - console.log("Generated " + this.data.length + " " + this.description); - this.store(); - this.render(); - } - load(data) { - for (let i = 0; i < data.length; i++) { - this.data.push(this.loadItem(data[i])); - } - console.log("Loaded " + this.data.length + " " + this.description); - this.render(); - } - store() { - let stringData = JSON.stringify(this.data); - localStorage.setItem(this.data[0].description, stringData); - } - render() { - let renderedHTML = this.data - .map((i) => { - return i.render(); - }) - .join(""); - let elementId = this.data[0].description + "_list"; - document.getElementById(elementId).innerHTML = renderedHTML; - this.addBehaviour(); - } - addBehaviour() { - for (let idx = 0; idx < this.data.length; ++idx) { - const elementId = this.data[0].description + "_" + this.data[idx].id; - const p = document.getElementById(elementId); - p.addEventListener("click", () => { - this.data[idx].toggle(); - this.store(); - p.classList.toggle("is-success"); - p.classList.toggle("is-danger"); - }); - } - } - active() { - return this.data.filter(function (c) { - return c.status; - }); - } - inactive() { - return this.data.filter(function (c) { - return !c.status; - }); - } -} - -export function shuffle(array) { - for (let i = array.length - 1; i > 0; i--) { - const j = Math.floor(Math.random() * (i + 1)); - [array[i], array[j]] = [array[j], array[i]]; - } - return array; -} - -export function randomLevel() { - const max_level = 10; - return Math.floor(Math.random() * max_level + 1); -} - -export function randomStatus() { - return Math.random() < 0.5; -} - -export function getNotifier(seconds) { - return new Notyf({ - duration: seconds * milliSecond, - position: { x: "center", y: "top" }, - dismissible: true, - }); -} -- cgit v1.3.1