import { sprintf } from 'sprintf-js' ; import { DeepPartial } from '../../../utils/DeepPartial' ; import { deepMerge } from '../../../utils/DeepMerge' ; import { deepCopy } from '../../../utils/DeepCopy' ; import { RankSystem } from '..' ; import { Player } from '../..' ; import { FatalError } from '../../../DimensionError' ; export class WinsSystem extends RankSystem < Wins . Configs , Wins . RankState > { public configs : Wins . Configs = { winValue : 3 , tieValue : 1 , lossValue : 0 , descending : true , } ; constructor ( configs ) { super ( ) ; this . configs = deepMerge ( this . configs , deepCopy ( configs ) ) ; } getPoints ( wins , ties , losses ) { return ( wins * this . configs . winValue + ties * this . configs . tieValue + losses * this . configs . lossValue ) ; } initializeRankState ( ) { return { wins : 0 , losses : 0 , ties : 0 , points : this . getPoints ( 0 , 0 , 0 ) , } ; } onPlayerUpdate ( rankState ) { return { wins : 0 , losses : 0 , ties : 0 , points : this . getPoints ( 0 , 0 , 0 ) , } ; } updateRanks ( rankStates , relativeRanks ) { if ( relativeRanks . length > 2 || rankStates . length > 2 ) { throw new FatalError ( 'WinsSystem only supports 2 agent matches' ) ; } if ( relativeRanks [ 0 ] === relativeRanks [ 1 ] ) { return rankStates . map ( ( state ) => { return { wins : state . wins , ties : state . ties + 1 , losses : state . losses , points : this . getPoints ( state . wins , state . ties + 1 , state . losses ) , } ; } ) ; } else { let winningInd = 0 ; let losingInd = 1 ; if ( relativeRanks [ 0 ] > relativeRanks [ 1 ] ) { winningInd = 1 ; losingInd = 0 ; } return [ { wins : rankStates [ winningInd ] . wins + 1 , ties : rankStates [ winningInd ] . ties , losses : rankStates [ winningInd ] . losses , points : this . getPoints ( rankStates [ winningInd ] . wins + 1 , rankStates [ winningInd ] . ties , rankStates [ winningInd ] . losses ) , } , { wins : rankStates [ losingInd ] . wins , ties : rankStates [ losingInd ] . ties , losses : rankStates [ losingInd ] . losses + 1 , points : this . getPoints ( rankStates [ losingInd ] . wins , rankStates [ losingInd ] . ties , rankStates [ losingInd ] . losses + 1 ) , } , ] ; } } resetRank ( rankState ) { return { wins : 0 , ties : 0 , losses : 0 , points : this . getPoints ( 0 , 0 , 0 ) , } ; } rankComparator ( rankState1 , rankState2 ) { return this . configs . descending ? rankState2 . points - rankState1 . points : rankState1 . points - rankState2 . points ; } getRankStatesHeaderString ( ) { return sprintf ( `%-30s | %-14s | %-5s | %-5s | %-5s | %8s | %-8s` . underline , 'Name' , 'ID' , 'W' , 'T' , 'L' , 'Points' , 'Matches' ) ; } getRankStateString ( player , rankState , matchesPlayed ) { return sprintf ( `%-30s` . blue + ` | %-14s | %-5s | %-5s | %-5s | ` + `%-8s` . green + ` | %-8s` , player . tournamentID . name , player . tournamentID . id , rankState . wins , rankState . ties , rankState . losses , rankState . points , matchesPlayed ) ; } } export namespace Wins { /**
     * The configuration interface for configuring the  WINS ranking system
      export interface Configs { /** Points given per win in a  Match winValue : number ; /** Points given per tie in a  Match tieValue : number ; /** Points given per loss in a  Match lossValue : number ; /** True if first place is the one with the most points. */ descending : boolean ; } /** The current rank state of a player */ export interface RankState { wins : number ; ties : number ; losses : number ; points : number ; } }