mirror of
				https://github.com/furyfire/trueskill.git
				synced 2025-11-04 10:12:28 +01: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