@lovebowls/leaguejs
Version:
A framework-agnostic JavaScript library for managing leagues, teams, and matches
113 lines (104 loc) • 3.47 kB
JavaScript
/**
* 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);
});
}
}