Open In App

Elo Rating Algorithm

Last Updated : 25 Jul, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

The Elo Rating Algorithm is a widely used rating algorithm used to rank players in many competitive games. 

  • Players with higher ELO ratings have a higher probability of winning a game than players with lower ELO ratings.
  • After each game, the ELO rating of players is updated.
  • If a player with a higher ELO rating wins, only a few points are transferred from the lower-rated player.
  • However if the lower-rated player wins, then the transferred points from a higher-rated player are far greater.

Approach: To Solve the problem follow the below idea:

P1: Probability of winning of the player with rating2, P2: Probability of winning of the player with rating1. 
P1 = (1.0 / (1.0 + pow(10, ((rating1 - rating2) / 400)))); 
P2 = (1.0 / (1.0 + pow(10, ((rating2 - rating1) / 400)))); 

Obviously, P1 + P2 = 1. The rating of the player is updated using the formula given below:- 
rating1 = rating1 + K*(Actual Score - Expected score); 

In most of the games, "Actual Score" is either 0 or 1 means the player either wins or loose. K is a constant. If K is of a lower value, then the rating is changed by a small fraction but if K is of a higher value, then the changes in the rating are significant. Different organizations set a different value of K.

Example:

Suppose there is a live match on chess.com between two players 
rating1 = 1200, rating2 = 1000; 

P1 = (1.0 / (1.0 + pow(10, ((1000-1200) / 400)))) = 0.76 
P2 = (1.0 / (1.0 + pow(10, ((1200-1000) / 400)))) = 0.24 
And Assume constant K=30; 

CASE-1: 
Suppose Player 1 wins: rating1 = rating1 + k*(actual - expected) = 1200+30(1 - 0.76) = 1207.2; 
rating2 = rating2 + k*(actual - expected) = 1000+30(0 - 0.24) = 992.8; 

Case-2: 
Suppose Player 2 wins: rating1 = rating1 + k*(actual - expected) = 1200+30(0 - 0.76) = 1177.2; 
rating2 = rating2 + k*(actual - expected) = 1000+30(1 - 0.24) = 1022.8;

Follow the below steps to solve the problem:

  • Calculate the probability of winning of players A and B using the formula given above
  • If player A wins or player B wins then the ratings are updated accordingly using the formulas:
    • rating1 = rating1 + K*(Actual Score - Expected score)
    • rating2 = rating2 + K*(Actual Score - Expected score)
    • Where the Actual score is 0 or 1
  • Print the updated ratings

Below is the implementation of the above approach:

CPP
#include <bits/stdc++.h>
using namespace std;

// Function to calculate the Probability
float Probability(int rating1, int rating2)
{
    // Calculate and return the expected score
    return 1.0 / (1 + pow(10, (rating1 - rating2) / 400.0));
}

// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
void EloRating(float Ra, float Rb, int K, float outcome)
{
    // Calculate the Winning Probability of Player B
    float Pb = Probability(Ra, Rb);

    // Calculate the Winning Probability of Player A
    float Pa = Probability(Rb, Ra);

    // Update the Elo Ratings
    Ra = Ra + K * (outcome - Pa);
    Rb = Rb + K * ((1 - outcome) - Pb);

    // Print updated ratings
    cout << "Updated Ratings:-\n";
    cout << "Ra = " << Ra << " Rb = " << Rb << endl;
}

// Driver code
int main()
{
    // Current ELO ratings
    float Ra = 1200, Rb = 1000;

    // K is a constant
    int K = 30;

    // Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
    float outcome = 1;

    // Function call
    EloRating(Ra, Rb, K, outcome);

    return 0;
}
Java
import java.lang.Math;

public class EloRating {

    // Function to calculate the Probability
    public static double Probability(int rating1, int rating2) {
        // Calculate and return the expected score
        return 1.0 / (1 + Math.pow(10, (rating1 - rating2) / 400.0));
    }

    // Function to calculate Elo rating
    // K is a constant.
    // outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
    public static void EloRating(double Ra, double Rb, int K, double outcome) {
        // Calculate the Winning Probability of Player B
        double Pb = Probability(Ra, Rb);

        // Calculate the Winning Probability of Player A
        double Pa = Probability(Rb, Ra);

        // Update the Elo Ratings
        Ra = Ra + K * (outcome - Pa);
        Rb = Rb + K * ((1 - outcome) - Pb);

        // Print updated ratings
        System.out.println("Updated Ratings:-");
        System.out.println("Ra = " + Ra + " Rb = " + Rb);
    }

    public static void main(String[] args) {
        // Current ELO ratings
        double Ra = 1200, Rb = 1000;

        // K is a constant
        int K = 30;

        // Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
        double outcome = 1;

        // Function call
        EloRating(Ra, Rb, K, outcome);
    }
}
Python
import math

# Function to calculate the Probability
def probability(rating1, rating2):
    # Calculate and return the expected score
    return 1.0 / (1 + math.pow(10, (rating1 - rating2) / 400.0))

# Function to calculate Elo rating
# K is a constant.
# outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
def elo_rating(Ra, Rb, K, outcome):
    # Calculate the Winning Probability of Player B
    Pb = probability(Ra, Rb)

    # Calculate the Winning Probability of Player A
    Pa = probability(Rb, Ra)

    # Update the Elo Ratings
    Ra = Ra + K * (outcome - Pa)
    Rb = Rb + K * ((1 - outcome) - Pb)

    # Print updated ratings
    print("Updated Ratings:-")
    print(f"Ra = {Ra} Rb = {Rb}")

# Current ELO ratings
Ra = 1200
Rb = 1000

# K is a constant
K = 30

# Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
outcome = 1

# Function call
elo_rating(Ra, Rb, K, outcome)
C#
using System;

class EloRating
{
    // Function to calculate the Probability
    public static double Probability(int rating1, int rating2)
    {
        // Calculate and return the expected score
        return 1.0 / (1 + Math.Pow(10, (rating1 - rating2) / 400.0));
    }

    // Function to calculate Elo rating
    // K is a constant.
    // outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
    public static void CalculateEloRating(ref double Ra, ref double Rb, int K, double outcome)
    {
        // Calculate the Winning Probability of Player B
        double Pb = Probability((int)Ra, (int)Rb);

        // Calculate the Winning Probability of Player A
        double Pa = Probability((int)Rb, (int)Ra);

        // Update the Elo Ratings
        Ra = Ra + K * (outcome - Pa);
        Rb = Rb + K * ((1 - outcome) - Pb);
    }

    static void Main()
    {
        // Current ELO ratings
        double Ra = 1200, Rb = 1000;

        // K is a constant
        int K = 30;

        // Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
        double outcome = 1;

        // Function call
        CalculateEloRating(ref Ra, ref Rb, K, outcome);

        // Print updated ratings
        Console.WriteLine("Updated Ratings:-");
        Console.WriteLine($"Ra = {Ra} Rb = {Rb}");
    }
}
JavaScript
// Function to calculate the Probability
function probability(rating1, rating2) {
    // Calculate and return the expected score
    return 1 / (1 + Math.pow(10, (rating1 - rating2) / 400));
}

// Function to calculate Elo rating
// K is a constant.
// outcome determines the outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw.
function eloRating(Ra, Rb, K, outcome) {
    // Calculate the Winning Probability of Player B
    let Pb = probability(Ra, Rb);

    // Calculate the Winning Probability of Player A
    let Pa = probability(Rb, Ra);

    // Update the Elo Ratings
    Ra = Ra + K * (outcome - Pa);
    Rb = Rb + K * ((1 - outcome) - Pb);

    // Print updated ratings
    console.log("Updated Ratings:-");
    console.log(`Ra = ${Ra} Rb = ${Rb}`);
}

// Current ELO ratings
let Ra = 1200, Rb = 1000;

// K is a constant
let K = 30;

// Outcome: 1 for Player A win, 0 for Player B win, 0.5 for draw
let outcome = 1;

// Function call
eloRating(Ra, Rb, K, outcome);

Output
Updated Ratings:-
Ra = 1207.21 Rb = 992.792

Time Complexity: The time complexity of the algorithm depends mostly on the complexity of the pow function whose complexity is dependent on Computer Architecture. On x86, this is constant time operation:-O(1)
Auxiliary Space: O(1)


Next Article
Article Tags :
Practice Tags :

Similar Reads