mirror of
https://github.com/furyfire/trueskill.git
synced 2025-01-15 17:37:39 +00:00
This commit is contained in:
@ -34,10 +34,12 @@
|
|||||||
],
|
],
|
||||||
"static": [
|
"static": [
|
||||||
"@analyze-phpstan",
|
"@analyze-phpstan",
|
||||||
"@analyze-psalm"
|
"@analyze-psalm",
|
||||||
|
"@analyze-rector"
|
||||||
],
|
],
|
||||||
"analyze-phpstan":"vendor/bin/phpstan analyze --error-format=raw",
|
"analyze-phpstan":"vendor/bin/phpstan analyze --error-format=raw",
|
||||||
"analyze-psalm": "vendor/bin/psalm --no-cache",
|
"analyze-psalm": "vendor/bin/psalm --no-cache",
|
||||||
|
"analyze-rector": "vendor/bin/rector --dry-run",
|
||||||
"html": [
|
"html": [
|
||||||
"pandoc -s README.md -o output/README.html",
|
"pandoc -s README.md -o output/README.html",
|
||||||
"pandoc -s docs/index.rst -o output/index.html"
|
"pandoc -s docs/index.rst -o output/index.html"
|
||||||
|
@ -47,6 +47,6 @@ PHP Tools
|
|||||||
---------
|
---------
|
||||||
For development Composer and the following packages are used (Recommended as Phars installed via Phive)
|
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
|
* sudo phive install -g composer phpdocumentor infection phpcs phpcbf phploc phpbench overtrue/phplint --force-accept-unsigned
|
||||||
* composer install
|
* composer install
|
||||||
* composer all
|
* composer all
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once(__DIR__ . "/vendor/autoload.php");
|
require_once(__DIR__ . "/../vendor/autoload.php");
|
||||||
|
|
||||||
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
|
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
|
||||||
use DNW\Skills\GameInfo;
|
use DNW\Skills\GameInfo;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
require_once(__DIR__ . "/vendor/autoload.php");
|
require_once(__DIR__ . "/../vendor/autoload.php");
|
||||||
|
|
||||||
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;
|
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;
|
||||||
use DNW\Skills\GameInfo;
|
use DNW\Skills\GameInfo;
|
||||||
|
@ -10,7 +10,7 @@ abstract class FactorGraph
|
|||||||
|
|
||||||
protected function __construct()
|
protected function __construct()
|
||||||
{
|
{
|
||||||
$this->variableFactory = new VariableFactory(fn () => NULL);
|
$this->variableFactory = new VariableFactory(static fn(): null => NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getVariableFactory(): VariableFactory
|
public function getVariableFactory(): VariableFactory
|
||||||
|
@ -15,12 +15,12 @@ abstract class FactorGraphLayer
|
|||||||
private array $localFactors = [];
|
private array $localFactors = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int,array<int,object>>
|
* @var array<int,array<int,Variable>>
|
||||||
*/
|
*/
|
||||||
private array $outputVariablesGroups = [];
|
private array $outputVariablesGroups = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array<int,array<int,object>>
|
* @var array<int,array<int,Variable>>
|
||||||
*/
|
*/
|
||||||
private array $inputVariablesGroups = [];
|
private array $inputVariablesGroups = [];
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ abstract class FactorGraphLayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array<int,array<int,object>>
|
* @return array<int,array<int,Variable>>
|
||||||
*/
|
*/
|
||||||
protected function getInputVariablesGroups(): array
|
protected function getInputVariablesGroups(): array
|
||||||
{
|
{
|
||||||
@ -44,7 +44,7 @@ abstract class FactorGraphLayer
|
|||||||
/**
|
/**
|
||||||
* This reference is still needed
|
* This reference is still needed
|
||||||
*
|
*
|
||||||
* @return array<int,array<int,object>>
|
* @return array<int,array<int,Variable>>
|
||||||
*/
|
*/
|
||||||
public function &getOutputVariablesGroups(): array
|
public function &getOutputVariablesGroups(): array
|
||||||
{
|
{
|
||||||
@ -60,7 +60,7 @@ abstract class FactorGraphLayer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int,array<int,object>> $value
|
* @param array<int,array<int,Variable>> $value
|
||||||
*/
|
*/
|
||||||
public function setInputVariablesGroups(array $value): void
|
public function setInputVariablesGroups(array $value): void
|
||||||
{
|
{
|
||||||
|
@ -13,13 +13,6 @@ use Exception;
|
|||||||
*/
|
*/
|
||||||
class Guard
|
class Guard
|
||||||
{
|
{
|
||||||
public static function argumentNotNull(mixed $value, string $parameterName): void
|
|
||||||
{
|
|
||||||
if ($value == NULL) {
|
|
||||||
throw new Exception($parameterName . ' can not be null');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function argumentIsValidIndex(int $index, int $count, string $parameterName): void
|
public static function argumentIsValidIndex(int $index, int $count, string $parameterName): void
|
||||||
{
|
{
|
||||||
if (($index < 0) || ($index >= $count)) {
|
if (($index < 0) || ($index >= $count)) {
|
||||||
|
@ -39,7 +39,6 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
|
|||||||
array $teamRanks
|
array $teamRanks
|
||||||
): RatingContainer
|
): RatingContainer
|
||||||
{
|
{
|
||||||
Guard::argumentNotNull($gameInfo, 'gameInfo');
|
|
||||||
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
||||||
|
|
||||||
RankSorter::sort($teams, $teamRanks);
|
RankSorter::sort($teams, $teamRanks);
|
||||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace DNW\Skills\TrueSkill\Layers;
|
namespace DNW\Skills\TrueSkill\Layers;
|
||||||
|
|
||||||
use DNW\Skills\FactorGraphs\KeyedVariable;
|
use DNW\Skills\FactorGraphs\KeyedVariable;
|
||||||
|
use DNW\Skills\FactorGraphs\Variable;
|
||||||
use DNW\Skills\FactorGraphs\ScheduleStep;
|
use DNW\Skills\FactorGraphs\ScheduleStep;
|
||||||
use DNW\Skills\Numerics\BasicMath;
|
use DNW\Skills\Numerics\BasicMath;
|
||||||
use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
|
use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
|
||||||
@ -20,9 +21,12 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
|
|||||||
foreach ($inputVariablesGroups as $currentTeam) {
|
foreach ($inputVariablesGroups as $currentTeam) {
|
||||||
$currentTeamPlayerPerformances = [];
|
$currentTeamPlayerPerformances = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Variable $playerSkillVariable
|
||||||
|
*/
|
||||||
foreach ($currentTeam as $playerSkillVariable) {
|
foreach ($currentTeam as $playerSkillVariable) {
|
||||||
$localPlayerSkillVariable = $playerSkillVariable;
|
$localPlayerSkillVariable = $playerSkillVariable;
|
||||||
$currentPlayer = $localPlayerSkillVariable->getKey();
|
$currentPlayer = ($localPlayerSkillVariable instanceof KeyedVariable) ? $localPlayerSkillVariable->getKey() : "";
|
||||||
$playerPerformance = $this->createOutputVariable($currentPlayer);
|
$playerPerformance = $this->createOutputVariable($currentPlayer);
|
||||||
$newLikelihoodFactor = $this->createLikelihood($localPlayerSkillVariable, $playerPerformance);
|
$newLikelihoodFactor = $this->createLikelihood($localPlayerSkillVariable, $playerPerformance);
|
||||||
$this->addLayerFactor($newLikelihoodFactor);
|
$this->addLayerFactor($newLikelihoodFactor);
|
||||||
@ -33,7 +37,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createLikelihood(KeyedVariable $playerSkill, KeyedVariable $playerPerformance): GaussianLikelihoodFactor
|
private function createLikelihood(Variable $playerSkill, Variable $playerPerformance): GaussianLikelihoodFactor
|
||||||
{
|
{
|
||||||
return new GaussianLikelihoodFactor(
|
return new GaussianLikelihoodFactor(
|
||||||
BasicMath::square($this->getParentFactorGraph()->getGameInfo()->getBeta()),
|
BasicMath::square($this->getParentFactorGraph()->getGameInfo()->getBeta()),
|
||||||
|
@ -12,8 +12,10 @@ use DNW\Skills\GameInfo;
|
|||||||
use DNW\Skills\Numerics\GaussianDistribution;
|
use DNW\Skills\Numerics\GaussianDistribution;
|
||||||
use DNW\Skills\Rating;
|
use DNW\Skills\Rating;
|
||||||
use DNW\Skills\Team;
|
use DNW\Skills\Team;
|
||||||
|
use DNW\Skills\Player;
|
||||||
use DNW\Skills\RatingContainer;
|
use DNW\Skills\RatingContainer;
|
||||||
use DNW\Skills\FactorGraphs\FactorGraphLayer;
|
use DNW\Skills\FactorGraphs\FactorGraphLayer;
|
||||||
|
use DNW\Skills\FactorGraphs\KeyedVariable;
|
||||||
use DNW\Skills\TrueSkill\Layers\IteratedTeamDifferencesInnerLayer;
|
use DNW\Skills\TrueSkill\Layers\IteratedTeamDifferencesInnerLayer;
|
||||||
use DNW\Skills\TrueSkill\Layers\PlayerPerformancesToTeamPerformancesLayer;
|
use DNW\Skills\TrueSkill\Layers\PlayerPerformancesToTeamPerformancesLayer;
|
||||||
use DNW\Skills\TrueSkill\Layers\PlayerPriorValuesToSkillsLayer;
|
use DNW\Skills\TrueSkill\Layers\PlayerPriorValuesToSkillsLayer;
|
||||||
@ -132,7 +134,7 @@ class TrueSkillFactorGraph extends FactorGraph
|
|||||||
$priorLayerOutputVariablesGroups = $this->priorLayer->getOutputVariablesGroups();
|
$priorLayerOutputVariablesGroups = $this->priorLayer->getOutputVariablesGroups();
|
||||||
foreach ($priorLayerOutputVariablesGroups as $currentTeam) {
|
foreach ($priorLayerOutputVariablesGroups as $currentTeam) {
|
||||||
foreach ($currentTeam as $currentPlayer) {
|
foreach ($currentTeam as $currentPlayer) {
|
||||||
$localCurrentPlayer = $currentPlayer->getKey();
|
$localCurrentPlayer = ($currentPlayer instanceof KeyedVariable) ? $currentPlayer->getKey() : new Player("");
|
||||||
$newRating = new Rating(
|
$newRating = new Rating(
|
||||||
$currentPlayer->getValue()->getMean(),
|
$currentPlayer->getValue()->getMean(),
|
||||||
$currentPlayer->getValue()->getStandardDeviation()
|
$currentPlayer->getValue()->getStandardDeviation()
|
||||||
|
@ -40,7 +40,6 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
|
|||||||
): RatingContainer
|
): RatingContainer
|
||||||
{
|
{
|
||||||
// Basic argument checking
|
// Basic argument checking
|
||||||
Guard::argumentNotNull($gameInfo, 'gameInfo');
|
|
||||||
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
||||||
|
|
||||||
// Make sure things are in order
|
// Make sure things are in order
|
||||||
@ -143,7 +142,6 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
|
|||||||
*/
|
*/
|
||||||
public function calculateMatchQuality(GameInfo $gameInfo, array $teams): float
|
public function calculateMatchQuality(GameInfo $gameInfo, array $teams): float
|
||||||
{
|
{
|
||||||
Guard::argumentNotNull($gameInfo, 'gameInfo');
|
|
||||||
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
||||||
|
|
||||||
$team1 = $teams[0];
|
$team1 = $teams[0];
|
||||||
|
@ -34,7 +34,6 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
|
|||||||
*/
|
*/
|
||||||
public function calculateNewRatings(GameInfo $gameInfo, array $teams, array $teamRanks): RatingContainer
|
public function calculateNewRatings(GameInfo $gameInfo, array $teams, array $teamRanks): RatingContainer
|
||||||
{
|
{
|
||||||
Guard::argumentNotNull($gameInfo, 'gameInfo');
|
|
||||||
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
||||||
|
|
||||||
RankSorter::sort($teams, $teamRanks);
|
RankSorter::sort($teams, $teamRanks);
|
||||||
@ -150,7 +149,6 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
|
|||||||
*/
|
*/
|
||||||
public function calculateMatchQuality(GameInfo $gameInfo, array $teams): float
|
public function calculateMatchQuality(GameInfo $gameInfo, array $teams): float
|
||||||
{
|
{
|
||||||
Guard::argumentNotNull($gameInfo, 'gameInfo');
|
|
||||||
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
$this->validateTeamCountAndPlayersCountPerTeam($teams);
|
||||||
|
|
||||||
// We've verified that there's just two teams
|
// We've verified that there's just two teams
|
||||||
|
@ -10,13 +10,6 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
class GuardTest extends TestCase
|
class GuardTest extends TestCase
|
||||||
{
|
{
|
||||||
public function testArgumentNotNull(): void
|
|
||||||
{
|
|
||||||
$this->expectException(Exception::class);
|
|
||||||
$this->expectExceptionMessage('dummy can not be null');
|
|
||||||
Guard::argumentNotNull(NULL, "dummy");
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testargumentIsValidIndex(): void
|
public function testargumentIsValidIndex(): void
|
||||||
{
|
{
|
||||||
$this->expectException(Exception::class);
|
$this->expectException(Exception::class);
|
||||||
|
Reference in New Issue
Block a user