football-scoreboard
Version:
A live football World Cup scoreboard library.
99 lines (98 loc) • 4.19 kB
JavaScript
"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;