Algorithm to say if win or lose using player's rating and randomness 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&gt;2:
        self.win_2()
    elif q&lt;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 &gt; 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.
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).