From a56c5c5f05d5fe00b7827e7910c90ca7bae7dc93 Mon Sep 17 00:00:00 2001 From: jbw Date: Fri, 28 May 2021 21:30:38 +0100 Subject: [PATCH 1/4] calculate mu test --- .../Glicko2CalculatorUnitTests.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs diff --git a/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs new file mode 100644 index 0000000..85e66b9 --- /dev/null +++ b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs @@ -0,0 +1,30 @@ +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 phi = 0.466273481; + + IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator(); + + // When + var mu = glickoCalculator.CalculateMu(phi); + + // Then + double expectedMu = -1.640591879; + mu.ShouldBe(expectedMu, 0.01); + } + } +} From b50c89cfdc64ec9c3b37be6ec3162dcbd2d302e8 Mon Sep 17 00:00:00 2001 From: jbw Date: Sat, 5 Jun 2021 16:00:00 +0100 Subject: [PATCH 2/4] add sub calculations --- .../Glicko2CalculatorUnitTests.cs | 94 ++++++++++++++++++- .../Glicko/IGlicko2RatingCalculator.cs | 13 +++ .../Glicko2/Glicko2RatingCalculator.cs | 61 ++++++++++++ 3 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs create mode 100644 src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs diff --git a/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs index 85e66b9..3405d97 100644 --- a/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs +++ b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs @@ -9,10 +9,43 @@ 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_mu() + 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; @@ -20,11 +53,64 @@ public void Calculates_mu() IGlicko2RatingCalculator glickoCalculator = new Glicko2RatingCalculator(); // When - var mu = glickoCalculator.CalculateMu(phi); + var g = glickoCalculator.CalculateG(phi); // Then - double expectedMu = -1.640591879; - mu.ShouldBe(expectedMu, 0.01); + 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(); + + 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(); + + var GsE = glickoCalculator.CalculateGsE(g, E, outcome); + + // Then + double expectedGsE = 0.8800138; + GsE.ShouldBe(expectedGsE, 0.01); } } } diff --git a/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs b/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs new file mode 100644 index 0000000..28a43e6 --- /dev/null +++ b/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs @@ -0,0 +1,13 @@ +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); + } + +} diff --git a/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs new file mode 100644 index 0000000..17c3c63 --- /dev/null +++ b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +namespace Podium.RatingSystem.Glicko2 +{ + public class Glicko2RatingCalculator : IGlicko2RatingCalculator + { + public double CalculateE(double phi) + { + throw new NotImplementedException(); + } + + 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 CalculateG2E(double phi) + { + throw new NotImplementedException(); + } + + 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; + } + } +} \ No newline at end of file From 8660dea258d7757720ff1bc10c4da780b47e7ff7 Mon Sep 17 00:00:00 2001 From: jbw Date: Sat, 5 Jun 2021 16:13:51 +0100 Subject: [PATCH 3/4] calculate nu and delta --- .../Glicko2CalculatorUnitTests.cs | 35 +++++++++++++++++-- .../Glicko/IGlicko2RatingCalculator.cs | 2 ++ .../Glicko2/Glicko2RatingCalculator.cs | 11 ++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs index 3405d97..444357c 100644 --- a/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs +++ b/src/Podium.UnitTests/Glicko2CalculatorUnitTests.cs @@ -85,9 +85,9 @@ 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 @@ -103,14 +103,45 @@ public void Calculates_GsE() 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); + } } } diff --git a/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs b/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs index 28a43e6..26c2707 100644 --- a/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs +++ b/src/Podium/Calculators/Glicko/IGlicko2RatingCalculator.cs @@ -8,6 +8,8 @@ public interface IGlicko2RatingCalculator 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); } } diff --git a/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs index 17c3c63..a174349 100644 --- a/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs +++ b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs @@ -57,5 +57,16 @@ public double CalculateGsE(double g, double E, double outcome) return GsE; } + + public double CalculateNu(double g2ESum) + { + return 1 / g2ESum; + } + + public double CalculateDelta(double gsESum, double nu) + { + return nu * gsESum; + } + } } \ No newline at end of file From b0555e8ed65dee6eb7238c2b716c65d31997a76c Mon Sep 17 00:00:00 2001 From: jbw Date: Sat, 5 Jun 2021 16:15:33 +0100 Subject: [PATCH 4/4] remove unused --- .../Calculators/Glicko2/Glicko2RatingCalculator.cs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs index a174349..ce6c8d1 100644 --- a/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs +++ b/src/Podium/Calculators/Glicko2/Glicko2RatingCalculator.cs @@ -5,11 +5,6 @@ namespace Podium.RatingSystem.Glicko2 { public class Glicko2RatingCalculator : IGlicko2RatingCalculator { - public double CalculateE(double phi) - { - throw new NotImplementedException(); - } - public double CalculatePhi(double opponentRD, double factor) { return opponentRD / factor; @@ -24,11 +19,6 @@ public double CalculateG(double phi) return g; } - public double CalculateG2E(double phi) - { - throw new NotImplementedException(); - } - public double CalculateMu(double opponentRating, double offset, double factor) { var mu = (opponentRating - offset) / factor;