Question

Problem:

If you go to http://www.newedenfaces.com/ down at the bottom you can see the player leaderboard. Everyone started out with a base score 1400. There are currently over 1100 players in the database, each two being picked randomly every time you vote. As of now, the highest rating is 1572. Furthermore leaderboard is very volatile. Someone who's been in Top 10 just today is now in 70+ range.

I would like score to be more significant. Most people in the leaderboard are only a few ratings apart, and some have even rating.

Sorry for the ugly and verbose code. I'll need to refactor it later.

eloRating: function(winnerIndex) {

    var kFactor = 16;

    if (winnerIndex == 0) {
      // A won
      var ratingA = this.collection.at(0).get('rating');
      var ratingB = this.collection.at(1).get('rating');

      var scoreA = this.collection.at(0).get('wins');
      var scoreB = this.collection.at(1).get('wins');

      var expectedA = 1.0 / (1.0 + Math.pow(10, ((ratingA - ratingB) / 400)));
      var expectedB = 1.0 / (1.0 + Math.pow(10, ((ratingA - ratingB) / 400)));

      var newRatingA = ratingA + (kFactor * expectedA);
      var newRatingB = ratingB - (kFactor * expectedA);

      this.collection.at(0).set('rating', Math.round(newRatingA));
      this.collection.at(1).set('rating', Math.round(newRatingB));
    } else {
      // B won
      var ratingA = this.collection.at(0).get('rating');
      var ratingB = this.collection.at(1).get('rating');

      var scoreA = this.collection.at(0).get('wins');
      var scoreB = this.collection.at(1).get('wins');

      var expectedA = 1.0 / (1.0 + Math.pow(10, ((ratingB - ratingA) / 400)));
      var expectedB = 1.0 / (1.0 + Math.pow(10, ((ratingB - ratingA) / 400)));

      var newRatingA = ratingA - (kFactor * expectedA);
      var newRatingB = ratingB + (kFactor * expectedA);

      this.collection.at(0).set('rating', Math.round(newRatingA));
      this.collection.at(1).set('rating', Math.round(newRatingB));
    }
Was it helpful?

Solution

Your equation for the expected score is incorrect. For example, by your equation someone 400 points higher would have an expected score of 10/11 (0.909). This is not right, because the actual win probability is higher than this (about 0.919). Here is the real equation:

ELO win probability

where D is the number of points in a standard deviation (normally 400 points). This equation has no closed form so a table of values which are precomputed must be used.

Also, more importantly, you are not computing the adjustment correctly. The winner gets (1-e)**k* points. The loser loses (e)**k* points where e is the expected score for the player. So, if Player A is 400 points higher than B and wins then he gets (1-0.919)*k = 1.296 points, and the loser loses 1.296 points. In your calculation the winner is getting 14.7 points (!!!) and loser is losing 14.7 points.

OTHER TIPS

This is my first post but I came up with this and it appears to be a fairly concise way of doing this.

I hope it may help someone.

var aElo = 1400; // player
var bElo = 1400; // opponent
var Res  = 1     // Result... 0.5 = draw, 1 = win, 0 = loss

var nElo = aElo+Math.round((32-((Math.floor(aElo/2101)+Math.floor(aElo/2401))*8)) * (Res - (1 / (1 + Math.pow(10, -(aElo - bElo) / 400)))));

alert("Players Elo was "+aElo+" but is now "+nElo);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top