glicko-ts
Version:
A TypeScript implementation of the Glicko-1 rating system.
127 lines (126 loc) • 7.78 kB
TypeScript
/**
* Glicko rating system implementation.
* This class provides methods for calculating and updating Glicko ratings for players based on match outcomes.
* The Glicko system accounts for rating deviation (RD), a measure of the uncertainty in a player's skill level.
* A lower RD indicates higher confidence in the rating, while a higher RD suggests more uncertainty.
*/
import { Player } from './interfaces/player';
import { Match } from './interfaces/match';
import { GlickoConfig } from './config/glicko_config';
export declare class Glicko {
private config;
/**
* Creates an instance of the Glicko rating system calculator.
* @param {Partial<GlickoConfig>} [config] Optional configuration settings.
*/
constructor(config?: Partial<GlickoConfig>);
/**
* Provides the default configuration values for the Glicko system.
* @returns {GlickoConfig} The default configuration.
* @private
*/
private defaultConfig;
/**
* Creates a new Player object with initial or overridden rating/RD values.
* @param {Partial<Player>} [overrides] Optional values to override defaults.
* @returns {Player} A new Player object.
*/
initializeNewPlayer(overrides?: Partial<Player>): Player;
/**
* Updates a player's Rating Deviation (RD) based on inactivity.
* RD increases towards a ceiling over time if the player hasn't played.
* @param {Player} player The player's state *before* the inactivity period.
* @param {number} daysSinceLastActive The number of days since the player's last rated match.
* @returns {Player} A new Player object with the potentially updated RD.
* @throws {Error} If daysSinceLastActive is negative.
*/
updateRDForInactivity(player: Player, daysSinceLastActive: number): Player;
/**
* Calculates the expected outcome (E) of a match for the player against an opponent.
* Represents the player's expected score (roughly, probability of winning) based on ratings and RDs.
* Formula: E = 1 / (1 + 10^(-g(RD_opp)*(r - r_opp)/400))
* @param {number} playerRating Player's rating (r).
* @param {number} opponentRating Opponent's rating (r_opp).
* @param {number} opponentRd Opponent's RD (RD_opp).
* @returns {number} Expected outcome for the player (0 to 1).
* @private
*/
private calculateExpectedOutcome;
/**
* Calculates the sum of factors related to the expected variance of match outcomes within a rating period.
* This sum quantifies the amount of information gained from the matches played, which influences the change in Rating Deviation (RD).
* Formula: sum[ g(opponent_RD)^2 * E * (1-E) ]
* A higher value indicates more information was gained, contributing to a larger RD decrease.
* @param {number} playerRating Rating of the player at the start of the period.
* @param {number} playerRd RD of the player at the start of the period.
* @param {Match[]} matchs Matches played during the rating period.
* @returns {number} The calculated sum. Returns 0 if matchs is empty/invalid.
* @throws {Error} If playerRd is not positive.
* @private
*/
private sumMatchVarianceFactors;
/**
* Calculates the sum of weighted differences between actual match scores and expected scores.
* This sum represents overall performance relative to expectation, adjusted for opponent RD.
* It's the primary factor determining the rating change direction and magnitude.
* Formula: sum[ g(opponent_RD) * (Actual_Score - Expected_Score) ]
* A positive sum indicates better-than-expected performance (rating increases); negative indicates worse (rating decreases).
* @param {number} playerRating Rating of the player at the start of the period.
* @param {number} playerRd RD of the player at the start of the period.
* @param {Match[]} matchs Matches played during the rating period.
* @returns {number} The calculated sum. Returns 0 if matchs is empty/invalid.
* @throws {Error} If playerRd is not positive.
* @private
*/
private sumWeightedScorePerformance;
/**
* Calculates the player's new Rating (r') for the end of the rating period.
* Determined by initial rating adjusted by overall performance (weightedScorePerformanceSum),
* scaled by the system constant (q) and the square of the new RD'.
* Formula: r' = r + q * (RD')^2 * weightedScorePerformanceSum
* @param {number} initialRating Player's rating at the start of the period.
* @param {number} newRd The newly calculated unrounded RD' (output of calculateNewRD).
* @param {number} weightedScorePerformanceSum Sum representing performance vs expectation.
* @returns {number} The new rating (unrounded).
* @private
*/
private calculateNewRating;
/**
* Calculates the player's new Rating Deviation (RD') for the end of the rating period.
* Determined by initial RD and information gained from matches (matchVarianceFactorSum). More information leads to a lower RD.
* Formula: RD' = 1 / sqrt( 1/RD^2 + q^2 * matchVarianceFactorSum )
* @param {number} initialRd Player's RD at the start of the period.
* @param {number} matchVarianceFactorSum Sum quantifying information gain from matches.
* @returns {number} The new rating deviation (unrounded). Returns initialRd if no info gained.
* @throws {Error} If initialRd is not positive.
* @private
*/
private calculateNewRD;
/**
* Processes all matches for a player within a single rating period to update their Glicko-1 rating and RD.
* This is the main public method used to calculate rating updates after a set of games representing one period.
*
* The process involves these steps:
* 1. Optionally updates the player's RD based on inactivity since their last known activity.
* 2. Calculates intermediate factors based on the match outcomes during the period compared to expectations.
* 3. Computes the new RD' based on the RD at the start of the period and the information gained from matches.
* 4. Computes the new Rating' based on the rating at the start of the period, the performance during the period, and the new RD'.
* 5. Returns the updated player state, including the new rating, new RD (rounded), and an updated `lastPlayedMatch` timestamp.
*
* @param {Player} player The player's state (rating, RD, lastPlayedMatch) *before* the start of this rating period.
* @param {Match[]} matchs An array of all matches the player participated in *during* this rating period.
* Each match object should contain the opponent's state (at the time of the match, or start of period)
* and the score achieved by the player (e.g., 1=win, 0.5=draw, 0=loss).
* @param {number} [daysSinceLastActive] Optional: The number of days that elapsed between the `player.lastPlayedMatch` date
* (from the input `player` object) and the *start* of this rating period.
* If provided and greater than 0, the player's RD will be updated for
* inactivity *before* processing the matches in this period.
* @returns {Player} The updated state of the player after processing the rating period, with updated rating, RD,
* and `lastPlayedMatch` set to the current time of processing. If no matches are provided
* (matchs array is empty or null), it returns the player's state after only the potential
* inactivity update (and `lastPlayedMatch` is NOT updated in this case).
* @throws {Error} Can throw if internal calculations encounter issues (e.g., non-positive RD input to helpers)
* or if `daysSinceLastActive` is negative (via `updateRDForInactivity`).
*/
processGameResults(player: Player, matchs: Match[], daysSinceLastActive?: number): Player;
}