Help implementing the Elo Rating System in Julia?

Hello There !
I recently thought out to implement the Elo Rating System in Julia.
https://en.wikipedia.org/wiki/Elo_rating_system More information about this.

The function should take an array of pre-ratings and returns an array containing post-ratings and it should be ordered from best performer to worst performer (winner -> loser).

My TA told me to use the default K factor as 32. I saw up an implementation on Ranking’s.jl but couldn’t understand. With help from my brother I was able to make it in javaScript.

I’m relatively new to Julia and would like to convert this into Julia code.

const elo = ([...ratings], kFactor = 32, selfRating) => {
  const [a, b] = ratings;
  const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400));
  const newRating = (rating, i) =>
    (selfRating || rating) + kFactor * (i - expectedScore(i ? a : b, i ? b : a));
  if (ratings.length === 2) return [newRating(a, 1), newRating(b, 0)];

  for (let i = 0, len = ratings.length; i < len; i++) {
    let j = i;
    while (j < len - 1) {
      j++;
      [ratings[i], ratings[j]] = elo([ratings[i], ratings[j]], kFactor);
    }
  }
  return ratings;
};

Output

// Standard 1v1s
elo([1200, 1200]); // [1216, 1184]
elo([1200, 1200], 64); // [1232, 1168]
// 4 player FFA, all same rank
elo([1200, 1200, 1200, 1200]).map(Math.round); // [1246, 1215, 1185, 1154]
/*
For teams, each rating can adjusted based on own team's average rating vs.
average rating of opposing team, with the score being added to their
own individual rating by supplying it as the third argument.
*/

What have you tried so far? Where did you get stuck?

I don’t seem to understand how

  const newRating = (rating, i) =>
    (selfRating || rating) + kFactor * (i - expectedScore(i ? a : b, i ? b : a));

can be coverted to julia
All other stuff has been done.
Thanks

how do you consider ties? for what i remembered, a tie is assigned 0.5 to each player, and the result of elo([1200, 1200]); // [1216, 1184] is weird in my opinion.
you can replace that with a function,taking into account that in julia 1 != true. As a workaround, you can do isone(1)

const newRating = (rating, i) =>
    (selfRating || rating) + kFactor * (i - expectedScore(i ? a : b, i ? b : a));
function newRating(rating, i)
  return (selfRating || rating) + kFactor * (i - expectedScore(isone(i) ? a : b, isone(i) ? b : a))
end

now there is still one part that needs correcting and can’t be passed to julia as-is, this statement:

(selfRating || rating)

as i have no real experience in javascript, i had to play around to see what this part does. technically, if the first argument exists, returns the first argument, else, return the second. i don’t know how do you represented the undefined or null value here. but taking a guess, you maybe used nothing. if this is the case, you can use something(a,b) . replacing this you have a valid (i think) julia function

function newRating(rating, i)
  return something(selfRating,rating) + kFactor * (i - expectedScore(isone(i) ? a : b, isone(i) ? b : a))
end

3 Likes