Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
using System;
using Xunit;
using Shouldly;
using System.Collections.Generic;
using Podium.RatingSystem.Glicko2;

namespace Podium.UnitTests
{

public class Glicko2CalculatorUnitTests
{
[Fact]
public void Calculates_mu()
{
// Given
double opponentRating = 1215;
double factor = 173.7177928;
double offset = 1500;

IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var mu = glickoCalculator.CalculateMu(opponentRating, offset, factor);

// Then
double expectedMu = -1.64059;
mu.ShouldBe(expectedMu, 0.01);
}

[Fact]
public void Calculates_phi()
{
// Given
double opponentRD = 81;
double factor = 173.7177928;

IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var phi = glickoCalculator.CalculatePhi(opponentRD, factor);

// Then
double expectedPhi = 0.466273481;
phi.ShouldBe(expectedPhi, 0.01);
}

[Fact]
public void Calculates_g()
{
// Given
double phi = 0.466273481;

IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var g = glickoCalculator.CalculateG(phi);

// Then
double expectedG = 0.96850994;
g.ShouldBe(expectedG, 0.01);
}


[Fact]
public void Calculates_E()
{
// Given
double playerMu = -4.0123;
double g = 0.9685;
double opponentMu = -1.6405;

IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var E = glickoCalculator.CalculateE(g, opponentMu, playerMu);

// Then
double expectedE = 0.091373481;
E.ShouldBe(expectedE, 0.01);
}

[Fact]
public void Calculates_G2E()
{
// Given
double E = 0.091373481;
double g = 0.9685;
IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var G2E = glickoCalculator.CalculateG2E(g, E);

// Then
double expectedG2E = 0.077877;
G2E.ShouldBe(expectedG2E, 0.01);
}


[Fact]
public void Calculates_GsE()
{
// Given
double E = 0.091373481;
double g = 0.9685;
double outcome = GameOutcome.Win;
IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var GsE = glickoCalculator.CalculateGsE(g, E, outcome);

// Then
double expectedGsE = 0.8800138;
GsE.ShouldBe(expectedGsE, 0.01);
}

[Fact]
public void Calculates_Nu()
{
// Given
double g2ESum = 0.077877;
IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var nu = glickoCalculator.CalculateNu(g2ESum);

// Then
double expectedNu = 12.84062;
nu.ShouldBe(expectedNu, 0.01);
}

[Fact]
public void Calculates_Delta()
{
// Given
double GsESum = 0.8800138;
double nu = 12.84062;
IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator();

// When
var delta = glickoCalculator.CalculateDelta(GsESum, nu);

// Then
double expectedDelta = 11.2999;
delta.ShouldBe(expectedDelta, 0.01);
}
}
}
15 changes: 15 additions & 0 deletions src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Podium
{
public interface IGlicko2RatingCalculator
{
public double CalculateMu(double opponentRating, double offset, double factor);
public double CalculatePhi(double opponentRD, double factor);
public double CalculateG(double phi);
public double CalculateE(double g, double opponentMu, double playerMu);
public double CalculateG2E(double phi, double e);
public double CalculateGsE(double phi, double e, double outcome);
public double CalculateNu(double g2ESum);
public double CalculateDelta(double gsESum, double nu);
}

}
62 changes: 62 additions & 0 deletions src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;

namespace Podium.RatingSystem.Glicko2
{
public class Glicko2RatingCalculator : IGlicko2RatingCalculator
{
public double CalculatePhi(double opponentRD, double factor)
{
return opponentRD / factor;
}

public double CalculateG(double phi)
{
var g = 1 + 3 * Math.Pow(phi, 2) * Math.Pow(Math.PI, -2);

g = Math.Pow(g, -0.5);

return g;
}

public double CalculateMu(double opponentRating, double offset, double factor)
{
var mu = (opponentRating - offset) / factor;

return mu;
}

public double CalculateE(double g, double opponentMu, double playerMu)
{
double E = 1 + Math.Exp(g * (opponentMu - playerMu));
E = Math.Pow(E, -1);

return E;
}

public double CalculateG2E(double g, double E)
{
var G2E = Math.Pow(g, 2) * E * (1 - E);

return G2E;
}

public double CalculateGsE(double g, double E, double outcome)
{
double GsE = g * (outcome - E);

return GsE;
}

public double CalculateNu(double g2ESum)
{
return 1 / g2ESum;
}

public double CalculateDelta(double gsESum, double nu)
{
return nu * gsESum;
}

}
}