UNPKG

@lovebowls/leaguejs

Version:

A framework-agnostic JavaScript library for managing leagues, teams, and matches

113 lines (104 loc) 3.47 kB
/** * League table calculator for leagueJS */ export class LeagueTableCalculator { /** * Create a new league table calculator * @param {League} league - League to calculate table for */ constructor(league) { this.league = league; } calculateTeamStats(teamId) { const team = this.league.getTeam(teamId); if (!team) { throw new Error('Team not found'); } const matches = this.league.getTeamMatches(teamId); const stats = { teamId: teamId, teamName: team.name, played: 0, won: 0, drawn: 0, lost: 0, shotsFor: 0, shotsAgainst: 0, points: 0, rinksWon: 0, rinksDrawn: 0, rinksLost: 0 }; matches.forEach(match => { if (!match.result) return; const isHome = match.homeTeam._id === teamId; const teamScore = isHome ? match.result.homeScore : match.result.awayScore; const opponentScore = isHome ? match.result.awayScore : match.result.homeScore; stats.played++; stats.shotsFor += teamScore; stats.shotsAgainst += opponentScore; if (teamScore > opponentScore) { stats.won++; stats.points += this.league.settings.pointsForWin; } else if (teamScore < opponentScore) { stats.lost++; stats.points += this.league.settings.pointsForLoss; } else { stats.drawn++; stats.points += this.league.settings.pointsForDraw; } // Calculate rink points if enabled if (this.league.settings.rinkPoints?.enabled && match.result.rinkScores) { const rinkResults = match.getRinkResults(); if (rinkResults) { if (isHome) { stats.rinksWon += rinkResults.homeWins; stats.rinksDrawn += rinkResults.draws; stats.rinksLost += rinkResults.awayWins; stats.points += (rinkResults.homeWins * this.league.settings.rinkPoints.pointsPerRinkWin) + (rinkResults.draws * this.league.settings.rinkPoints.pointsPerRinkDraw); } else { stats.rinksWon += rinkResults.awayWins; stats.rinksDrawn += rinkResults.draws; stats.rinksLost += rinkResults.homeWins; stats.points += (rinkResults.awayWins * this.league.settings.rinkPoints.pointsPerRinkWin) + (rinkResults.draws * this.league.settings.rinkPoints.pointsPerRinkDraw); } } } }); return stats; } calculateLeagueTable() { return this.league.teams .map(team => { const stats = this.calculateTeamStats(team._id); return { teamId: team._id, teamName: team.name, ...stats, shotDifference: stats.shotsFor - stats.shotsAgainst }; }) .sort((a, b) => { // Sort by points first if (b.points !== a.points) { return b.points - a.points; } // Then by matches played (teams that have played should be higher) if (b.played !== a.played) { return b.played - a.played; } // Then by shot difference if (b.shotDifference !== a.shotDifference) { return b.shotDifference - a.shotDifference; } // Then by shots scored if (b.shotsFor !== a.shotsFor) { return b.shotsFor - a.shotsFor; } // Finally by team name return a.teamName.localeCompare(b.teamName); }); } }