import { sprintf } from 'sprintf-js' ; import { DeepPartial } from '../../../utils/DeepPartial' ; import { deepMerge } from '../../../utils/DeepMerge' ; import { deepCopy } from '../../../utils/DeepCopy' ; import { ELORating , ELOWrapper } from '../../ELO' ; import { RankSystem } from '..' ; import { Player } from '../..' ; export class ELOSystem extends RankSystem < ELO . Configs , ELO . RankState > { public configs : ELO . Configs = { startingScore : 1000 , kFactor : 32 , } ; private elo : ELOWrapper ; constructor ( configs ) { super ( ) ; this . configs = deepMerge ( this . configs , deepCopy ( configs ) ) ; this . elo = new ELOWrapper ( this . configs . kFactor , this . configs . startingScore ) ; } initializeRankState ( ) { return { rating : this . elo . createRating ( ) , } ; } onPlayerUpdate ( rankState ) { return { rating : this . elo . createRating ( rankState . rating . score ) , } ; } updateRanks ( rankStates , relativeRanks ) { const ratings = [ ] ; rankStates . forEach ( ( rankState ) => { ratings . push ( this . elo . createRating ( rankState . rating . score ) ) ; } ) ; this . elo . rate ( ratings , relativeRanks ) ; return ratings . map ( ( value ) => { return { rating : value } ; } ) ; } resetRank ( rankState ) { return { rating : this . elo . createRating ( ) , } ; } rankComparator ( rankState1 , rankState2 ) { return rankState2 . rating . score - rankState1 . rating . score ; } getRankStatesHeaderString ( ) { return sprintf ( `%-30s | %-15s | %-15s | %-8s` . underline , 'Name' , 'ID' , 'ELO Score' , 'Matches' ) ; } getRankStateString ( player , rankState , matchesPlayed ) { return sprintf ( `%-30s` . blue + ` | %-15s | ` + `%-15s` . green + ` | %-8s` , player . tournamentID . name , player . tournamentID . id , rankState . rating . score , matchesPlayed ) ; } } export namespace ELO { /**
     * The configuration interface for configuring the  ELO ranking system
      export interface Configs { default startingScore : number ; default kFactor : number ; } /** The current rank state of a player */ export interface RankState { /** The ELO Rating */ rating : ELORating ; } }