Compare commits

..

No commits in common. "99eb3271c22882cb0b1416a09190cdb93edcfa1c" and "c18ccd38e2a674f9f60ce3ae700a8acae43bd8e6" have entirely different histories.

13 changed files with 80 additions and 164 deletions

8
README

@ -6,10 +6,4 @@ 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 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
For details on how to use this project, see the accompanying unit tests with this project

72
composer.lock generated

@ -1590,16 +1590,16 @@
},
{
"name": "phpunit/phpunit",
"version": "10.5.10",
"version": "10.5.9",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c"
"reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/50b8e314b6d0dd06521dc31d1abffa73f25f850c",
"reference": "50b8e314b6d0dd06521dc31d1abffa73f25f850c",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
"reference": "0bd663704f0165c9e76fe4f06ffa6a1ca727fdbe",
"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.10"
"source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.9"
},
"funding": [
{
@ -1687,7 +1687,7 @@
"type": "tidelift"
}
],
"time": "2024-02-04T09:07:51+00:00"
"time": "2024-01-22T14:35:40+00:00"
},
{
"name": "psr/container",
@ -2928,16 +2928,16 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.29.0",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
"shasum": ""
},
"require": {
@ -2951,6 +2951,9 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -2987,7 +2990,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
},
"funding": [
{
@ -3003,20 +3006,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2023-01-26T09:26:14+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.29.0",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f"
"reference": "875e90aeea2777b6f135677f618529449334a612"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612",
"reference": "875e90aeea2777b6f135677f618529449334a612",
"shasum": ""
},
"require": {
@ -3027,6 +3030,9 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -3065,7 +3071,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0"
},
"funding": [
{
@ -3081,20 +3087,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2023-01-26T09:26:14+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.29.0",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92",
"shasum": ""
},
"require": {
@ -3105,6 +3111,9 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -3146,7 +3155,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0"
},
"funding": [
{
@ -3162,20 +3171,20 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2023-01-26T09:26:14+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.29.0",
"version": "v1.28.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
"reference": "42292d99c55abe617799667f454222c54c60e229"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
"reference": "42292d99c55abe617799667f454222c54c60e229",
"shasum": ""
},
"require": {
@ -3189,6 +3198,9 @@
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
@ -3226,7 +3238,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
},
"funding": [
{
@ -3242,7 +3254,7 @@
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2023-07-28T09:04:16+00:00"
},
{
"name": "symfony/service-contracts",

@ -7,8 +7,7 @@
"tests"
],
"report": {
"html": "output/metrics/",
"json": "output/metrics/report.json"
"html": "output/metrics/"
},
"plugins": {
"git": {

@ -18,7 +18,6 @@
<coverage>
<report>
<html outputDirectory="output/coverage" />
<clover outputFile ="output/coverage/clover.xml" />
</report>
</coverage>
</phpunit>

@ -8,6 +8,11 @@ class FactorGraph
{
private VariableFactory $variableFactory;
public function __construct(VariableFactory $factory)
{
$this->variableFactory = $factory;
}
public function getVariableFactory(): VariableFactory
{
return $this->variableFactory;

@ -1,22 +0,0 @@
<?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,18 +15,4 @@ 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,27 +7,12 @@ 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,
@ -125,7 +110,9 @@ class MatrixTest extends TestCase
1, 2, 3,
4, 5, 6);
$d = Matrix::fromColumnValues(2, 3, [[1, 4], [2, 5], [3,6]]);
$d = Matrix::fromRowsColumns(2, 3,
1, 2, 3,
4, 5, 6);
$this->assertTrue($c->equals($d));
@ -157,21 +144,6 @@ 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
@ -225,14 +197,6 @@ 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,19 +27,5 @@ 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());
}
}

@ -0,0 +1,28 @@
<?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,20 +8,10 @@ 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();
@ -63,21 +53,4 @@ 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,13 +6,9 @@ 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,13 +6,9 @@ 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();