diff --git a/composer.json b/composer.json index 9743f8c..fe4623e 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,8 @@ "phpunit/phpunit": "^10", "rector/rector": "^0.17", "phpstan/phpstan": "^1", - "laravel/pint": "^1" + "laravel/pint": "^1", + "squizlabs/php_codesniffer": "*" }, "autoload": { "psr-4": { @@ -20,5 +21,15 @@ "psr-4": { "DNW\\Skills\\Tests\\": "tests/" } + }, + "scripts": { + "test": "vendor/bin/phpunit tests --display-warnings", + "test-coverage": "vendor/bin/phpunit tests --testdox --coverage-filter src --coverage-html output/coverage --coverage-text --path-coverage --testdox-html output/test.html --log-junit output/test.xml ", + "analyze": [ + "@analyze-phpstan", + "@analyze-phpcs" + ], + "analyze-phpstan":"vendor/bin/phpstan analyze --level=8 --error-format=raw src/", + "analyze-phpcs": "vendor/bin/phpcs src --report=emacs --standard=PSR12" } } diff --git a/composer.lock b/composer.lock index d5d5f0c..3ef1a94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "f51a29d6ec21868ebc22ce4439494ab0", + "content-hash": "6092042789ea6465090b6dd55aa2d70b", "packages": [], "packages-dev": [ { @@ -1754,6 +1754,63 @@ ], "time": "2023-02-07T11:34:05+00:00" }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879", + "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2023-02-22T23:07:41+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.1", diff --git a/src/GameInfo.php b/src/GameInfo.php index 1726895..4d26989 100644 --- a/src/GameInfo.php +++ b/src/GameInfo.php @@ -7,18 +7,23 @@ namespace DNW\Skills; */ class GameInfo { - final const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6 + private const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6 - final const DEFAULT_DRAW_PROBABILITY = 0.10; + private const DEFAULT_DRAW_PROBABILITY = 0.10; - final const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300 + private const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300 - final const DEFAULT_INITIAL_MEAN = 25.0; + private const DEFAULT_INITIAL_MEAN = 25.0; - final const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333; + private const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333; - public function __construct(private $_initialMean = self::DEFAULT_INITIAL_MEAN, private $_initialStandardDeviation = self::DEFAULT_INITIAL_STANDARD_DEVIATION, private $_beta = self::DEFAULT_BETA, private $_dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR, private $_drawProbability = self::DEFAULT_DRAW_PROBABILITY) - { + public function __construct( + private $_initialMean = self::DEFAULT_INITIAL_MEAN, + private $_initialStandardDeviation = self::DEFAULT_INITIAL_STANDARD_DEVIATION, + private $_beta = self::DEFAULT_BETA, + private $_dynamicsFactor = self::DEFAULT_DYNAMICS_FACTOR, + private $_drawProbability = self::DEFAULT_DRAW_PROBABILITY + ) { } public function getInitialMean() diff --git a/src/Guard.php b/src/Guard.php index 0df3eac..0c4b915 100644 --- a/src/Guard.php +++ b/src/Guard.php @@ -14,21 +14,21 @@ class Guard public static function argumentNotNull(mixed $value, string $parameterName): void { if ($value == null) { - throw new Exception($parameterName.' can not be null'); + throw new Exception($parameterName . ' can not be null'); } } public static function argumentIsValidIndex(int $index, int $count, string $parameterName): void { if (($index < 0) || ($index >= $count)) { - throw new Exception($parameterName.' is an invalid index'); + throw new Exception($parameterName . ' is an invalid index'); } } public static function argumentInRangeInclusive(float $value, float $min, float $max, string $parameterName): void { if (($value < $min) || ($value > $max)) { - throw new Exception($parameterName.' is not in the valid range ['.$min.', '.$max.']'); + throw new Exception($parameterName . ' is not in the valid range [' . $min . ', ' . $max . ']'); } } } diff --git a/src/HashMap.php b/src/HashMap.php index b951eb9..71be566 100644 --- a/src/HashMap.php +++ b/src/HashMap.php @@ -7,42 +7,42 @@ namespace DNW\Skills; */ class HashMap { - private array $_hashToValue = []; + private array $hashToValue = []; - private array $_hashToKey = []; + private array $hashToKey = []; public function getValue(string|object $key): mixed { $hash = self::getHash($key); - return $this->_hashToValue[$hash]; + return $this->hashToValue[$hash]; } public function setValue(string|object $key, mixed $value): self { $hash = self::getHash($key); - $this->_hashToKey[$hash] = $key; - $this->_hashToValue[$hash] = $value; + $this->hashToKey[$hash] = $key; + $this->hashToValue[$hash] = $value; return $this; } public function getAllKeys(): array { - return array_values($this->_hashToKey); + return array_values($this->hashToKey); } public function getAllValues(): array { - return array_values($this->_hashToValue); + return array_values($this->hashToValue); } public function count(): int { - return count($this->_hashToKey); + return count($this->hashToKey); } - private static function getHash(string|Object $key): string + private static function getHash(string|object $key): string { if (is_object($key)) { return spl_object_hash($key); diff --git a/src/PairwiseComparison.php b/src/PairwiseComparison.php index e4a98f7..17053b9 100644 --- a/src/PairwiseComparison.php +++ b/src/PairwiseComparison.php @@ -5,7 +5,8 @@ namespace DNW\Skills; /** * Represents a comparison between two players. * - * @internal The actual values for the enum were chosen so that the also correspond to the multiplier for updates to means. + * @internal The actual values for the enum were chosen so + * that the also correspond to the multiplier for updates to means. */ enum PairwiseComparison: int { diff --git a/src/SkillCalculator.php b/src/SkillCalculator.php index c83b277..fe14511 100644 --- a/src/SkillCalculator.php +++ b/src/SkillCalculator.php @@ -9,21 +9,25 @@ use Exception; */ abstract class SkillCalculator { - protected function __construct(private $_supportedOptions, private readonly TeamsRange $_totalTeamsAllowed, private readonly PlayersRange $_playersPerTeamAllowed) - { + protected function __construct( + private $_supportedOptions, + private readonly TeamsRange $_totalTeamsAllowed, + private readonly PlayersRange $_playersPerTeamAllowed + ) { } /** * Calculates new ratings based on the prior ratings and team ranks. * - * @param GameInfo $gameInfo Parameters for the game. - * @param array $teamsOfPlayerToRatings A mapping of team players and their ratings. - * @param array $teamRanks The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2). + * @param GameInfo $gameInfo Parameters for the game. + * @param array $teamsOfPlayerToRatings A mapping of team players and their ratings. + * @param array $teamRanks The ranks of the teams where 1 is first place. For a tie, repeat the number (e.g. 1, 2, 2). * @return All the players and their new ratings. */ - abstract public function calculateNewRatings(GameInfo $gameInfo, - array $teamsOfPlayerToRatings, - array $teamRanks); + abstract public function calculateNewRatings( + GameInfo $gameInfo, + array $teamsOfPlayerToRatings, + array $teamRanks); /** * Calculates the match quality as the likelihood of all teams drawing. @@ -66,11 +70,3 @@ abstract class SkillCalculator } } -class SkillCalculatorSupportedOptions -{ - final const NONE = 0x00; - - final const PARTIAL_PLAY = 0x01; - - final const PARTIAL_UPDATE = 0x02; -} diff --git a/src/SkillCalculatorSupportedOptions.php b/src/SkillCalculatorSupportedOptions.php new file mode 100644 index 0000000..4869f67 --- /dev/null +++ b/src/SkillCalculatorSupportedOptions.php @@ -0,0 +1,12 @@ +getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key."'s performance"); + return $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance"); } public function createPriorSchedule(): ScheduleSequence @@ -52,8 +52,10 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer return $this->scheduleSequence( array_map( fn ($likelihood) => new ScheduleStep('Skill to Perf step', $likelihood, 0), - $localFactors), - 'All skill to performance sending'); + $localFactors + ), + 'All skill to performance sending' + ); } public function createPosteriorSchedule(): ScheduleSequence @@ -63,7 +65,9 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer return $this->scheduleSequence( array_map( fn ($likelihood) => new ScheduleStep('name', $likelihood, 1), - $localFactors), - 'All skill to performance sending'); + $localFactors + ), + 'All skill to performance sending' + ); } } diff --git a/src/TrueSkill/TwoTeamTrueSkillCalculator.php b/src/TrueSkill/TwoTeamTrueSkillCalculator.php index 600102e..83dab5b 100644 --- a/src/TrueSkill/TwoTeamTrueSkillCalculator.php +++ b/src/TrueSkill/TwoTeamTrueSkillCalculator.php @@ -41,17 +41,21 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator $results = new RatingContainer(); - self::updatePlayerRatings($gameInfo, + self::updatePlayerRatings( + $gameInfo, $results, $team1, $team2, - $wasDraw ? PairwiseComparison::DRAW : PairwiseComparison::WIN); + $wasDraw ? PairwiseComparison::DRAW : PairwiseComparison::WIN + ); - self::updatePlayerRatings($gameInfo, + self::updatePlayerRatings( + $gameInfo, $results, $team2, $team1, - $wasDraw ? PairwiseComparison::DRAW : PairwiseComparison::LOSE); + $wasDraw ? PairwiseComparison::DRAW : PairwiseComparison::LOSE + ); return $results; }