Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I wrote a small simulator to understand the Elo rating system. I can create players, matches and tournaments, and I want to be able to predict the match ending depending on the rating of each player and some randomness. At the beginning the ratings are all around the same values (say 600) and it appears to stay between 400 and 1600. This is what I've tried :

p1 and p2 are instances of Player, rating is an integer attribute.

def random_win(self):
    q = float(self.p2.rating)/float(self.p1.rating)
    if q>2:
        self.win_2()
    elif q<0.5:
        self.win_1()
    else:
        d = float(self.p2.rating)-float(self.p1.rating)
        lim = max(self.p1.rating, self.p2.rating)/2
        r = random.randint(-lim, lim)
        if r > d:
            self.win_1()
        else:
            self.win_2()

I'd like to know if there are some "official" ways of doing this, this custom one works quite fine but I think it can be improved or at least simplified. Any ideas ? The best would be to get something closer the World Chess Ratings.


Once the wins and losses calculated and stored into the Player as a list attribute, I calculate the new rating for each player using this algorithm.

share|improve this question

World Chess Ratings are going to be skewed: people that lose are less likely to play than people who win, so it's quite possible that everyone who went to a single tournament and got wrecked is not going to play in tournaments anymore. And Elo is a measurement of skill, not skill itself, so of course it won't go past a certain value. A good chess player who played 1 competitive match has a lower rating than his playing strength. So even though his rating is lower, he'll win more than his rating suggests, that's why his rating goes up.

As such, your simulation is going to keep giving skewed results until you give each player a "skill" attribute which determines their real playing strength. That means each player would have a rating (which starts at 1000) and a skill (which starts at a randomized value between 0 and 2500 or so, where the distribution is, say, Gaussian), and where you used to compare rating, you compare skill instead. This should give you a more realistic simulation of Elo rating, but you'll still be assuming that players all play equally as much (which is not the case in real life).

share|improve this answer
    
Fair enough. I was going to reply to your comment but you made a more complete answer, so... Do you suggest to change the whole rating system ? How could I differentiate skill and rating ? – BusyAnt 4 hours ago
    
@BusyAnt slightly updated answer - you just gotta add an attribute and use that – Pimgd 4 hours ago
    
Then the skill would be (for example) the mean of the other players ratings that you've beaten, or something like this ? – BusyAnt 4 hours ago
2  
@BusyAnt skill doesn't change - ratings change. The rating is supposed to match the skill after enough games - imagine that skill is a variable which you cannot access but have to determine within several points... – Pimgd 4 hours ago

Is your goal to calculate rating changes for the winner and loser in a match given their difference original ratings? If yes, you should look into an error function (integral of Gaussian function).

Update:
These values don't fit well in Gaussian function. This applet http://statpages.info/nonlin.html suggests 0.5*exp(-(x/217)^2), but the results are off: (0, 0.5); (100, 0.41); (200, 0.22)

A simple exponent 0.5*exp(-(x/(100*e))) seems to predict loser's chances correctly (0, 0.5); (100, 0.346); (200, 0.24)

Winners chances should then be 1-loser's_chances.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.