Solved Basic ELO System

Discussion in 'Plugin Development' started by Xp10d3, May 25, 2021.

  1. Offline

    Xp10d3

    As the title says, how would I create a basic ELO system? Sorry nothing I can really elaborate on lol.

    Basic code (just rough pseudo code right now):
    Code:java
    1.  
    2. public static void insertPlayer() {
    3. if (!player.existsInDb()) {
    4. // insert player
    5. }
    6. }
    7.  
    8. public static int getData(Player player) {
    9. int elo = getPlayerFromDB();
    10. return elo;
    11. }
    12.  
    13. public static void onFinishGame(Player player) {
    14. int elo = getData(player);
    15. int eloToChange = someEloThing();
    16. elo = elo - eloToChange;
    17. }
    18.  

    I've tried searching up a few ELO systems, but am not entirely sure I'm doing it correctly.
    This is what I have so far:
    Code:java
    1.  
    2. public static void main(String args[]) {
    3. eloRating(1100, 1200);
    4. }
    5.  
    6. public static double calculateElo(int rating1, int rating2) {
    7. return 1.0 * 1.0 / (1 + 1.0 * Math.pow(10, 1.0 * (rating1 - rating2) / 400));
    8. }
    9.  
    10. public static void eloRating(int ra, int rb) {
    11. double pb = calculateElo(ra, rb);
    12. double pa = calculateElo(rb, ra);
    13.  
    14. System.out.println("pa elo: " + pb);
    15. System.out.println("pb elo: " + pa);
    16. }
    17.  

    The code returned:
    Code:
    pa elo: 0.6400649998028851
    pb elo: 0.35993500019711494
    
     
  2. Offline

    KarimAKL

  3. Offline

    Shqep

    I really don't know if this is the correct forum to ask about an Elo system design lol. Anyhow, I could theoretically summarize the wiki page, but more info is found on there.

    From what I can see from your codes, it seems like you implemented Arpad Elo's rating system for chess, briefly:
    Brief Description (open)
    The difference in the ratings between two players serves as a predictor of the outcome of a match. Two players with equal ratings who play against each other are expected to score an equal number of wins. A player whose rating is 100 points greater than their opponent's is expected to score 64%; if the difference is 200 points, then the expected score for the stronger player is 76%.


    wiki tl;dr (open)

    What you evaluated out as
    Code:
    pa elo: 0.6400649998028851
    pb elo: 0.35993500019711494
    
    These are "expected scores" as you can see their sum approaches 1 if not is equal to 1.

    And here is the formula to update a player's rating after a match:
    Code:
    new_rating1 = old_rating1 + k(actual - expected)
    new_rating2 = old_rating2 + k(actual - expected)
    
    Whereas:
    - k is the factor, in a nutshell, higher rating = lower gain on win, lower rating = higher gain on win.
    - actual is the outcome, it's usually 1 if it's a win, 0 if it's a loss and 0.5 if it's a draw.
    - expected is the expected score, this is what you evaluated to.

    For example:
    Code:
    Two players with two ratings: r1 = 1100, r2 = 1800
    Expected scores: e1 = 0.017472091494833444, e2 = 0.9825279085051666
    Actual outcome: player 1 win. so a1 = 1, a2 = 0.
    Assuming the external factor k is 16.
    Now the new elos:
    r'1 = r1 + k(a1 - e1) = 1115.7204465360826
    r'2 = r2 + k(a1 - e2) = 1784.2795534639174
    And r'1 + r'2 == r1 + r2.
    
    That's all to Elo's rating system.

    For what value k should be? Idk, it's your job to decide. Watch these chess dudes do it.
     
    Xp10d3 likes this.
  4. Offline

    Xp10d3

    LOLL my bad. Thanks; that makes sense. I guess I should've done more research on the different ELO systems haha. :eek::oops:

    It does; thanks. I'll probably end up using this (even though it is chess related, the algorithm is probably a bit easier to understand than 1.0 * 1.0 / (1 + 1.0 * Math.pow(10, 1.0 * (rating1 - rating2) / 400));)
    upload_2021-5-25_11-51-12.png
    For anyone else who wants to try this lol 400 is the K factor as Shqep said. I think 32 is usually the most common K factor but I could be wrong.

    EDIT: Works perfectly; thanks everyone. Final code:
    Code:java
    1.  
    2. package eltik.testing.endran;
    3.  
    4. public class Core {
    5. public static void main(String args[]) {
    6. // Player1's ELO is 1000, Player2's ELO is 1300.
    7. eloRating(1000, 1300);
    8. }
    9.  
    10. public static int elo;
    11. // rating1: The person who won/loss the game. We'll call them Player1.
    12. // rating2: Player1's opponent (Player2 in this case).
    13. // numGames: Amount of games Player1 won.
    14. // win: Whether Player1 won the game.
    15. // draw: Whether the game was a draw or not.
    16. public static double calculateElo(int rating1, int rating2, int numGames, boolean win, boolean draw) {
    17. if (win && !draw) {
    18. // If the game is won and it isn't a draw.
    19. elo = rating1 + ((rating2 + 400) / numGames);
    20. } else if (!win && !draw) {
    21. // If the game isn't won and it isn't a draw.
    22. elo = rating1 + ((rating2 - 400) / numGames);
    23. } else if (draw) {
    24. // If the game is a draw.
    25. elo = rating1 + (rating2 + 400) * 0 / numGames;
    26. }
    27. return elo;
    28. }
    29.  
    30. public static void eloRating(int ra, int rb) {
    31. // Rate a game with Player1's ELO (ra) and Player2's ELO (rb) that is won and isn't a draw.
    32. System.out.println((int)calculateElo(ra, rb, 10, true, false));
    33. }
    34. }
    35.  
     
    Last edited: May 25, 2021
    Shqep likes this.
  5. Offline

    Shqep

    Glad that you found something that suits you, but I'd still recommend using the right one to assure the highest accuracy:
    - The performance rating, the one you ended up using, should be used in one-time tournaments, similar to those tournaments (Skywars, Blitz) Hypixel hosts for example.
    - The average rating which I explained, should be used if you can play an infinite amount of matches, just like Ranked Skywars on Hypixel, the ranked system on Practice servers, etc.

    But you do you, I'm just here to suggest stuff. Also, 1 code problem:
    PHP:
    public static double calculateElo(int rating1int rating2int numGamesboolean winboolean draw) {
        
    // put. the. variable. inside. the. method. if. you. are. going. to. use. it. once. and. return.
        
    double elo;
        if (
    win && !draw) {
             
    elo rating1 + ((rating2 400) / numGames);
        } else if (!
    win && !draw) {
             
    elo rating1 + ((rating2 400) / numGames);
        } else if (
    draw) {
             
    elo rating1 + (rating2 400) * numGames;
        }
        return 
    elo;
    }
     
    Xp10d3 likes this.
  6. Offline

    Xp10d3

    Lol I noticed that. I don't know why I put the variable outside of the method...??? But thanks; marking as solved.
     

Share This Page