mirror of
https://github.com/furyfire/trueskill.git
synced 2025-04-04 14:24:01 +00:00
Initial version of Moserware.Skills TrueSkill calculator to go along with my Computing Your Skill blog post
This commit is contained in:
51
UnitTests/Elo/DuellingEloTest.cs
Normal file
51
UnitTests/Elo/DuellingEloTest.cs
Normal file
@ -0,0 +1,51 @@
|
||||
using Moserware.Skills;
|
||||
using Moserware.Skills.Elo;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Elo
|
||||
{
|
||||
[TestFixture]
|
||||
public class DuellingEloTest
|
||||
{
|
||||
private const double ErrorTolerance = 0.1;
|
||||
|
||||
[Test]
|
||||
public void TwoOnTwoDuellingTest()
|
||||
{
|
||||
var calculator = new DuellingEloCalculator(new GaussianEloCalculator());
|
||||
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating)
|
||||
.AddPlayer(player2, gameInfo.DefaultRating);
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// TODO: Verify?
|
||||
AssertRating(37, newRatingsWinLose[player1]);
|
||||
AssertRating(37, newRatingsWinLose[player2]);
|
||||
AssertRating(13, newRatingsWinLose[player3]);
|
||||
AssertRating(13, newRatingsWinLose[player4]);
|
||||
|
||||
var quality = calculator.CalculateMatchQuality(gameInfo, teams);
|
||||
Assert.AreEqual(1.0, quality, 0.001);
|
||||
}
|
||||
|
||||
private static void AssertRating(double expected, Rating actual)
|
||||
{
|
||||
Assert.AreEqual(expected, actual.Mean, ErrorTolerance);
|
||||
}
|
||||
}
|
||||
}
|
37
UnitTests/Elo/EloAssert.cs
Normal file
37
UnitTests/Elo/EloAssert.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Moserware.Skills;
|
||||
using Moserware.Skills.Elo;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Elo
|
||||
{
|
||||
internal static class EloAssert
|
||||
{
|
||||
private const double ErrorTolerance = 0.1;
|
||||
|
||||
public static void AssertChessRating(TwoPlayerEloCalculator calculator,
|
||||
double player1BeforeRating,
|
||||
double player2BeforeRating,
|
||||
PairwiseComparison player1Result,
|
||||
double player1AfterRating,
|
||||
double player2AfterRating)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var teams = Teams.Concat(
|
||||
new Team(player1, new EloRating(player1BeforeRating)),
|
||||
new Team(player2, new EloRating(player2BeforeRating)));
|
||||
|
||||
var chessGameInfo = new GameInfo(1200, 0, 200, 0, 0);
|
||||
|
||||
var result = calculator.CalculateNewRatings(chessGameInfo, teams,
|
||||
(player1Result == PairwiseComparison.Win) ? new[] { 1, 2 } :
|
||||
(player1Result == PairwiseComparison.Lose) ? new[] { 2, 1 } :
|
||||
new[] { 1, 1 });
|
||||
|
||||
|
||||
Assert.AreEqual(player1AfterRating, result[player1].Mean, ErrorTolerance);
|
||||
Assert.AreEqual(player2AfterRating, result[player2].Mean, ErrorTolerance);
|
||||
}
|
||||
}
|
||||
}
|
36
UnitTests/Elo/FideEloCalculatorTest.cs
Normal file
36
UnitTests/Elo/FideEloCalculatorTest.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using Moserware.Skills;
|
||||
using Moserware.Skills.Elo;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Elo
|
||||
{
|
||||
[TestFixture]
|
||||
public class FideEloCalculatorTest
|
||||
{
|
||||
[Test]
|
||||
public void FideProvisionalEloCalculatorTests()
|
||||
{
|
||||
// verified against http://ratings.fide.com/calculator_rtd.phtml
|
||||
var calc = new FideEloCalculator(new FideKFactor.Provisional());
|
||||
|
||||
EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Win, 1221.25, 1478.75);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Draw, 1208.75, 1491.25);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1500, PairwiseComparison.Lose, 1196.25, 1503.75);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FideNonProvisionalEloCalculatorTests()
|
||||
{
|
||||
// verified against http://ratings.fide.com/calculator_rtd.phtml
|
||||
var calc = new FideEloCalculator();
|
||||
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Win, 1207.5, 1192.5);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Draw, 1200, 1200);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Lose, 1192.5, 1207.5);
|
||||
|
||||
EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Win, 2603.6, 2496.4);
|
||||
EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Draw, 2598.6, 2501.4);
|
||||
EloAssert.AssertChessRating(calc, 2600, 2500, PairwiseComparison.Lose, 2593.6, 2506.4);
|
||||
}
|
||||
}
|
||||
}
|
26
UnitTests/Elo/GaussianEloCalculatorTest.cs
Normal file
26
UnitTests/Elo/GaussianEloCalculatorTest.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Moserware.Skills;
|
||||
using Moserware.Skills.Elo;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Elo
|
||||
{
|
||||
[TestFixture]
|
||||
public class GaussianEloCalculatorTest
|
||||
{
|
||||
[Test]
|
||||
public void GaussianEloCalculatorTests()
|
||||
{
|
||||
const double defaultKFactor = 24.0;
|
||||
var calc = new GaussianEloCalculator();
|
||||
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Win, 1212, 1188);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Draw, 1200, 1200);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1200, PairwiseComparison.Lose, 1188, 1212);
|
||||
|
||||
// verified using TrueSkill paper equation
|
||||
EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Win, 1200 + ((1 - 0.76024993890652326884) * defaultKFactor), 1000 - (1 - 0.76024993890652326884) * defaultKFactor);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Draw, 1200 - (0.76024993890652326884 - 0.5) * defaultKFactor, 1000 + (0.76024993890652326884 - 0.5) * defaultKFactor);
|
||||
EloAssert.AssertChessRating(calc, 1200, 1000, PairwiseComparison.Lose, 1200 - 0.76024993890652326884 * defaultKFactor, 1000 + 0.76024993890652326884 * defaultKFactor);
|
||||
}
|
||||
}
|
||||
}
|
68
UnitTests/Numerics/GaussianDistributionTests.cs
Normal file
68
UnitTests/Numerics/GaussianDistributionTests.cs
Normal file
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Moserware.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Numerics
|
||||
{
|
||||
[TestFixture]
|
||||
public class GaussianDistributionTests
|
||||
{
|
||||
private const double ErrorTolerance = 0.000001;
|
||||
|
||||
[Test]
|
||||
public void MultiplicationTests()
|
||||
{
|
||||
// I verified this against the formula at http://www.tina-vision.net/tina-knoppix/tina-memo/2003-003.pdf
|
||||
var standardNormal = new GaussianDistribution(0, 1);
|
||||
var shiftedGaussian = new GaussianDistribution(2, 3);
|
||||
|
||||
var product = standardNormal * shiftedGaussian;
|
||||
|
||||
Assert.AreEqual(0.2, product.Mean, ErrorTolerance);
|
||||
Assert.AreEqual(3.0 / Math.Sqrt(10), product.StandardDeviation, ErrorTolerance);
|
||||
|
||||
var m4s5 = new GaussianDistribution(4, 5);
|
||||
var m6s7 = new GaussianDistribution(6, 7);
|
||||
|
||||
var product2 = m4s5 * m6s7;
|
||||
Func<double, double> square = x => x*x;
|
||||
|
||||
var expectedMean = (4 * square(7) + 6 * square(5)) / (square(5) + square(7));
|
||||
Assert.AreEqual(expectedMean, product2.Mean, ErrorTolerance);
|
||||
|
||||
var expectedSigma = Math.Sqrt(((square(5) * square(7)) / (square(5) + square(7))));
|
||||
Assert.AreEqual(expectedSigma, product2.StandardDeviation, ErrorTolerance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DivisionTests()
|
||||
{
|
||||
// Since the multiplication was worked out by hand, we use the same numbers but work backwards
|
||||
var product = new GaussianDistribution(0.2, 3.0 / Math.Sqrt(10));
|
||||
var standardNormal = new GaussianDistribution(0, 1);
|
||||
|
||||
var productDividedByStandardNormal = product / standardNormal;
|
||||
Assert.AreEqual(2.0, productDividedByStandardNormal.Mean, ErrorTolerance);
|
||||
Assert.AreEqual(3.0, productDividedByStandardNormal.StandardDeviation, ErrorTolerance);
|
||||
|
||||
Func<double, double> square = x => x * x;
|
||||
var product2 = new GaussianDistribution((4 * square(7) + 6 * square(5)) / (square(5) + square(7)), Math.Sqrt(((square(5) * square(7)) / (square(5) + square(7)))));
|
||||
var m4s5 = new GaussianDistribution(4,5);
|
||||
var product2DividedByM4S5 = product2 / m4s5;
|
||||
Assert.AreEqual(6.0, product2DividedByM4S5.Mean, ErrorTolerance);
|
||||
Assert.AreEqual(7.0, product2DividedByM4S5.StandardDeviation, ErrorTolerance);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LogProductNormalizationTests()
|
||||
{
|
||||
var m4s5 = new GaussianDistribution(4, 5);
|
||||
var m6s7 = new GaussianDistribution(6, 7);
|
||||
|
||||
var product2 = m4s5 * m6s7;
|
||||
var normConstant = 1.0 / (Math.Sqrt(2 * Math.PI) * product2.StandardDeviation);
|
||||
var lpn = GaussianDistribution.LogProductNormalization(m4s5, m6s7);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
186
UnitTests/Numerics/MatrixTests.cs
Normal file
186
UnitTests/Numerics/MatrixTests.cs
Normal file
@ -0,0 +1,186 @@
|
||||
using Moserware.Numerics;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.Numerics
|
||||
{
|
||||
[TestFixture]
|
||||
public class MatrixTests
|
||||
{
|
||||
[Test]
|
||||
public void TwoByTwoDeterminantTests()
|
||||
{
|
||||
var a = new SquareMatrix(1, 2,
|
||||
3, 4);
|
||||
Assert.AreEqual(-2, a.Determinant);
|
||||
|
||||
var b = new SquareMatrix(3, 4,
|
||||
5, 6);
|
||||
Assert.AreEqual(-2, b.Determinant);
|
||||
|
||||
var c = new SquareMatrix(1, 1,
|
||||
1, 1);
|
||||
Assert.AreEqual(0, c.Determinant);
|
||||
|
||||
var d = new SquareMatrix(12, 15,
|
||||
17, 21);
|
||||
Assert.AreEqual(12 * 21 - 15 * 17, d.Determinant);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThreeByThreeDeterminantTests()
|
||||
{
|
||||
var a = new SquareMatrix(1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9);
|
||||
Assert.AreEqual(0, a.Determinant);
|
||||
|
||||
var π = new SquareMatrix(3, 1, 4,
|
||||
1, 5, 9,
|
||||
2, 6, 5);
|
||||
|
||||
// Verified against http://www.wolframalpha.com/input/?i=determinant+%7B%7B3%2C1%2C4%7D%2C%7B1%2C5%2C9%7D%2C%7B2%2C6%2C5%7D%7D
|
||||
Assert.AreEqual(-90, π.Determinant);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FourByFourDeterminantTests()
|
||||
{
|
||||
var a = new SquareMatrix( 1, 2, 3, 4,
|
||||
5, 6, 7, 8,
|
||||
9, 10, 11, 12,
|
||||
13, 14, 15, 16);
|
||||
|
||||
Assert.AreEqual(0, a.Determinant);
|
||||
|
||||
var π = new SquareMatrix(3, 1, 4, 1,
|
||||
5, 9, 2, 6,
|
||||
5, 3, 5, 8,
|
||||
9, 7, 9, 3);
|
||||
|
||||
// Verified against http://www.wolframalpha.com/input/?i=determinant+%7B+%7B3%2C1%2C4%2C1%7D%2C+%7B5%2C9%2C2%2C6%7D%2C+%7B5%2C3%2C5%2C8%7D%2C+%7B9%2C7%2C9%2C3%7D%7D
|
||||
Assert.AreEqual(98, π.Determinant);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EightByEightDeterminantTests()
|
||||
{
|
||||
var a = new SquareMatrix( 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24,
|
||||
25, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 32, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 52, 53, 54, 55, 56,
|
||||
57, 58, 59, 60, 61, 62, 63, 64);
|
||||
|
||||
Assert.AreEqual(0, a.Determinant);
|
||||
|
||||
var π = new SquareMatrix(3, 1, 4, 1, 5, 9, 2, 6,
|
||||
5, 3, 5, 8, 9, 7, 9, 3,
|
||||
2, 3, 8, 4, 6, 2, 6, 4,
|
||||
3, 3, 8, 3, 2, 7, 9, 5,
|
||||
0, 2, 8, 8, 4, 1, 9, 7,
|
||||
1, 6, 9, 3, 9, 9, 3, 7,
|
||||
5, 1, 0, 5, 8, 2, 0, 9,
|
||||
7, 4, 9, 4, 4, 5, 9, 2);
|
||||
|
||||
// Verified against http://www.wolframalpha.com/input/?i=det+%7B%7B3%2C1%2C4%2C1%2C5%2C9%2C2%2C6%7D%2C%7B5%2C3%2C5%2C8%2C9%2C7%2C9%2C3%7D%2C%7B2%2C3%2C8%2C4%2C6%2C2%2C6%2C4%7D%2C%7B3%2C3%2C8%2C3%2C2%2C7%2C9%2C5%7D%2C%7B0%2C2%2C8%2C8%2C4%2C1%2C9%2C7%7D%2C%7B1%2C6%2C9%2C3%2C9%2C9%2C3%2C7%7D%2C%7B5%2C1%2C0%2C5%2C8%2C2%2C0%2C9%7D%2C%7B7%2C4%2C9%2C4%2C4%2C5%2C9%2C2%7D%7D
|
||||
Assert.AreEqual(1378143, π.Determinant);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void EqualsTest()
|
||||
{
|
||||
var a = new SquareMatrix(1, 2,
|
||||
3, 4);
|
||||
|
||||
var b = new SquareMatrix(1, 2,
|
||||
3, 4);
|
||||
|
||||
Assert.IsTrue(a == b);
|
||||
Assert.AreEqual(a, b);
|
||||
|
||||
var c = new Matrix(2, 3,
|
||||
1, 2, 3,
|
||||
4, 5, 6);
|
||||
|
||||
var d = new Matrix(2, 3,
|
||||
1, 2, 3,
|
||||
4, 5, 6);
|
||||
|
||||
Assert.IsTrue(c == d);
|
||||
Assert.AreEqual(c, d);
|
||||
|
||||
var e = new Matrix(3, 2,
|
||||
1, 4,
|
||||
2, 5,
|
||||
3, 6);
|
||||
|
||||
var f = e.Transpose;
|
||||
Assert.IsTrue(d == f);
|
||||
Assert.AreEqual(d, f);
|
||||
Assert.AreEqual(d.GetHashCode(), f.GetHashCode());
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AdjugateTests()
|
||||
{
|
||||
// From Wikipedia: http://en.wikipedia.org/wiki/Adjugate_matrix
|
||||
|
||||
var a = new SquareMatrix(1, 2,
|
||||
3, 4);
|
||||
|
||||
var b = new SquareMatrix( 4, -2,
|
||||
-3, 1);
|
||||
|
||||
Assert.AreEqual(b, a.Adjugate);
|
||||
|
||||
|
||||
var c = new SquareMatrix(-3, 2, -5,
|
||||
-1, 0, -2,
|
||||
3, -4, 1);
|
||||
|
||||
var d = new SquareMatrix(-8, 18, -4,
|
||||
-5, 12, -1,
|
||||
4, -6, 2);
|
||||
|
||||
Assert.AreEqual(d, c.Adjugate);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void InverseTests()
|
||||
{
|
||||
// see http://www.mathwords.com/i/inverse_of_a_matrix.htm
|
||||
var a = new SquareMatrix(4, 3,
|
||||
3, 2);
|
||||
|
||||
var b = new SquareMatrix(-2, 3,
|
||||
3, -4);
|
||||
|
||||
var aInverse = a.Inverse;
|
||||
Assert.AreEqual(b, aInverse);
|
||||
|
||||
var identity2x2 = new IdentityMatrix(2);
|
||||
|
||||
var aaInverse = a * aInverse;
|
||||
Assert.IsTrue(identity2x2 == aaInverse);
|
||||
|
||||
var c = new SquareMatrix(1, 2, 3,
|
||||
0, 4, 5,
|
||||
1, 0, 6);
|
||||
|
||||
var cInverse = c.Inverse;
|
||||
var d = (1.0 / 22) * new SquareMatrix(24, -12, -2,
|
||||
5, 3, -5,
|
||||
-4, 2, 4);
|
||||
|
||||
|
||||
Assert.IsTrue(d == cInverse);
|
||||
var identity3x3 = new IdentityMatrix(3);
|
||||
|
||||
var ccInverse = c * cInverse;
|
||||
Assert.IsTrue(identity3x3 == ccInverse);
|
||||
}
|
||||
}
|
||||
}
|
35
UnitTests/Properties/AssemblyInfo.cs
Normal file
35
UnitTests/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("UnitTests")]
|
||||
[assembly: AssemblyDescription("Unit tests for Moserware.Skills")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Jeff Moser")]
|
||||
[assembly: AssemblyProduct("UnitTests")]
|
||||
[assembly: AssemblyCopyright("Copyright © Jeff Moser 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ddd7d430-f9c0-45c8-9576-70418d766e1f")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
23
UnitTests/README.txt
Normal file
23
UnitTests/README.txt
Normal file
@ -0,0 +1,23 @@
|
||||
These tests were written using NUnit 2.5.2 that is available for download
|
||||
at:
|
||||
|
||||
http://sourceforge.net/projects/nunit/files/NUnit%20Version%202/NUnit-2.5.2.9222.msi/download
|
||||
|
||||
If you have a different version or setup, you'll need to update the path under
|
||||
the UnitTests project properties by right clicking on UnitTests and then
|
||||
click "properties" and then click the "debug" tab. The "start external program"
|
||||
points to the NUnit test runner.
|
||||
|
||||
I did it this way so you didn't need more than the express version of
|
||||
Visual Studio to run. If you have a fancy test runner already, feel
|
||||
free to use that.
|
||||
|
||||
Additionally, it should be easy to update the tests to your tool
|
||||
of choice.
|
||||
|
||||
Finally, realize that these tests test *all* of the calculators
|
||||
implementations. For that reason, they create a new instance of
|
||||
a particular calculator. If you're using this code in your application,
|
||||
you can just use the convenience helper class of "TrueSkillCalculator"
|
||||
that has static methods. If you do that, you won't have to worry
|
||||
about creating your own instances.
|
34
UnitTests/RankSorterTest.cs
Normal file
34
UnitTests/RankSorterTest.cs
Normal file
@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using Moserware.Skills;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class RankSorterTest
|
||||
{
|
||||
[Test]
|
||||
public void SortAlreadySortedTest()
|
||||
{
|
||||
IEnumerable<string> people = new[] { "One", "Two", "Three" };
|
||||
int[] ranks = new[] { 1, 2, 3 };
|
||||
|
||||
RankSorter.Sort(ref people, ref ranks);
|
||||
|
||||
CollectionAssert.AreEqual(new[] { "One", "Two", "Three" }, people);
|
||||
CollectionAssert.AreEqual(new[] { 1, 2, 3 }, ranks);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SortUnsortedTest()
|
||||
{
|
||||
IEnumerable<string> people = new[] { "Five", "Two1", "Two2", "One", "Four" };
|
||||
int[] ranks = new[] { 5, 2, 2, 1, 4 };
|
||||
|
||||
RankSorter.Sort(ref people, ref ranks);
|
||||
|
||||
CollectionAssert.AreEqual(new[] { "One", "Two1", "Two2", "Four", "Five" }, people);
|
||||
CollectionAssert.AreEqual(new[] { 1, 2, 2, 4, 5 }, ranks);
|
||||
}
|
||||
}
|
||||
}
|
27
UnitTests/TrueSkill/DrawMarginTest.cs
Normal file
27
UnitTests/TrueSkill/DrawMarginTest.cs
Normal file
@ -0,0 +1,27 @@
|
||||
using Moserware.Skills.TrueSkill;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.TrueSkill
|
||||
{
|
||||
[TestFixture]
|
||||
public class DrawMarginTest
|
||||
{
|
||||
private const double ErrorTolerance = .000001;
|
||||
|
||||
[Test]
|
||||
public void GetDrawMarginFromDrawProbabilityTest()
|
||||
{
|
||||
double beta = 25.0 / 6.0;
|
||||
// The expected values were compared against Ralf Herbrich's implementation in F#
|
||||
AssertDrawMargin(0.10, beta, 0.74046637542690541);
|
||||
AssertDrawMargin(0.25, beta, 1.87760059883033);
|
||||
AssertDrawMargin(0.33, beta, 2.5111010132487492);
|
||||
}
|
||||
|
||||
private static void AssertDrawMargin(double drawProbability, double beta, double expected)
|
||||
{
|
||||
double actual = DrawMargin.GetDrawMarginFromDrawProbability(drawProbability, beta);
|
||||
Assert.AreEqual(expected, actual, ErrorTolerance);
|
||||
}
|
||||
}
|
||||
}
|
22
UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs
Normal file
22
UnitTests/TrueSkill/FactorGraphTrueSkillCalculatorTests.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Moserware.Skills.TrueSkill;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.TrueSkill
|
||||
{
|
||||
[TestFixture]
|
||||
public class FactorGraphTrueSkillCalculatorTests
|
||||
{
|
||||
[Test]
|
||||
public void FullFactorGraphCalculatorTests()
|
||||
{
|
||||
var calculator = new FactorGraphTrueSkillCalculator();
|
||||
|
||||
// We can test all classes
|
||||
TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator);
|
||||
TrueSkillCalculatorTests.TestAllTwoTeamScenarios(calculator);
|
||||
TrueSkillCalculatorTests.TestAllMultipleTeamScenarios(calculator);
|
||||
|
||||
TrueSkillCalculatorTests.TestPartialPlayScenarios(calculator);
|
||||
}
|
||||
}
|
||||
}
|
987
UnitTests/TrueSkill/TrueSkillCalculatorTests.cs
Normal file
987
UnitTests/TrueSkill/TrueSkillCalculatorTests.cs
Normal file
@ -0,0 +1,987 @@
|
||||
using Moserware.Skills;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.TrueSkill
|
||||
{
|
||||
public static class TrueSkillCalculatorTests
|
||||
{
|
||||
private const double ErrorTolerance = 0.085;
|
||||
|
||||
// These are the roll-up ones
|
||||
|
||||
public static void TestAllTwoPlayerScenarios(SkillCalculator calculator)
|
||||
{
|
||||
TwoPlayerTestNotDrawn(calculator);
|
||||
TwoPlayerTestDrawn(calculator);
|
||||
OneOnOneMassiveUpsetDrawTest(calculator);
|
||||
|
||||
TwoPlayerChessTestNotDrawn(calculator);
|
||||
}
|
||||
|
||||
public static void TestAllTwoTeamScenarios(SkillCalculator calculator)
|
||||
{
|
||||
OneOnTwoSimpleTest(calculator);
|
||||
OneOnTwoDrawTest(calculator);
|
||||
OneOnTwoSomewhatBalanced(calculator);
|
||||
OneOnThreeDrawTest(calculator);
|
||||
OneOnThreeSimpleTest(calculator);
|
||||
OneOnSevenSimpleTest(calculator);
|
||||
|
||||
TwoOnTwoSimpleTest(calculator);
|
||||
TwoOnTwoUnbalancedDrawTest(calculator);
|
||||
TwoOnTwoDrawTest(calculator);
|
||||
TwoOnTwoUpsetTest(calculator);
|
||||
|
||||
ThreeOnTwoTests(calculator);
|
||||
|
||||
FourOnFourSimpleTest(calculator);
|
||||
}
|
||||
|
||||
public static void TestAllMultipleTeamScenarios(SkillCalculator calculator)
|
||||
{
|
||||
ThreeTeamsOfOneNotDrawn(calculator);
|
||||
ThreeTeamsOfOneDrawn(calculator);
|
||||
FourTeamsOfOneNotDrawn(calculator);
|
||||
FiveTeamsOfOneNotDrawn(calculator);
|
||||
EightTeamsOfOneDrawn(calculator);
|
||||
EightTeamsOfOneUpset(calculator);
|
||||
SixteenTeamsOfOneNotDrawn(calculator);
|
||||
|
||||
TwoOnFourOnTwoWinDraw(calculator);
|
||||
}
|
||||
|
||||
public static void TestPartialPlayScenarios(SkillCalculator calculator)
|
||||
{
|
||||
OneOnTwoBalancedPartialPlay(calculator);
|
||||
}
|
||||
|
||||
//------------------- Actual Tests ---------------------------
|
||||
// If you see more than 3 digits of precision in the decimal point, then the expected values calculated from
|
||||
// F# RalfH's implementation with the same input. It didn't support teams, so team values all came from the
|
||||
// online calculator at http://atom.research.microsoft.com/trueskill/rankcalculator.aspx
|
||||
//
|
||||
// All match quality expected values came from the online calculator
|
||||
|
||||
// In both cases, there may be some discrepancy after the first decimal point. I think this is due to my implementation
|
||||
// using slightly higher precision in GaussianDistribution.
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Two Player Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void TwoPlayerTestNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(29.39583201999924, 7.171475587326186, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(20.60416798000076, 7.171475587326186, player2NewRating);
|
||||
|
||||
AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void TwoPlayerTestDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(25.0, 6.4575196623173081, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(25.0, 6.4575196623173081, player2NewRating);
|
||||
|
||||
AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void TwoPlayerChessTestNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
// Inspired by a real bug :-)
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var gameInfo = new GameInfo(1200.0, 1200.0 / 3.0, 200.0, 1200.0 / 300.0, 0.03);
|
||||
|
||||
var team1 = new Team(player1, new Rating(1301.0007, 42.9232));
|
||||
var team2 = new Team(player2, new Rating(1188.7560, 42.5570));
|
||||
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, Teams.Concat(team1, team2), 1, 2);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(1304.7820836053318, 42.843513887848658, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(1185.0383099003536, 42.485604606897752, player2NewRating);
|
||||
}
|
||||
|
||||
private static void OneOnOneMassiveUpsetDrawTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, new Rating(50, 12.5));
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(31.662, 7.137, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(35.010, 7.910, newRatingsWinLose[player2]);
|
||||
|
||||
AssertMatchQuality(0.110, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Two Team Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void TwoOnTwoSimpleTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating)
|
||||
.AddPlayer(player2, gameInfo.DefaultRating);
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(28.108, 7.774, newRatingsWinLose[player1]);
|
||||
AssertRating(28.108, 7.774, newRatingsWinLose[player2]);
|
||||
|
||||
// Losers
|
||||
AssertRating(21.892, 7.774, newRatingsWinLose[player3]);
|
||||
AssertRating(21.892, 7.774, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void TwoOnTwoDrawTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating)
|
||||
.AddPlayer(player2, gameInfo.DefaultRating);
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(25, 7.455, newRatingsWinLose[player1]);
|
||||
AssertRating(25, 7.455, newRatingsWinLose[player2]);
|
||||
|
||||
// Losers
|
||||
AssertRating(25, 7.455, newRatingsWinLose[player3]);
|
||||
AssertRating(25, 7.455, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void TwoOnTwoUnbalancedDrawTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, new Rating(15, 8))
|
||||
.AddPlayer(player2, new Rating(20, 6));
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, new Rating(25, 4))
|
||||
.AddPlayer(player4, new Rating(30, 3));
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(21.570, 6.556, newRatingsWinLose[player1]);
|
||||
AssertRating(23.696, 5.418, newRatingsWinLose[player2]);
|
||||
|
||||
// Losers
|
||||
AssertRating(23.357, 3.833, newRatingsWinLose[player3]);
|
||||
AssertRating(29.075, 2.931, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.214, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void TwoOnTwoUpsetTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, new Rating(20, 8))
|
||||
.AddPlayer(player2, new Rating(25, 6));
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, new Rating(35, 7))
|
||||
.AddPlayer(player4, new Rating(40, 5));
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(29.698, 7.008, newRatingsWinLose[player1]);
|
||||
AssertRating(30.455, 5.594, newRatingsWinLose[player2]);
|
||||
|
||||
// Losers
|
||||
AssertRating(27.575, 6.346, newRatingsWinLose[player3]);
|
||||
AssertRating(36.211, 4.768, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.084, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void FourOnFourSimpleTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating)
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player5, gameInfo.DefaultRating)
|
||||
.AddPlayer(player6, gameInfo.DefaultRating)
|
||||
.AddPlayer(player7, gameInfo.DefaultRating)
|
||||
.AddPlayer(player8, gameInfo.DefaultRating);
|
||||
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(27.198, 8.059, newRatingsWinLose[player1]);
|
||||
AssertRating(27.198, 8.059, newRatingsWinLose[player2]);
|
||||
AssertRating(27.198, 8.059, newRatingsWinLose[player3]);
|
||||
AssertRating(27.198, 8.059, newRatingsWinLose[player4]);
|
||||
|
||||
// Losers
|
||||
AssertRating(22.802, 8.059, newRatingsWinLose[player5]);
|
||||
AssertRating(22.802, 8.059, newRatingsWinLose[player6]);
|
||||
AssertRating(22.802, 8.059, newRatingsWinLose[player7]);
|
||||
AssertRating(22.802, 8.059, newRatingsWinLose[player8]);
|
||||
|
||||
AssertMatchQuality(0.447, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnTwoSimpleTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(33.730, 7.317, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(16.270, 7.317, newRatingsWinLose[player2]);
|
||||
AssertRating(16.270, 7.317, newRatingsWinLose[player3]);
|
||||
|
||||
AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnTwoSomewhatBalanced(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, new Rating(40, 6));
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, new Rating(20, 7))
|
||||
.AddPlayer(player3, new Rating(25, 8));
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(42.744, 5.602, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(16.266, 6.359, newRatingsWinLose[player2]);
|
||||
AssertRating(20.123, 7.028, newRatingsWinLose[player3]);
|
||||
|
||||
AssertMatchQuality(0.478, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnThreeSimpleTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(36.337, 7.527, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(13.663, 7.527, newRatingsWinLose[player2]);
|
||||
AssertRating(13.663, 7.527, newRatingsWinLose[player3]);
|
||||
AssertRating(13.663, 7.527, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnTwoDrawTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(31.660, 7.138, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(18.340, 7.138, newRatingsWinLose[player2]);
|
||||
AssertRating(18.340, 7.138, newRatingsWinLose[player3]);
|
||||
|
||||
AssertMatchQuality(0.135, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnThreeDrawTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(34.990, 7.455, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(15.010, 7.455, newRatingsWinLose[player2]);
|
||||
AssertRating(15.010, 7.455, newRatingsWinLose[player3]);
|
||||
AssertRating(15.010, 7.455, newRatingsWinLose[player4]);
|
||||
|
||||
AssertMatchQuality(0.012, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void OneOnSevenSimpleTest(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, gameInfo.DefaultRating);
|
||||
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player2, gameInfo.DefaultRating)
|
||||
.AddPlayer(player3, gameInfo.DefaultRating)
|
||||
.AddPlayer(player4, gameInfo.DefaultRating)
|
||||
.AddPlayer(player5, gameInfo.DefaultRating)
|
||||
.AddPlayer(player6, gameInfo.DefaultRating)
|
||||
.AddPlayer(player7, gameInfo.DefaultRating)
|
||||
.AddPlayer(player8, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(40.582, 7.917, newRatingsWinLose[player1]);
|
||||
|
||||
// Losers
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player2]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player3]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player4]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player5]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player6]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player7]);
|
||||
AssertRating(9.418, 7.917, newRatingsWinLose[player8]);
|
||||
|
||||
AssertMatchQuality(0.000, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void ThreeOnTwoTests(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, new Rating(28, 7))
|
||||
.AddPlayer(player2, new Rating(27, 6))
|
||||
.AddPlayer(player3, new Rating(26, 5));
|
||||
|
||||
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player4, new Rating(30, 4))
|
||||
.AddPlayer(player5, new Rating(31, 3));
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatingsWinLoseExpected = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(28.658, 6.770, newRatingsWinLoseExpected[player1]);
|
||||
AssertRating(27.484, 5.856, newRatingsWinLoseExpected[player2]);
|
||||
AssertRating(26.336, 4.917, newRatingsWinLoseExpected[player3]);
|
||||
|
||||
// Losers
|
||||
AssertRating(29.785, 3.958, newRatingsWinLoseExpected[player4]);
|
||||
AssertRating(30.879, 2.983, newRatingsWinLoseExpected[player5]);
|
||||
|
||||
var newRatingsWinLoseUpset = calculator.CalculateNewRatings(gameInfo, Teams.Concat(team1, team2), 2, 1);
|
||||
|
||||
// Winners
|
||||
AssertRating(32.012, 3.877, newRatingsWinLoseUpset[player4]);
|
||||
AssertRating(32.132, 2.949, newRatingsWinLoseUpset[player5]);
|
||||
|
||||
// Losers
|
||||
AssertRating(21.840, 6.314, newRatingsWinLoseUpset[player1]);
|
||||
AssertRating(22.474, 5.575, newRatingsWinLoseUpset[player2]);
|
||||
AssertRating(22.857, 4.757, newRatingsWinLoseUpset[player3]);
|
||||
|
||||
AssertMatchQuality(0.254, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Multiple Teams Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void TwoOnFourOnTwoWinDraw(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team()
|
||||
.AddPlayer(player1, new Rating(40,4))
|
||||
.AddPlayer(player2, new Rating(45,3));
|
||||
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(player3, new Rating(20, 7))
|
||||
.AddPlayer(player4, new Rating(19, 6))
|
||||
.AddPlayer(player5, new Rating(30, 9))
|
||||
.AddPlayer(player6, new Rating(10, 4));
|
||||
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
|
||||
var team3 = new Team()
|
||||
.AddPlayer(player7, new Rating(50,5))
|
||||
.AddPlayer(player8, new Rating(30,2));
|
||||
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3);
|
||||
var newRatingsWinLose = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 2);
|
||||
|
||||
// Winners
|
||||
AssertRating(40.877, 3.840, newRatingsWinLose[player1]);
|
||||
AssertRating(45.493, 2.934, newRatingsWinLose[player2]);
|
||||
AssertRating(19.609, 6.396, newRatingsWinLose[player3]);
|
||||
AssertRating(18.712, 5.625, newRatingsWinLose[player4]);
|
||||
AssertRating(29.353, 7.673, newRatingsWinLose[player5]);
|
||||
AssertRating(9.872, 3.891, newRatingsWinLose[player6]);
|
||||
AssertRating(48.830, 4.590, newRatingsWinLose[player7]);
|
||||
AssertRating(29.813, 1.976, newRatingsWinLose[player8]);
|
||||
|
||||
AssertMatchQuality(0.367, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void ThreeTeamsOfOneNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(31.675352419172107, 6.6559853776206905, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(25.000000000003912, 6.2078966412243233, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(18.324647580823971, 6.6559853776218318, player3NewRating);
|
||||
|
||||
AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void ThreeTeamsOfOneDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(25.000, 5.698, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(25.000, 5.695, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(25.000, 5.698, player3NewRating);
|
||||
|
||||
AssertMatchQuality(0.200, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void FourTeamsOfOneNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
var team4 = new Team(player4, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3, team4);
|
||||
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(33.206680965631264, 6.3481091698077057, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(27.401454693843323, 5.7871629348447584, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(22.598545306188374, 5.7871629348413451, player3NewRating);
|
||||
|
||||
var player4NewRating = newRatings[player4];
|
||||
AssertRating(16.793319034361271, 6.3481091698144967, player4NewRating);
|
||||
|
||||
AssertMatchQuality(0.089, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void FiveTeamsOfOneNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
var team4 = new Team(player4, gameInfo.DefaultRating);
|
||||
var team5 = new Team(player5, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3, team4, team5);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4, 5);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(34.363135705841188, 6.1361528798112692, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(29.058448805636779, 5.5358352402833413, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(25.000000000031758, 5.4200805474429847, player3NewRating);
|
||||
|
||||
var player4NewRating = newRatings[player4];
|
||||
AssertRating(20.941551194426314, 5.5358352402709672, player4NewRating);
|
||||
|
||||
var player5NewRating = newRatings[player5];
|
||||
AssertRating(15.636864294158848, 6.136152879829349, player5NewRating);
|
||||
|
||||
AssertMatchQuality(0.040, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void EightTeamsOfOneDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
var team4 = new Team(player4, gameInfo.DefaultRating);
|
||||
var team5 = new Team(player5, gameInfo.DefaultRating);
|
||||
var team6 = new Team(player6, gameInfo.DefaultRating);
|
||||
var team7 = new Team(player7, gameInfo.DefaultRating);
|
||||
var team8 = new Team(player8, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(25.000, 4.592, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(25.000, 4.583, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(25.000, 4.576, player3NewRating);
|
||||
|
||||
var player4NewRating = newRatings[player4];
|
||||
AssertRating(25.000, 4.573, player4NewRating);
|
||||
|
||||
var player5NewRating = newRatings[player5];
|
||||
AssertRating(25.000, 4.573, player5NewRating);
|
||||
|
||||
var player6NewRating = newRatings[player6];
|
||||
AssertRating(25.000, 4.576, player6NewRating);
|
||||
|
||||
var player7NewRating = newRatings[player7];
|
||||
AssertRating(25.000, 4.583, player7NewRating);
|
||||
|
||||
var player8NewRating = newRatings[player8];
|
||||
AssertRating(25.000, 4.592, player8NewRating);
|
||||
|
||||
AssertMatchQuality(0.004, calculator.CalculateMatchQuality(gameInfo, teams));
|
||||
}
|
||||
|
||||
private static void EightTeamsOfOneUpset(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, new Rating(10, 8));
|
||||
var team2 = new Team(player2, new Rating(15, 7));
|
||||
var team3 = new Team(player3, new Rating(20, 6));
|
||||
var team4 = new Team(player4, new Rating(25, 5));
|
||||
var team5 = new Team(player5, new Rating(30, 4));
|
||||
var team6 = new Team(player6, new Rating(35, 3));
|
||||
var team7 = new Team(player7, new Rating(40, 2));
|
||||
var team8 = new Team(player8, new Rating(45, 1));
|
||||
|
||||
var teams = Teams.Concat(team1, team2, team3, team4, team5, team6, team7, team8);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2, 3, 4, 5, 6, 7, 8);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(35.135, 4.506, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(32.585, 4.037, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(31.329, 3.756, player3NewRating);
|
||||
|
||||
var player4NewRating = newRatings[player4];
|
||||
AssertRating(30.984, 3.453, player4NewRating);
|
||||
|
||||
var player5NewRating = newRatings[player5];
|
||||
AssertRating(31.751, 3.064, player5NewRating);
|
||||
|
||||
var player6NewRating = newRatings[player6];
|
||||
AssertRating(34.051, 2.541, player6NewRating);
|
||||
|
||||
var player7NewRating = newRatings[player7];
|
||||
AssertRating(38.263, 1.849, player7NewRating);
|
||||
|
||||
var player8NewRating = newRatings[player8];
|
||||
AssertRating(44.118, 0.983, player8NewRating);
|
||||
|
||||
AssertMatchQuality(0.000, calculator.CalculateMatchQuality(gameInfo,teams));
|
||||
}
|
||||
|
||||
private static void SixteenTeamsOfOneNotDrawn(SkillCalculator calculator)
|
||||
{
|
||||
var player1 = new Player(1);
|
||||
var player2 = new Player(2);
|
||||
var player3 = new Player(3);
|
||||
var player4 = new Player(4);
|
||||
var player5 = new Player(5);
|
||||
var player6 = new Player(6);
|
||||
var player7 = new Player(7);
|
||||
var player8 = new Player(8);
|
||||
var player9 = new Player(9);
|
||||
var player10 = new Player(10);
|
||||
var player11 = new Player(11);
|
||||
var player12 = new Player(12);
|
||||
var player13 = new Player(13);
|
||||
var player14 = new Player(14);
|
||||
var player15 = new Player(15);
|
||||
var player16 = new Player(16);
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var team1 = new Team(player1, gameInfo.DefaultRating);
|
||||
var team2 = new Team(player2, gameInfo.DefaultRating);
|
||||
var team3 = new Team(player3, gameInfo.DefaultRating);
|
||||
var team4 = new Team(player4, gameInfo.DefaultRating);
|
||||
var team5 = new Team(player5, gameInfo.DefaultRating);
|
||||
var team6 = new Team(player6, gameInfo.DefaultRating);
|
||||
var team7 = new Team(player7, gameInfo.DefaultRating);
|
||||
var team8 = new Team(player8, gameInfo.DefaultRating);
|
||||
var team9 = new Team(player9, gameInfo.DefaultRating);
|
||||
var team10 = new Team(player10, gameInfo.DefaultRating);
|
||||
var team11 = new Team(player11, gameInfo.DefaultRating);
|
||||
var team12 = new Team(player12, gameInfo.DefaultRating);
|
||||
var team13 = new Team(player13, gameInfo.DefaultRating);
|
||||
var team14 = new Team(player14, gameInfo.DefaultRating);
|
||||
var team15 = new Team(player15, gameInfo.DefaultRating);
|
||||
var team16 = new Team(player16, gameInfo.DefaultRating);
|
||||
|
||||
var newRatings =
|
||||
calculator.CalculateNewRatings(
|
||||
gameInfo,
|
||||
Teams.Concat(
|
||||
team1, team2, team3, team4, team5,
|
||||
team6, team7, team8, team9, team10,
|
||||
team11, team12, team13, team14, team15,
|
||||
team16),
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
|
||||
|
||||
var player1NewRating = newRatings[player1];
|
||||
AssertRating(40.53945776946920, 5.27581643889050, player1NewRating);
|
||||
|
||||
var player2NewRating = newRatings[player2];
|
||||
AssertRating(36.80951229454210, 4.71121217610266, player2NewRating);
|
||||
|
||||
var player3NewRating = newRatings[player3];
|
||||
AssertRating(34.34726355544460, 4.52440328139991, player3NewRating);
|
||||
|
||||
var player4NewRating = newRatings[player4];
|
||||
AssertRating(32.33614722608720, 4.43258628279632, player4NewRating);
|
||||
|
||||
var player5NewRating = newRatings[player5];
|
||||
AssertRating(30.55048814671730, 4.38010805034365, player5NewRating);
|
||||
|
||||
var player6NewRating = newRatings[player6];
|
||||
AssertRating(28.89277312234790, 4.34859291776483, player6NewRating);
|
||||
|
||||
var player7NewRating = newRatings[player7];
|
||||
AssertRating(27.30952161972210, 4.33037679041216, player7NewRating);
|
||||
|
||||
var player8NewRating = newRatings[player8];
|
||||
AssertRating(25.76571046519540, 4.32197078088701, player8NewRating);
|
||||
|
||||
var player9NewRating = newRatings[player9];
|
||||
AssertRating(24.23428953480470, 4.32197078088703, player9NewRating);
|
||||
|
||||
var player10NewRating = newRatings[player10];
|
||||
AssertRating(22.69047838027800, 4.33037679041219, player10NewRating);
|
||||
|
||||
var player11NewRating = newRatings[player11];
|
||||
AssertRating(21.10722687765220, 4.34859291776488, player11NewRating);
|
||||
|
||||
var player12NewRating = newRatings[player12];
|
||||
AssertRating(19.44951185328290, 4.38010805034375, player12NewRating);
|
||||
|
||||
var player13NewRating = newRatings[player13];
|
||||
AssertRating(17.66385277391300, 4.43258628279643, player13NewRating);
|
||||
|
||||
var player14NewRating = newRatings[player14];
|
||||
AssertRating(15.65273644455550, 4.52440328139996, player14NewRating);
|
||||
|
||||
var player15NewRating = newRatings[player15];
|
||||
AssertRating(13.19048770545810, 4.71121217610273, player15NewRating);
|
||||
|
||||
var player16NewRating = newRatings[player16];
|
||||
AssertRating(9.46054223053080, 5.27581643889032, player16NewRating);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Partial Play Tests
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void OneOnTwoBalancedPartialPlay(SkillCalculator calculator)
|
||||
{
|
||||
var gameInfo = GameInfo.DefaultGameInfo;
|
||||
|
||||
var p1 = new Player(1);
|
||||
var team1 = new Team(p1, gameInfo.DefaultRating);
|
||||
|
||||
var p2 = new Player(2, 0.0);
|
||||
var p3 = new Player(3, 1.00);
|
||||
|
||||
var team2 = new Team()
|
||||
.AddPlayer(p2, gameInfo.DefaultRating)
|
||||
.AddPlayer(p3, gameInfo.DefaultRating);
|
||||
|
||||
var teams = Teams.Concat(team1, team2);
|
||||
var newRatings = calculator.CalculateNewRatings(gameInfo, teams, 1, 2);
|
||||
var matchQuality = calculator.CalculateMatchQuality(gameInfo, teams);
|
||||
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private static void AssertRating(double expectedMean, double expectedStandardDeviation, Rating actual)
|
||||
{
|
||||
Assert.AreEqual(expectedMean, actual.Mean, ErrorTolerance);
|
||||
Assert.AreEqual(expectedStandardDeviation, actual.StandardDeviation, ErrorTolerance);
|
||||
}
|
||||
|
||||
private static void AssertMatchQuality(double expectedMatchQuality, double actualMatchQuality)
|
||||
{
|
||||
Assert.AreEqual(expectedMatchQuality, actualMatchQuality, 0.0005);
|
||||
}
|
||||
}
|
||||
}
|
20
UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs
Normal file
20
UnitTests/TrueSkill/TwoPlayerTrueSkillCalculatorTest.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using Moserware.Skills.TrueSkill;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.TrueSkill
|
||||
{
|
||||
[TestFixture]
|
||||
public class TwoPlayerTrueSkillCalculatorTest
|
||||
{
|
||||
[Test]
|
||||
public void TwoPlayerTrueSkillCalculatorTests()
|
||||
{
|
||||
var calculator = new TwoPlayerTrueSkillCalculator();
|
||||
|
||||
// We only support two players
|
||||
TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator);
|
||||
|
||||
// TODO: Assert failures for larger teams
|
||||
}
|
||||
}
|
||||
}
|
19
UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs
Normal file
19
UnitTests/TrueSkill/TwoTeamTrueSkillCalculatorTest.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using Moserware.Skills.TrueSkill;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace UnitTests.TrueSkill
|
||||
{
|
||||
[TestFixture]
|
||||
public class TwoTeamTrueSkillCalculatorTest
|
||||
{
|
||||
[Test]
|
||||
public void TwoTeamTrueSkillCalculatorTests()
|
||||
{
|
||||
var calculator = new TwoTeamTrueSkillCalculator();
|
||||
|
||||
// This calculator supports up to two teams with many players each
|
||||
TrueSkillCalculatorTests.TestAllTwoPlayerScenarios(calculator);
|
||||
TrueSkillCalculatorTests.TestAllTwoTeamScenarios(calculator);
|
||||
}
|
||||
}
|
||||
}
|
80
UnitTests/UnitTests.csproj
Normal file
80
UnitTests/UnitTests.csproj
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{6F80946D-AC8B-4063-8588-96841C18BF0A}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>UnitTests</RootNamespace>
|
||||
<AssemblyName>UnitTests</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="nunit.framework, Version=2.5.2.9222, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Elo\DuellingEloTest.cs" />
|
||||
<Compile Include="Elo\EloAssert.cs" />
|
||||
<Compile Include="Elo\GaussianEloCalculatorTest.cs" />
|
||||
<Compile Include="TrueSkill\DrawMarginTest.cs" />
|
||||
<Compile Include="TrueSkill\FactorGraphTrueSkillCalculatorTests.cs" />
|
||||
<Compile Include="Elo\FideEloCalculatorTest.cs" />
|
||||
<Compile Include="Numerics\GaussianDistributionTests.cs" />
|
||||
<Compile Include="Numerics\MatrixTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="RankSorterTest.cs" />
|
||||
<Compile Include="TrueSkill\TrueSkillCalculatorTests.cs" />
|
||||
<Compile Include="TrueSkill\TwoPlayerTrueSkillCalculatorTest.cs" />
|
||||
<Compile Include="TrueSkill\TwoTeamTrueSkillCalculatorTest.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Skills\Skills.csproj">
|
||||
<Project>{15AD1345-984C-48ED-AF9A-2EAB44E5AA2B}</Project>
|
||||
<Name>Skills</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="README.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
9
UnitTests/UnitTests.csproj.user
Normal file
9
UnitTests/UnitTests.csproj.user
Normal file
@ -0,0 +1,9 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>C:\Program Files (x86)\NUnit 2.5.2\bin\net-2.0\nunit.exe</StartProgram>
|
||||
<StartWorkingDirectory>
|
||||
</StartWorkingDirectory>
|
||||
<StartArguments>UnitTests.dll</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
Reference in New Issue
Block a user