UNPKG

football-scoreboard

Version:

A live football World Cup scoreboard library.

99 lines (98 loc) 4.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Scoreboard = void 0; const match_1 = require("./match"); const constants_1 = require("./constants"); class Scoreboard { constructor() { this.matches = new Map(); this.sortedMatches = []; this.activeTeams = new Set(); } startMatch(homeTeam, awayTeam) { const { homeTeamNormalized, awayTeamNormalized } = this.getNormalizedTeams(homeTeam, awayTeam); if (this.isSameTeam(homeTeamNormalized, awayTeamNormalized)) throw new Error(constants_1.ERROR_SAME_TEAM); if (this.isPlaying(homeTeamNormalized, awayTeamNormalized)) throw new Error(constants_1.ERROR_ALREADY_PLAYING); const matchKey = this.generateMatchKey(homeTeamNormalized, awayTeamNormalized); const match = new match_1.Match(homeTeam, awayTeam); const insertIndex = this.findInsertionIndex(match); this.matches.set(matchKey, match); this.sortedMatches.splice(insertIndex, 0, match); this.activeTeams.add(homeTeamNormalized); this.activeTeams.add(awayTeamNormalized); } updateScore(homeTeam, awayTeam, newHomeScore, newAwayScore) { const { homeTeamNormalized, awayTeamNormalized } = this.getNormalizedTeams(homeTeam, awayTeam); const matchKey = this.generateMatchKey(homeTeamNormalized, awayTeamNormalized); const match = this.matches.get(matchKey); if (match) { match.updateScore(newHomeScore, newAwayScore); const removeIndex = this.sortedMatches.indexOf(match); this.sortedMatches.splice(removeIndex, 1); const insertIndex = this.findInsertionIndex(match); this.sortedMatches.splice(insertIndex, 0, match); } else throw new Error(constants_1.ERROR_NO_MATCH); } finishMatch(homeTeam, awayTeam) { const { homeTeamNormalized, awayTeamNormalized } = this.getNormalizedTeams(homeTeam, awayTeam); const matchKey = this.generateMatchKey(homeTeamNormalized, awayTeamNormalized); const match = this.matches.get(matchKey); if (match) { const removeIndex = this.sortedMatches.indexOf(match); this.sortedMatches.splice(removeIndex, 1); this.matches.delete(matchKey); this.activeTeams.delete(homeTeamNormalized); this.activeTeams.delete(awayTeamNormalized); } else throw new Error(constants_1.ERROR_NO_MATCH); } getSummary() { return this.sortedMatches.map((match, index) => `${index + 1}. ${match.homeTeam} ${match.homeScore} - ${match.awayTeam} ${match.awayScore}`); } findInsertionIndex(newMatch) { const totalScore = newMatch.homeScore + newMatch.awayScore; let low = 0; let high = this.sortedMatches.length; while (low < high) { const mid = Math.floor((low + high) / 2); const midMatch = this.sortedMatches[mid]; const midScore = midMatch.homeScore + midMatch.awayScore; if (totalScore > midScore) { high = mid; } else if (totalScore < midScore) { low = mid + 1; } else if (newMatch.startTime > midMatch.startTime) { high = mid; } else { low = mid + 1; } } return low; } getNormalizedTeams(homeTeam, awayTeam) { const normalize = (team) => team.trim().toLowerCase(); return { homeTeamNormalized: normalize(homeTeam), awayTeamNormalized: normalize(awayTeam), }; } generateMatchKey(homeTeamNormalized, awayTeamNormalized) { return `${homeTeamNormalized} vs ${awayTeamNormalized}`; } isSameTeam(homeTeamNormalized, awayTeamNormalized) { return homeTeamNormalized === awayTeamNormalized; } isPlaying(homeTeamNormalized, awayTeamNormalized) { return (this.activeTeams.has(homeTeamNormalized) || this.activeTeams.has(awayTeamNormalized)); } } exports.Scoreboard = Scoreboard;