2024-02-02 14:53:38 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
2024-01-16 15:07:14 +00:00
|
|
|
|
|
|
|
namespace DNW\Skills\Tests\TrueSkill;
|
|
|
|
|
|
|
|
use DNW\Skills\GameInfo;
|
|
|
|
use DNW\Skills\Player;
|
|
|
|
use DNW\Skills\Team;
|
|
|
|
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
|
2024-02-06 12:05:19 +00:00
|
|
|
use DNW\Skills\SkillCalculatorSupportedOptions;
|
2024-02-01 10:50:18 +00:00
|
|
|
use PHPUnit\Framework\TestCase;
|
2024-02-06 13:06:05 +00:00
|
|
|
use PHPUnit\Framework\Attributes\CoversClass;
|
2024-02-06 12:05:19 +00:00
|
|
|
use PHPUnit\Framework\Attributes\CoversNothing;
|
2024-02-06 13:06:05 +00:00
|
|
|
use PHPUnit\Framework\Attributes\UsesClass;
|
2024-01-16 15:07:14 +00:00
|
|
|
|
2024-02-06 13:06:05 +00:00
|
|
|
#[CoversClass(FactorGraphTrueSkillCalculator::class)]
|
2024-02-06 13:45:40 +00:00
|
|
|
#[UsesClass(\DNW\Skills\Numerics\Range::class)]
|
|
|
|
#[UsesClass(\DNW\Skills\PlayersRange::class)]
|
|
|
|
#[UsesClass(\DNW\Skills\SkillCalculator::class)]
|
|
|
|
#[UsesClass(\DNW\Skills\TeamsRange::class)]
|
2024-01-16 15:07:14 +00:00
|
|
|
class FactorGraphTrueSkillCalculatorTest extends TestCase
|
|
|
|
{
|
2024-02-06 12:05:19 +00:00
|
|
|
#[CoversNothing]
|
2024-01-16 15:07:14 +00:00
|
|
|
public function testMicrosoftResearchExample(): void
|
|
|
|
{
|
|
|
|
$gameInfo = new GameInfo();
|
|
|
|
|
2024-01-22 13:11:13 +00:00
|
|
|
$players = [
|
|
|
|
new Player("alice"),
|
|
|
|
new Player("bob"),
|
|
|
|
new Player("chris"),
|
|
|
|
new Player("darren"),
|
|
|
|
new Player("eve"),
|
|
|
|
new Player("fabien"),
|
|
|
|
new Player("george"),
|
|
|
|
new Player("hillary"),
|
|
|
|
];
|
|
|
|
|
2024-02-02 14:53:38 +00:00
|
|
|
$teams = [];
|
2024-01-16 15:07:14 +00:00
|
|
|
foreach ($players as $player) {
|
|
|
|
$teams[] = new Team($player, $gameInfo->getDefaultRating());
|
|
|
|
}
|
|
|
|
|
|
|
|
$calculator = new FactorGraphTrueSkillCalculator();
|
|
|
|
|
|
|
|
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1,2,3,4,5,6,7,8]);
|
|
|
|
|
2024-01-22 13:11:13 +00:00
|
|
|
$expected = [
|
|
|
|
'alice' => [36.771, 5.749],
|
|
|
|
'bob' => [32.242, 5.133],
|
|
|
|
'chris' => [29.074, 4.943],
|
|
|
|
'darren' => [26.322, 4.874],
|
|
|
|
'eve' => [23.678, 4.874],
|
|
|
|
'fabien' => [20.926, 4.943],
|
|
|
|
'george' => [17.758, 5.133],
|
|
|
|
'hillary' => [13.229, 5.749],
|
|
|
|
];
|
2024-01-16 15:07:14 +00:00
|
|
|
|
|
|
|
foreach ($players as $player) {
|
|
|
|
$rating = $newRatings->getRating($player);
|
|
|
|
$this->assertEqualsWithDelta($expected[$player->getId()][0], $rating->getMean(), 0.001);
|
|
|
|
$this->assertEqualsWithDelta($expected[$player->getId()][1], $rating->getStandardDeviation(), 0.001);
|
|
|
|
}
|
|
|
|
}
|
2024-02-06 12:05:19 +00:00
|
|
|
|
|
|
|
#[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));
|
|
|
|
}
|
2024-01-16 15:07:14 +00:00
|
|
|
}
|