mirror of
https://github.com/furyfire/trueskill.git
synced 2025-01-15 17:37:39 +00:00
Compare commits
4 Commits
c18ccd38e2
...
99eb3271c2
Author | SHA1 | Date | |
---|---|---|---|
99eb3271c2 | |||
747f06f7c9 | |||
1bbc4bb91c | |||
1359cbeb6b |
8
README
8
README
@ -6,4 +6,10 @@ For more details on how the algorithm works, see
|
||||
|
||||
http://www.moserware.com/2010/03/computing-your-skill.html
|
||||
|
||||
For details on how to use this project, see the accompanying unit tests with this project
|
||||
For details on how to use this project, see the accompanying example snippets with this project.
|
||||
|
||||
For development Composer and the following packages are used (Recommended as Phars installed via Phive)
|
||||
|
||||
sudo phive install -g composer phpdocumentor infection phpcs phpcbf phploc phpbench overtrue/phplint
|
||||
composer install
|
||||
composer all
|
72
composer.lock
generated
72
composer.lock
generated
@ -1590,16 +1590,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "10.5.9",
|
||||
"version": "10.5.10",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe"
|
||||
"reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
|
||||
"reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50b8e314b6d0dd06521dc31d1abffa73f25f850c",
|
||||
"reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -1671,7 +1671,7 @@
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.9"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.10"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -1687,7 +1687,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-22T14:35:40+00:00"
|
||||
"time": "2024-02-04T09:07:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
@ -2928,16 +2928,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.28.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -2951,9 +2951,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -2990,7 +2987,7 @@
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3006,20 +3003,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-grapheme",
|
||||
"version": "v1.28.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
|
||||
"reference": "875e90aeea2777b6f135677f618529449334a612"
|
||||
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
|
||||
"reference": "875e90aeea2777b6f135677f618529449334a612",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
|
||||
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3030,9 +3027,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -3071,7 +3065,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3087,20 +3081,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-intl-normalizer",
|
||||
"version": "v1.28.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
|
||||
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
|
||||
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
|
||||
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3111,9 +3105,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -3155,7 +3146,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
|
||||
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3171,20 +3162,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.28.0",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229"
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@ -3198,9 +3189,6 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@ -3238,7 +3226,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@ -3254,7 +3242,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-07-28T09:04:16+00:00"
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
|
@ -7,7 +7,8 @@
|
||||
"tests"
|
||||
],
|
||||
"report": {
|
||||
"html": "output/metrics/"
|
||||
"html": "output/metrics/",
|
||||
"json": "output/metrics/report.json"
|
||||
},
|
||||
"plugins": {
|
||||
"git": {
|
||||
|
@ -18,6 +18,7 @@
|
||||
<coverage>
|
||||
<report>
|
||||
<html outputDirectory="output/coverage" />
|
||||
<clover outputFile ="output/coverage/clover.xml" />
|
||||
</report>
|
||||
</coverage>
|
||||
</phpunit>
|
||||
|
@ -8,11 +8,6 @@ class FactorGraph
|
||||
{
|
||||
private VariableFactory $variableFactory;
|
||||
|
||||
public function __construct(VariableFactory $factory)
|
||||
{
|
||||
$this->variableFactory = $factory;
|
||||
}
|
||||
|
||||
public function getVariableFactory(): VariableFactory
|
||||
{
|
||||
return $this->variableFactory;
|
||||
|
22
tests/GameInfoTest.php
Normal file
22
tests/GameInfoTest.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DNW\Skills\Tests;
|
||||
|
||||
use DNW\Skills\GameInfo;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class GameInfoTest extends TestCase
|
||||
{
|
||||
public function testMembers(): void
|
||||
{
|
||||
$gi = new GameInfo(1, 2, 3, 4, 5);
|
||||
$this->assertEquals(1, $gi->getInitialMean());
|
||||
$this->assertEquals(2, $gi->getInitialStandardDeviation());
|
||||
$this->assertEquals(3, $gi->getBeta());
|
||||
$this->assertEquals(4, $gi->getDynamicsFactor());
|
||||
$this->assertEquals(5, $gi->getDrawProbability());
|
||||
$this->assertInstanceOf(\DNW\Skills\Rating::class, $gi->getDefaultRating());
|
||||
}
|
||||
}
|
@ -15,4 +15,18 @@ class BasicMathTest extends TestCase
|
||||
$this->assertEquals(1.44, BasicMath::square(1.2));
|
||||
$this->assertEquals(4, BasicMath::square(2));
|
||||
}
|
||||
|
||||
public function testSum(): void
|
||||
{
|
||||
$arr = [1, 1, 1, 1];
|
||||
|
||||
$func_return = function ($f) {
|
||||
return $f;
|
||||
};
|
||||
$func_double = function ($f) {
|
||||
return $f * 2;
|
||||
};
|
||||
$this->assertEquals(4, BasicMath::sum($arr, $func_return));
|
||||
$this->assertEquals(8, BasicMath::sum($arr, $func_double));
|
||||
}
|
||||
}
|
||||
|
@ -7,12 +7,27 @@ namespace DNW\Skills\Tests\Numerics;
|
||||
use DNW\Skills\Numerics\IdentityMatrix;
|
||||
use DNW\Skills\Numerics\Matrix;
|
||||
use DNW\Skills\Numerics\SquareMatrix;
|
||||
use DNW\Skills\Numerics\DiagonalMatrix;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use Exception;
|
||||
|
||||
#[CoversClass(Matrix::class)]
|
||||
#[UsesClass(SquareMatrix::class)]
|
||||
#[UsesClass(IdentityMatrix::class)]
|
||||
#[UsesClass(DiagonalMatrix::class)]
|
||||
// phpcs:disable PSR2.Methods.FunctionCallSignature,Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma
|
||||
class MatrixTest extends TestCase
|
||||
{
|
||||
public function testOneByOneDeterminant(): void
|
||||
{
|
||||
$a = new SquareMatrix(1);
|
||||
|
||||
$this->assertEquals(1, $a->getDeterminant());
|
||||
}
|
||||
|
||||
|
||||
public function testTwoByTwoDeterminant(): void
|
||||
{
|
||||
$a = new SquareMatrix(1, 2,
|
||||
@ -110,9 +125,7 @@ class MatrixTest extends TestCase
|
||||
1, 2, 3,
|
||||
4, 5, 6);
|
||||
|
||||
$d = Matrix::fromRowsColumns(2, 3,
|
||||
1, 2, 3,
|
||||
4, 5, 6);
|
||||
$d = Matrix::fromColumnValues(2, 3, [[1, 4], [2, 5], [3,6]]);
|
||||
|
||||
$this->assertTrue($c->equals($d));
|
||||
|
||||
@ -144,6 +157,21 @@ class MatrixTest extends TestCase
|
||||
$this->assertFalse($k->equals($l));
|
||||
}
|
||||
|
||||
public function testAdd(): void
|
||||
{
|
||||
// From Wikipedia: http://en.wikipedia.org/wiki/Adjugate_matrix
|
||||
$a = new SquareMatrix(1, 2,
|
||||
3, 4);
|
||||
|
||||
$b = new SquareMatrix(4, 3,
|
||||
2, 1);
|
||||
|
||||
$sum = Matrix::add($a, $b);
|
||||
|
||||
$result = new SquareMatrix(5, 5, 5, 5);
|
||||
$this->assertEquals(TRUE, $result->equals($sum));
|
||||
}
|
||||
|
||||
public function testAdjugate(): void
|
||||
{
|
||||
// From Wikipedia: http://en.wikipedia.org/wiki/Adjugate_matrix
|
||||
@ -197,6 +225,14 @@ class MatrixTest extends TestCase
|
||||
|
||||
$ccInverse = Matrix::multiply($c, $cInverse);
|
||||
$this->assertTrue($identity3x3->equals($ccInverse));
|
||||
|
||||
|
||||
$e = new SquareMatrix(10);
|
||||
|
||||
$f = new SquareMatrix(0.1);
|
||||
|
||||
$eInverse = $e->getInverse();
|
||||
$this->assertTrue($f->equals($eInverse));
|
||||
}
|
||||
|
||||
public function testErrorDeterminant(): void
|
||||
|
@ -27,5 +27,19 @@ class RangeTest extends TestCase
|
||||
$range = Range::inclusive(1, 10);
|
||||
$this->assertEquals(1, $range->getMin());
|
||||
$this->assertEquals(10, $range->getMax());
|
||||
$this->assertEquals(FALSE, $range->isInRange(0));
|
||||
$this->assertEquals(TRUE, $range->isInRange(1));
|
||||
$this->assertEquals(TRUE, $range->isInRange(2));
|
||||
$this->assertEquals(TRUE, $range->isInRange(9));
|
||||
$this->assertEquals(TRUE, $range->isInRange(10));
|
||||
$this->assertEquals(FALSE, $range->isInRange(11));
|
||||
|
||||
$range = Range::atLeast(20);
|
||||
$this->assertEquals(20, $range->getMin());
|
||||
$this->assertEquals(PHP_INT_MAX, $range->getMax());
|
||||
|
||||
$range = Range::exactly(5);
|
||||
$this->assertEquals(5, $range->getMin());
|
||||
$this->assertEquals(5, $range->getMax());
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DNW\Skills\Tests\TrueSkill;
|
||||
|
||||
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
|
||||
use DNW\Skills\SkillCalculatorSupportedOptions;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FactorGraphTeamTrueSkillCalculatorTest extends TestCase
|
||||
{
|
||||
public function testFactorGraphTrueSkillCalculator(): void
|
||||
{
|
||||
$calculator = new FactorGraphTrueSkillCalculator();
|
||||
|
||||
TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testAllTwoTeamScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testAllMultipleTeamScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testPartialPlayScenarios($this, $calculator);
|
||||
}
|
||||
|
||||
public function testMethodisSupported(): void
|
||||
{
|
||||
$calculator = new FactorGraphTrueSkillCalculator();
|
||||
$this->assertEquals(TRUE, $calculator->isSupported(SkillCalculatorSupportedOptions::PARTIAL_PLAY));
|
||||
}
|
||||
}
|
@ -8,10 +8,20 @@ use DNW\Skills\GameInfo;
|
||||
use DNW\Skills\Player;
|
||||
use DNW\Skills\Team;
|
||||
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
|
||||
use DNW\Skills\SkillCalculatorSupportedOptions;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\CoversNothing;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
|
||||
#[CoversClass(FactorGraphTrueSkillCalculator::class)]
|
||||
#[UsesClass(\DNW\Skills\Numerics\Range::class)]
|
||||
#[UsesClass(\DNW\Skills\PlayersRange::class)]
|
||||
#[UsesClass(\DNW\Skills\SkillCalculator::class)]
|
||||
#[UsesClass(\DNW\Skills\TeamsRange::class)]
|
||||
class FactorGraphTrueSkillCalculatorTest extends TestCase
|
||||
{
|
||||
#[CoversNothing]
|
||||
public function testMicrosoftResearchExample(): void
|
||||
{
|
||||
$gameInfo = new GameInfo();
|
||||
@ -53,4 +63,21 @@ class FactorGraphTrueSkillCalculatorTest extends TestCase
|
||||
$this->assertEqualsWithDelta($expected[$player->getId()][1], $rating->getStandardDeviation(), 0.001);
|
||||
}
|
||||
}
|
||||
|
||||
#[CoversNothing]
|
||||
public function testFactorGraphTrueSkillCalculator(): void
|
||||
{
|
||||
$calculator = new FactorGraphTrueSkillCalculator();
|
||||
|
||||
TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testAllTwoTeamScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testAllMultipleTeamScenarios($this, $calculator);
|
||||
TrueSkillCalculatorTests::testPartialPlayScenarios($this, $calculator);
|
||||
}
|
||||
|
||||
public function testMethodisSupported(): void
|
||||
{
|
||||
$calculator = new FactorGraphTrueSkillCalculator();
|
||||
$this->assertEquals(TRUE, $calculator->isSupported(SkillCalculatorSupportedOptions::PARTIAL_PLAY));
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,13 @@ namespace DNW\Skills\Tests\TrueSkill;
|
||||
|
||||
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\CoversNothing;
|
||||
|
||||
#[CoversClass(TwoPlayerTrueSkillCalculator::class)]
|
||||
class TwoPlayerTrueSkillCalculatorTest extends TestCase
|
||||
{
|
||||
#[CoversNothing]
|
||||
public function testTwoPlayerTrueSkillCalculator(): void
|
||||
{
|
||||
$calculator = new TwoPlayerTrueSkillCalculator();
|
||||
|
@ -6,9 +6,13 @@ namespace DNW\Skills\Tests\TrueSkill;
|
||||
|
||||
use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\CoversNothing;
|
||||
|
||||
//#[CoversClass(TwoTeamTrueSkillCalculator::class)]
|
||||
class TwoTeamTrueSkillCalculatorTest extends TestCase
|
||||
{
|
||||
#[CoversNothing]
|
||||
public function testTwoTeamTrueSkillCalculator(): void
|
||||
{
|
||||
$calculator = new TwoTeamTrueSkillCalculator();
|
||||
|
Reference in New Issue
Block a user