3

I implement elo algorithm however it was working in quite opposite way as i mix results (set win where is lose and opposite..) That little detail fail my results - thats why question is - how can i reverse that ?

I have only new Elo and old elo as i was garhering statistics..

My algorithm looks exactly like on wiki: https://en.wikipedia.org/wiki/Elo_rating_system#Theory

which is:

public class EloAlgorithm {

   public static Integer calculateRating(Integer myRating, Integer opponentRating, EloGameResultValue result) {
       myRating += calculateEloDelta(myRating, opponentRating, result);
       if (myRating<0){
           return 0;
       }
       return myRating;
   }

   private static Integer calculateEloDelta(Integer myRating, Integer opponentRating, EloGameResultValue result){
       Double myChanceToWin = 1 / (1 + Math.pow(10, (opponentRating - myRating) / 400));
       Long eloDelta = Math.round(getKFactor(myRating) * (result.getValue() - myChanceToWin));
       return eloDelta.intValue();
   }

   private static double getKFactor(Integer myRating) {
      if(myRating < 2100) return 32.0;
      else if(myRating >= 2100 && myRating < 2400) return 24;
      else return 16;
   }
}

i tried to reverse it but probably i did a mistake in my calculations:

public static Integer fetchOponentRatingFromDifference(int myOldRating, int myNewRating, EloGameResultValue result){
    double delta = myNewRating - myOldRating;

    double k = getKFactor(myOldRating);
    double myChanceToWin =  (k* result.getValue() - difference)/k ;

    double log = Math.log10(1/myChanceToWin - 1);
    Double resultToReturn = 400*log + myOldRating;

    return (int)Math.round(resultToReturn);
}

Can you please help me find a mistake in it or reccomend better solution?

EDIT: As was requested:

I test it via JUnit

public class EloValueBinaryFinderTest {
     @Test
     public void eloValueFinderTest(){   
     System.out.println(
       EloValueBinaryFinder.fetchOponentRatingFromDifference(952,968)
     );
}

}

however main method with this will be :

public class EloValueBinaryFinderTest {
      public static void main(String... args){
      System.out.println(
         EloValueBinaryFinder.fetchOponentRatingFromDifference(952,968)
      );
   }
}

EloGameResultValue as was necessary is just an enum:

public enum EloGameResultValue {
WIN(1),
DRAW(0.5),
LOSE(0);

Double value;

EloGameResultValue(double value) {
    this.value = value;
}

public Double getValue() {
    return value;
}


public Boolean isWin() {
    if(value.equals(1.0)){
        return true;
    }
    if(value.equals(0.0)){
        return false;
    }
    return null;
}

}
Alex R
  • 175
  • 1
  • 12
  • ues `int` rather than `Integer` and `double` rather than `Double` when you're not force to, easier, can you give main method to test ? – azro Jul 26 '17 at 17:01
  • please come here https://chat.stackoverflow.com/rooms/info/150213/elo-algo?tab=general better to talk – azro Jul 26 '17 at 17:11
  • 1
    and caution with integer division: e.g. `380/400 = 0`, while `(double)380/400 = 380.0/400 = 380/400.0 = 0.95` – user85421 Jul 26 '17 at 17:14
  • I cant come to room - damn stackoverlow allow it when i will have 20 reps :( sorry @azro – Alex R Jul 26 '17 at 17:16
  • you can come in chat – azro Jul 26 '17 at 17:18
  • server is still calulating i think - here i have 25 , on chat room i have 15 xd will try join as it will load properly :) Thank you :) – Alex R Jul 26 '17 at 17:20

1 Answers1

1

Okay i solve that, calculation was okay but implementation was wrong :)

First mistake was good spotted by @Carlos Hauberger

Second one, was my mistake - logarithm can take only positive values as parameter as negative cause NaN

Alex R
  • 175
  • 1
  • 12