UNPKG

toefungi-elo-calculator

Version:

A package to do all necessary computations to determine ELO rankings

173 lines 7.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** * https://metinmediamath.wordpress.com/2013/11/27/how-to-calculate-the-elo-rating-including-example/ * * EloCalculator class to do calculations to determine the elo of a player after a match. */ var EloCalculator = /** @class */ (function () { /** * Constructor method for the EloCalculator class. * * @param {boolean} shouldRound Whether or not the new ELO should be rounded before being returned. * @param {number} kFactor The factor the new ELO is calculated against. */ function EloCalculator(shouldRound, kFactor) { if (shouldRound === void 0) { shouldRound = true; } if (kFactor === void 0) { kFactor = 32; } this.kFactor = 32; this.kFactor = kFactor; this.shouldRound = shouldRound; } /** * @private * * Takes a current ELO score and will convert it to it's equivalent base10 value which can be used * to determine ELO for a win, loss or draw. * * @param {number} elo An ELO score to be converted to base10. * @return {Promise<number>} The equivalent base10 rank of the given ELO. */ EloCalculator.prototype.convertEloToBase10 = function (elo) { var divide = function () { return elo / 400; }; var convertToBase10 = function (value) { return Math.pow(10, value); }; return Promise.resolve() .then(divide) .then(convertToBase10); }; /** * @private * * Calculates the base10 equivalent value of each player's ELO score which can then be used to determine the new ELO * score for the player. * * @param {number} playerElo The initial ELO of the player. * @param {number} opponentElo The initial ELO of the opponent. * @return {Promise<RelativeRank>} An object containing the equivalent base10 value of both player's ELO score. */ EloCalculator.prototype.determineRelativeRank = function (playerElo, opponentElo) { return Promise.all([ this.convertEloToBase10(playerElo), this.convertEloToBase10(opponentElo) ]).then(function (_a) { var player = _a[0], opponent = _a[1]; return ({ player: player, opponent: opponent }); }); }; /** * @private * * Determines the scoring factor of the player based on their rank against their opponents rank. * * @param {number} playerRank The base10 value of the player's ELO score. * @param {number} opponentRank The base10 value of the opponent's ELO score. * @return {Promise<number>} The determined scoring factor. */ EloCalculator.prototype.determineScoreFactor = function (playerRank, opponentRank) { var add = function () { return playerRank + opponentRank; }; var divide = function (value) { return playerRank / value; }; return Promise.resolve() .then(add) .then(divide); }; /** * @private * * Determines the new ELO of a player based on the score factor, a win or loss and current ELO score. * * @param {number} playerElo A player's current ELO score. * @param {number} scoringFactor A factor derived from the player's relative base10 ELO score with their opponent's . * @param {ScoringBonus} score Enum with [ WIN, LOSS, DRAW ]. * @param {number} scoreDiff The difference in the score as a number. * @return {Promise<number>} The new calculated ELO. */ EloCalculator.prototype.determineElo = function (playerElo, scoringFactor, score, scoreDiff) { var _this = this; var getFactor = function (difference) { if (!difference) { return _this.kFactor; } return Math.log(Math.abs(difference) + 1) * _this.kFactor; }; var subtract = function () { return score - scoringFactor; }; var add = function (value) { return playerElo + value; }; var multiply = function (value) { return value * getFactor(scoreDiff); }; return Promise.resolve() .then(subtract) .then(multiply) .then(add); }; /** * @private * * Rounds off the ELO score before it is returned. * * @param {number} elo A value representing the ELO. * @return {Promise<number>} The rounded off ELO value. */ EloCalculator.prototype.rounding = function (elo) { var _this = this; return Promise.resolve() .then(function () { if (!_this.shouldRound) { return elo; } return Math.round(elo); }); }; /** * @private * * Creates a probability object which will be returned to the user. * * @param {number} probability The probability of the `player` to win the game. * @return {Promise<Probabilities>} The probability of a win for either player based on the `player` ELO. */ EloCalculator.prototype.createProbability = function (probability) { return Promise.resolve() .then(function () { var player = Math.round(probability * 100); var opponent = Math.round((1 - probability) * 100); return { player: player, opponent: opponent }; }); }; /** * Calculate the ELO of a player after a match based on their opponent's ELO and whether or not the player won the game. * * @param {number} playerElo The ELO of the player. * @param {number} opponentElo The ELO of the opponent. * @param {ScoringBonus} score The outcome of the game for the player, enum with [ WIN, LOSS, DRAW ]. * @param {number} scoreDiff The difference in the score as a number. * @return {Promise<number>} The new ELO of the player. */ EloCalculator.prototype.calculateElo = function (playerElo, opponentElo, score, scoreDiff) { var _this = this; return Promise.resolve() .then(function () { return _this.determineRelativeRank(playerElo, opponentElo); }) .then(function (relativeRank) { return _this.determineScoreFactor(relativeRank.player, relativeRank.opponent); }) .then(function (scoringFactor) { return _this.determineElo(playerElo, scoringFactor, score, scoreDiff); }) .then(function (elo) { return _this.rounding(elo); }); }; /** * Calculate the win probability for players in a match up given their respective ELO's. * * @param {number} playerElo The ELO of the player. * @param {number} opponentElo The ELO of the opponent. * @return {Promise<Probabilities>} The win probability for each player respectively. */ EloCalculator.prototype.caluclateWinProbability = function (playerElo, opponentElo) { var determineDiff = function () { return opponentElo - playerElo; }; var determineProbability = function (elo) { return 1 / (1 + elo); }; return Promise.resolve() .then(determineDiff) .then(this.convertEloToBase10) .then(determineProbability) .then(this.createProbability); }; return EloCalculator; }()); exports.EloCalculator = EloCalculator; //# sourceMappingURL=EloCalculator.js.map