{"version":3,"file":"index.mjs","sources":["../src/main/contestants/player/index.ts","../src/main/contestants/team/index.ts","../src/lib/error/index.ts","../src/lib/match/error/index.ts","../src/lib/match/index.ts","../src/lib/match/options.ts","../src/main/matches/duel/index.ts","../src/main/matches/free-for-all/index.ts","../src/main/matches/team-duel/index.ts","../src/main/matches/team-free-for-all/index.ts"],"sourcesContent":["const DEFAULT_ELO_SCALE_FACTOR = 400\nconst Result = {\n  WIN: 1,\n  LOSS: 0\n}\n\nexport class Player {\n  id: string\n  elo: number\n\n  constructor(id: string, elo: number) {\n    this.id = id\n    this.elo = elo\n  }\n\n  static create(id: string, elo: number): Player {\n    return new Player(id, elo)\n  }\n\n  getExpectedResult(opponentElo: number): number {\n    return 1 / (1 + Math.pow(10, (opponentElo - this.elo) / DEFAULT_ELO_SCALE_FACTOR))\n  }\n\n  calculate(opponentElo: number, won: boolean, kFactor: number): number {\n    const result = won ? Result.WIN : Result.LOSS\n    const expectedResult = this.getExpectedResult(opponentElo)\n    return Math.round(this.elo + kFactor * (result - expectedResult))\n  }\n}\n","import { Player } from '../player'\n\nexport class Team {\n  id: string\n  players: Map<string, Player>\n\n  constructor(id: string, players?: Player[]) {\n    this.id = id\n    this.players = new Map()\n\n    if (players) {\n      this.addPlayers(...players)\n    }\n  }\n\n  static create(id: string, players?: Player[]): Team {\n    return new Team(id, players)\n  }\n\n  addPlayer(player: Player): this {\n    this.players.set(player.id, player)\n    return this\n  }\n\n  addPlayers(...players: Player[]): this {\n    players.forEach(player => this.addPlayer(player))\n    return this\n  }\n\n  getAverageElo(): number {\n    if (this.players.size === 0) {\n      return 0\n    }\n\n    let elo = 0\n\n    for (const player of this.players.values()) {\n      elo += player.elo\n    }\n\n    return elo / this.players.size\n  }\n}\n","export class BaseError<T extends string> extends Error {\n  name: T\n  message: string\n\n  constructor(name: T, message: string) {\n    super()\n    this.name = name\n    this.message = message\n  }\n}\n","import { BaseError } from '../../error'\n\nconst ERROR_NAME = 'MATCH_ERROR'\n\nexport const ErrorType = {\n  MATCH_COMPLETE: 'Match completed',\n  MATCH_INCOMPLETE: 'Match incomplete',\n  MAX_PLAYERS: 'Cannot add more players',\n  MIN_PLAYERS: 'Need more players',\n  MAX_TEAMS: 'Cannot add more teams',\n  MIN_TEAMS: 'Need more teams',\n  SIZE_MISMATCH: 'Calculation does not match contestant size in match',\n  PLAYER_NOT_FOUND: 'Player not found',\n  TEAM_NOT_FOUND: 'Team not found',\n  MISSING_OPPONENT_ELO: 'Could not find opponent elo'\n}\n\ntype ErrorTypeKey = keyof typeof ErrorType\n\nexport class MatchError<T extends ErrorTypeKey> extends BaseError<typeof ERROR_NAME> {\n  constructor(message: (typeof ErrorType)[T]) {\n    super(ERROR_NAME, message)\n  }\n}\n","import { Player } from '../../main/contestants/player'\nimport { Team } from '../../main/contestants/team'\nimport {\n  Options,\n  DEFAULT_K_FACTOR,\n  DEFAULT_MIN_CONTESTANTS,\n  DEFAULT_MAX_CONTESTANTS\n} from './options'\nimport { Results } from './results'\nimport { ErrorType, MatchError } from './error'\n\ntype Contestant = Player | Team\n\nexport abstract class Match {\n  private _contestants: Map<string, Contestant>\n  private _completed: boolean\n  protected readonly minContestants: number\n  protected readonly maxContestants: number\n  protected readonly kFactor: number\n\n  constructor(options?: Options) {\n    this._contestants = new Map()\n    this._completed = false\n    this.minContestants = options?.minContestants ?? DEFAULT_MIN_CONTESTANTS\n    this.maxContestants = options?.maxContestants ?? DEFAULT_MAX_CONTESTANTS\n    this.kFactor = options?.kFactor ?? DEFAULT_K_FACTOR\n  }\n\n  get contestants(): Map<string, Contestant> {\n    return this._contestants\n  }\n\n  get size(): number {\n    return this._contestants.size\n  }\n\n  get completed(): boolean {\n    return this._completed\n  }\n\n  protected set completed(completed: boolean) {\n    if (this._completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    this._completed = completed\n  }\n\n  protected contestantMapToEloMap(): Map<string, number> {\n    const elos = new Map<string, number>()\n\n    for (const [id, contestant] of this._contestants) {\n      if (contestant instanceof Player) {\n        elos.set(id, contestant.elo)\n      } else if (contestant instanceof Team) {\n        elos.set(id, contestant.getAverageElo())\n      }\n    }\n\n    return elos\n  }\n\n  protected contestantMapToResults<T extends Results>(): T {\n    const results = []\n\n    for (const [id, contestant] of this._contestants) {\n      if (contestant instanceof Player) {\n        const player = { id, elo: contestant.elo }\n        results.push(player)\n      } else if (contestant instanceof Team) {\n        const team = {\n          id,\n          players: [...contestant.players.values()].map(player => ({\n            id: player.id,\n            elo: player.elo\n          }))\n        }\n        results.push(team)\n      }\n    }\n\n    return results as T\n  }\n\n  protected findOpponentElos(contestantId: string, contestants: Map<string, number>): number[] {\n    const elos: number[] = []\n\n    for (const [id, elo] of contestants) {\n      if (id !== contestantId) {\n        elos.push(elo)\n      }\n    }\n\n    return elos\n  }\n\n  protected addContestant(contestant: Contestant) {\n    if (this._completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    this._contestants.set(contestant.id, contestant)\n  }\n\n  getResults(): Results {\n    if (!this._completed) {\n      throw new MatchError(ErrorType.MATCH_INCOMPLETE)\n    }\n\n    return this.contestantMapToResults()\n  }\n\n  abstract calculate(contestantIds: string | string[]): Results\n}\n","export interface Options {\n  kFactor?: number\n  minContestants?: number\n  maxContestants?: number\n}\n\n// Elo calculation\nexport const DEFAULT_K_FACTOR = 32\n\n// Min/max contestants\nexport const DUEL_SIZE = 2\nexport const DEFAULT_MIN_CONTESTANTS = 2\nexport const DEFAULT_MAX_CONTESTANTS = 256\n","import { Player } from '../../contestants/player'\nimport { Match } from '../../../lib/match'\nimport { Options, DUEL_SIZE } from '../../../lib/match/options'\nimport { PlayerResult } from '../../../lib/match/results'\nimport { MatchError, ErrorType } from '../../../lib/match/error'\n\ntype DuelOptions = Partial<Pick<Options, 'kFactor'>>\n\nexport class Duel extends Match {\n  constructor(players?: Player[], options?: DuelOptions) {\n    super({\n      minContestants: DUEL_SIZE,\n      maxContestants: DUEL_SIZE,\n      ...options\n    })\n\n    if (players) {\n      this.addPlayers(...players)\n    }\n  }\n\n  static create(players?: Player[], options?: DuelOptions): Duel {\n    return new Duel(players, options)\n  }\n\n  addPlayer(player: Player): this {\n    if (this.size === DUEL_SIZE) {\n      throw new MatchError(ErrorType.MAX_PLAYERS)\n    }\n\n    this.addContestant(player)\n\n    return this\n  }\n\n  addPlayers(...players: Player[]): this {\n    players.forEach(player => this.addPlayer(player))\n    return this\n  }\n\n  calculate(playerId: string): PlayerResult[] {\n    if (this.completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    if (this.size !== DUEL_SIZE) {\n      throw new MatchError(ErrorType.MIN_PLAYERS)\n    }\n\n    const players = this.contestantMapToEloMap()\n\n    for (const [id, contestant] of this.contestants) {\n      const player = contestant as Player\n      const elos = this.findOpponentElos(id, players)\n\n      if (elos.length === 0) {\n        throw new MatchError(ErrorType.MISSING_OPPONENT_ELO)\n      }\n\n      const elo = player.calculate(elos[0], playerId === id, this.kFactor)\n\n      player.elo = elo\n    }\n\n    this.completed = true\n\n    return this.contestantMapToResults()\n  }\n}\n","import { Player } from '../../contestants/player'\nimport { Match } from '../../../lib/match'\nimport { Options } from '../../../lib/match/options'\nimport { PlayerResult } from '../../../lib/match/results'\nimport { MatchError, ErrorType } from '../../../lib/match/error'\n\ninterface FreeForAllOptions extends Partial<Pick<Options, 'kFactor'>> {\n  minPlayers?: number\n  maxPlayers?: number\n}\n\nexport class FreeForAll extends Match {\n  constructor(players?: Player[], options?: FreeForAllOptions) {\n    super({\n      minContestants: options?.minPlayers,\n      maxContestants: options?.maxPlayers,\n      ...options\n    })\n\n    if (players) {\n      this.addPlayers(...players)\n    }\n  }\n\n  static create(players?: Player[], options?: FreeForAllOptions): FreeForAll {\n    return new FreeForAll(players, options)\n  }\n\n  addPlayer(player: Player): this {\n    if (this.size === this.maxContestants) {\n      throw new MatchError(ErrorType.MAX_PLAYERS)\n    }\n\n    this.addContestant(player)\n\n    return this\n  }\n\n  addPlayers(...players: Player[]): this {\n    players.forEach(player => this.addPlayer(player))\n    return this\n  }\n\n  calculate(playerIds: string[]): PlayerResult[] {\n    if (this.completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    if (this.size < this.minContestants) {\n      throw new MatchError(ErrorType.MIN_PLAYERS)\n    }\n\n    if (this.size !== playerIds.length) {\n      throw new MatchError(ErrorType.SIZE_MISMATCH)\n    }\n\n    const players = this.contestantMapToEloMap()\n\n    for (let i = 0; i < playerIds.length; i++) {\n      const player = this.contestants.get(playerIds[i]) as Player\n\n      if (!player) {\n        throw new MatchError(ErrorType.PLAYER_NOT_FOUND)\n      }\n\n      let eloDiff = 0\n\n      for (let j = 0; j < playerIds.length; j++) {\n        if (i != j) {\n          const opponentElo = players.get(playerIds[j])\n\n          if (!opponentElo) {\n            throw new MatchError(ErrorType.MISSING_OPPONENT_ELO)\n          }\n\n          eloDiff += player.calculate(opponentElo, j > i, this.kFactor)\n        }\n      }\n\n      player.elo = Math.floor(eloDiff / (playerIds.length - 1))\n    }\n\n    this.completed = true\n\n    return this.contestantMapToResults()\n  }\n}\n","import { Team } from '../../contestants/team'\nimport { Match } from '../../../lib/match'\nimport { Options, DUEL_SIZE } from '../../../lib/match/options'\nimport { TeamResult } from '../../../lib/match/results'\nimport { MatchError, ErrorType } from '../../../lib/match/error'\n\ntype TeamDuelOptions = Partial<Pick<Options, 'kFactor'>>\n\nexport class TeamDuel extends Match {\n  constructor(teams?: Team[], options?: TeamDuelOptions) {\n    super({\n      minContestants: DUEL_SIZE,\n      maxContestants: DUEL_SIZE,\n      ...options\n    })\n\n    if (teams) {\n      this.addTeams(...teams)\n    }\n  }\n\n  static create(teams?: Team[], options?: TeamDuelOptions): TeamDuel {\n    return new TeamDuel(teams, options)\n  }\n\n  addTeam(team: Team): this {\n    if (this.size === DUEL_SIZE) {\n      throw new MatchError(ErrorType.MAX_TEAMS)\n    }\n\n    this.addContestant(team)\n\n    return this\n  }\n\n  addTeams(...teams: Team[]): this {\n    teams.forEach(team => this.addTeam(team))\n    return this\n  }\n\n  calculate(teamId: string): TeamResult[] {\n    if (this.completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    if (this.size !== DUEL_SIZE) {\n      throw new MatchError(ErrorType.MIN_TEAMS)\n    }\n\n    const teams = this.contestantMapToEloMap()\n\n    for (const [id, contestant] of this.contestants) {\n      const team = contestant as Team\n      const elos = this.findOpponentElos(id, teams)\n\n      if (elos.length === 0) {\n        throw new MatchError(ErrorType.MISSING_OPPONENT_ELO)\n      }\n\n      for (const [, player] of team.players) {\n        const elo = player.calculate(elos[0], teamId === id, this.kFactor)\n\n        player.elo = elo\n      }\n    }\n\n    this.completed = true\n\n    return this.contestantMapToResults()\n  }\n}\n","import { Team } from '../../contestants/team'\nimport { Match } from '../../../lib/match'\nimport { Options } from '../../../lib/match/options'\nimport { TeamResult } from '../../../lib/match/results'\nimport { MatchError, ErrorType } from '../../../lib/match/error'\n\ninterface TeamFreeForAllOptions extends Partial<Pick<Options, 'kFactor'>> {\n  minTeams?: number\n  maxTeams?: number\n}\n\nexport class TeamFreeForAll extends Match {\n  constructor(teams?: Team[], options?: TeamFreeForAllOptions) {\n    super({\n      minContestants: options?.minTeams,\n      maxContestants: options?.maxTeams,\n      ...options\n    })\n\n    if (teams) {\n      this.addTeams(...teams)\n    }\n  }\n\n  static create(teams?: Team[], options?: TeamFreeForAllOptions): TeamFreeForAll {\n    return new TeamFreeForAll(teams, options)\n  }\n\n  addTeam(team: Team): this {\n    if (this.size === this.maxContestants) {\n      throw new MatchError(ErrorType.MAX_TEAMS)\n    }\n\n    this.addContestant(team)\n\n    return this\n  }\n\n  addTeams(...teams: Team[]): this {\n    teams.forEach(team => this.addTeam(team))\n    return this\n  }\n\n  calculate(teamIds: string[]): TeamResult[] {\n    if (this.completed) {\n      throw new MatchError(ErrorType.MATCH_COMPLETE)\n    }\n\n    if (this.size < this.minContestants) {\n      throw new MatchError(ErrorType.MIN_TEAMS)\n    }\n\n    if (this.size !== teamIds.length) {\n      throw new MatchError(ErrorType.SIZE_MISMATCH)\n    }\n\n    const teams = this.contestantMapToEloMap()\n\n    for (let i = 0; i < teamIds.length; i++) {\n      const team = this.contestants.get(teamIds[i]) as Team\n\n      if (!team) {\n        throw new MatchError(ErrorType.TEAM_NOT_FOUND)\n      }\n\n      for (const [, player] of team.players) {\n        let eloDiff = 0\n\n        for (let j = 0; j < teamIds.length; j++) {\n          if (i != j) {\n            const opponentElo = teams.get(teamIds[j])\n\n            if (!opponentElo) {\n              throw new MatchError(ErrorType.MISSING_OPPONENT_ELO)\n            }\n\n            eloDiff += player.calculate(opponentElo, j > i, this.kFactor)\n          }\n        }\n\n        player.elo = Math.floor(eloDiff / (teamIds.length - 1))\n      }\n    }\n\n    this.completed = true\n\n    return this.contestantMapToResults()\n  }\n}\n"],"names":["Result","Player","constructor","id","elo","this","create","getExpectedResult","opponentElo","Math","pow","calculate","won","kFactor","result","expectedResult","round","Team","players","Map","addPlayers","addPlayer","player","set","forEach","getAverageElo","size","values","BaseError","Error","name","message","super","ErrorType","MatchError","Match","options","_contestants","_completed","minContestants","_a","maxContestants","_b","_c","contestants","completed","contestantMapToEloMap","elos","contestant","contestantMapToResults","results","push","team","map","findOpponentElos","contestantId","addContestant","getResults","Duel","Object","assign","playerId","length","FreeForAll","minPlayers","maxPlayers","playerIds","i","get","eloDiff","j","floor","TeamDuel","teams","addTeams","addTeam","teamId","TeamFreeForAll","minTeams","maxTeams","teamIds"],"mappings":"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"}