Pint applied for formatting

This commit is contained in:
Alex Wulf 2022-07-05 15:55:47 +02:00
parent bfc558d1f2
commit 7d4547df6a
68 changed files with 670 additions and 402 deletions

@ -3,7 +3,8 @@
"keywords": ["trueskill", "matchmaking", "ranking", "skill", "elo"], "keywords": ["trueskill", "matchmaking", "ranking", "skill", "elo"],
"version": "1.0.0", "version": "1.0.0",
"require": { "require": {
"php": "^8.1" "php": "^8.1",
"laravel/pint": "^0.2.3"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^9.0" "phpunit/phpunit": "^9.0"
@ -18,4 +19,4 @@
"DNW\\Skills\\Tests\\": "tests/" "DNW\\Skills\\Tests\\": "tests/"
} }
} }
} }

71
composer.lock generated

@ -4,8 +4,75 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "c016c54cac9a371fa358f63b592c310d", "content-hash": "27116ea101bf0dd938fe452b46b9c1b7",
"packages": [], "packages": [
{
"name": "laravel/pint",
"version": "v0.2.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "d0829631687c1238abdd660daac3d7218254b65c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/d0829631687c1238abdd660daac3d7218254b65c",
"reference": "d0829631687c1238abdd660daac3d7218254b65c",
"shasum": ""
},
"require": {
"ext-json": "*",
"ext-mbstring": "*",
"ext-tokenizer": "*",
"ext-xml": "*",
"php": "^8.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.8.0",
"illuminate/view": "^9.17.0",
"laravel-zero/framework": "^9.1.1",
"mockery/mockery": "^1.5.0",
"nunomaduro/larastan": "^2.1.11",
"nunomaduro/termwind": "^1.10.1",
"pestphp/pest": "^1.21.3"
},
"bin": [
"builds/pint"
],
"type": "project",
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Seeders\\": "database/seeders/",
"Database\\Factories\\": "database/factories/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nuno Maduro",
"email": "enunomaduro@gmail.com"
}
],
"description": "An opinionated code formatter for PHP.",
"homepage": "https://laravel.com",
"keywords": [
"format",
"formatter",
"lint",
"linter",
"php"
],
"support": {
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2022-07-04T16:04:06+00:00"
}
],
"packages-dev": [ "packages-dev": [
{ {
"name": "doctrine/instantiator", "name": "doctrine/instantiator",

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
use Exception; use Exception;
@ -7,7 +9,7 @@ class DefaultVariable extends Variable
{ {
public function __construct() public function __construct()
{ {
parent::__construct("Default", null); parent::__construct('Default', null);
} }
public function getValue() public function getValue()
@ -19,4 +21,4 @@ class DefaultVariable extends Variable
{ {
throw new Exception(); throw new Exception();
} }
} }

@ -1,20 +1,24 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
use Exception;
use DNW\Skills\Guard; use DNW\Skills\Guard;
use DNW\Skills\HashMap; use DNW\Skills\HashMap;
use Exception;
abstract class Factor abstract class Factor
{ {
private $_messages = array(); private $_messages = [];
private $_messageToVariableBinding; private $_messageToVariableBinding;
private $_name; private $_name;
private $_variables = array();
private $_variables = [];
protected function __construct($name) protected function __construct($name)
{ {
$this->_name = "Factor[" . $name . "]"; $this->_name = 'Factor['.$name.']';
$this->_messageToVariableBinding = new HashMap(); $this->_messageToVariableBinding = new HashMap();
} }
@ -46,14 +50,17 @@ abstract class Factor
/** /**
* Update the message and marginal of the i-th variable that the factor is connected to * Update the message and marginal of the i-th variable that the factor is connected to
*
* @param $messageIndex * @param $messageIndex
*
* @throws Exception * @throws Exception
*/ */
public function updateMessageIndex($messageIndex) public function updateMessageIndex($messageIndex)
{ {
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), "messageIndex"); Guard::argumentIsValidIndex($messageIndex, count($this->_messages), 'messageIndex');
$message = $this->_messages[$messageIndex]; $message = $this->_messages[$messageIndex];
$variable = $this->_messageToVariableBinding->getValue($message); $variable = $this->_messageToVariableBinding->getValue($message);
return $this->updateMessageVariable($message, $variable); return $this->updateMessageVariable($message, $variable);
} }
@ -75,28 +82,32 @@ abstract class Factor
/** /**
* Sends the ith message to the marginal and returns the log-normalization constant * Sends the ith message to the marginal and returns the log-normalization constant
*
* @param $messageIndex * @param $messageIndex
* @return * @return
*
* @throws Exception * @throws Exception
*/ */
public function sendMessageIndex($messageIndex) public function sendMessageIndex($messageIndex)
{ {
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), "messageIndex"); Guard::argumentIsValidIndex($messageIndex, count($this->_messages), 'messageIndex');
$message = $this->_messages[$messageIndex]; $message = $this->_messages[$messageIndex];
$variable = $this->_messageToVariableBinding->getValue($message); $variable = $this->_messageToVariableBinding->getValue($message);
return $this->sendMessageVariable($message, $variable); return $this->sendMessageVariable($message, $variable);
} }
protected abstract function sendMessageVariable(Message $message, Variable $variable); abstract protected function sendMessageVariable(Message $message, Variable $variable);
public abstract function createVariableToMessageBinding(Variable $variable); abstract public function createVariableToMessageBinding(Variable $variable);
protected function createVariableToMessageBindingWithMessage(Variable $variable, Message $message) protected function createVariableToMessageBindingWithMessage(Variable $variable, Message $message)
{ {
$this->_messageToVariableBinding->setValue($message, $variable); $this->_messageToVariableBinding->setValue($message, $variable);
$this->_messages[] = $message; $this->_messages[] = $message;
$this->_variables[] = $variable; $this->_variables[] = $variable;
return $message; return $message;
} }
@ -104,4 +115,4 @@ abstract class Factor
{ {
return $this->_name; return $this->_name;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class FactorGraph class FactorGraph
{ {
@ -13,4 +15,4 @@ class FactorGraph
{ {
$this->_variableFactory = $factory; $this->_variableFactory = $factory;
} }
} }

@ -1,10 +1,16 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
// edit this // edit this
abstract class FactorGraphLayer abstract class FactorGraphLayer
{ {
private $_localFactors = array(); private $_localFactors = [];
private $_outputVariablesGroups = array();
private $_inputVariablesGroups = array(); private $_outputVariablesGroups = [];
private $_inputVariablesGroups = [];
private $_parentFactorGraph; private $_parentFactorGraph;
protected function __construct(FactorGraph $parentGraph) protected function __construct(FactorGraph $parentGraph)
@ -54,7 +60,7 @@ abstract class FactorGraphLayer
$this->_localFactors[] = $factor; $this->_localFactors[] = $factor;
} }
public abstract function buildLayer(); abstract public function buildLayer();
public function createPriorSchedule() public function createPriorSchedule()
{ {
@ -65,4 +71,4 @@ abstract class FactorGraphLayer
{ {
return null; return null;
} }
} }

@ -1,11 +1,13 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
/** /**
* Helper class for computing the factor graph's normalization constant. * Helper class for computing the factor graph's normalization constant.
*/ */
class FactorList class FactorList
{ {
private $_list = array(); private $_list = [];
public function getLogNormalization() public function getLogNormalization()
{ {
@ -45,6 +47,7 @@ class FactorList
public function addFactor(Factor $factor) public function addFactor(Factor $factor)
{ {
$this->_list[] = $factor; $this->_list[] = $factor;
return $factor; return $factor;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class KeyedVariable extends Variable class KeyedVariable extends Variable
{ {
@ -14,4 +16,4 @@ class KeyedVariable extends Variable
{ {
return $this->_key; return $this->_key;
} }
} }

@ -1,8 +1,11 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class Message class Message
{ {
private $_name; private $_name;
private $_value; private $_value;
public function __construct($value = null, $name = null) public function __construct($value = null, $name = null)
@ -23,6 +26,6 @@ class Message
public function __toString() public function __toString()
{ {
return (string)$this->_name; return (string) $this->_name;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
abstract class Schedule abstract class Schedule
{ {
@ -9,10 +11,10 @@ abstract class Schedule
$this->_name = $name; $this->_name = $name;
} }
public abstract function visit($depth = -1, $maxDepth = 0); abstract public function visit($depth = -1, $maxDepth = 0);
public function __toString() public function __toString()
{ {
return $this->_name; return $this->_name;
} }
} }

@ -1,8 +1,11 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class ScheduleLoop extends Schedule class ScheduleLoop extends Schedule
{ {
private $_maxDelta; private $_maxDelta;
private $_scheduleToLoop; private $_scheduleToLoop;
public function __construct($name, Schedule $scheduleToLoop, $maxDelta) public function __construct($name, Schedule $scheduleToLoop, $maxDelta)
@ -23,4 +26,4 @@ class ScheduleLoop extends Schedule
return $delta; return $delta;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class ScheduleSequence extends Schedule class ScheduleSequence extends Schedule
{ {
@ -22,4 +24,4 @@ class ScheduleSequence extends Schedule
return $maxDelta; return $maxDelta;
} }
} }

@ -1,8 +1,11 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class ScheduleStep extends Schedule class ScheduleStep extends Schedule
{ {
private $_factor; private $_factor;
private $_index; private $_index;
public function __construct($name, Factor $factor, $index) public function __construct($name, Factor $factor, $index)
@ -16,6 +19,7 @@ class ScheduleStep extends Schedule
{ {
$currentFactor = $this->_factor; $currentFactor = $this->_factor;
$delta = $currentFactor->updateMessageIndex($this->_index); $delta = $currentFactor->updateMessageIndex($this->_index);
return $delta; return $delta;
} }
} }

@ -1,15 +1,18 @@
<?php <?php
namespace DNW\Skills\FactorGraphs; namespace DNW\Skills\FactorGraphs;
class Variable class Variable
{ {
private $_name; private $_name;
private $_prior; private $_prior;
private $_value; private $_value;
public function __construct($name, $prior) public function __construct($name, $prior)
{ {
$this->_name = "Variable[" . $name . "]"; $this->_name = 'Variable['.$name.']';
$this->_prior = $prior; $this->_prior = $prior;
$this->resetToPrior(); $this->resetToPrior();
} }
@ -33,4 +36,4 @@ class Variable
{ {
return $this->_name; return $this->_name;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs; <?php
namespace DNW\Skills\FactorGraphs;
class VariableFactory class VariableFactory
{ {
@ -14,6 +16,7 @@ class VariableFactory
{ {
$initializer = $this->_variablePriorInitializer; $initializer = $this->_variablePriorInitializer;
$newVar = new Variable($name, $initializer()); $newVar = new Variable($name, $initializer());
return $newVar; return $newVar;
} }
@ -21,6 +24,7 @@ class VariableFactory
{ {
$initializer = $this->_variablePriorInitializer; $initializer = $this->_variablePriorInitializer;
$newVar = new KeyedVariable($key, $name, $initializer()); $newVar = new KeyedVariable($key, $name, $initializer());
return $newVar; return $newVar;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Parameters about the game for calculating the TrueSkill. * Parameters about the game for calculating the TrueSkill.
@ -6,15 +8,23 @@
class GameInfo class GameInfo
{ {
const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6 const DEFAULT_BETA = 4.1666666666666666666666666666667; // Default initial mean / 6
const DEFAULT_DRAW_PROBABILITY = 0.10; const DEFAULT_DRAW_PROBABILITY = 0.10;
const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300 const DEFAULT_DYNAMICS_FACTOR = 0.083333333333333333333333333333333; // Default initial mean / 300
const DEFAULT_INITIAL_MEAN = 25.0; const DEFAULT_INITIAL_MEAN = 25.0;
const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333; // Default initial mean / 3 const DEFAULT_INITIAL_STANDARD_DEVIATION = 8.3333333333333333333333333333333; // Default initial mean / 3
private $_initialMean; private $_initialMean;
private $_initialStandardDeviation; private $_initialStandardDeviation;
private $_beta; private $_beta;
private $_dynamicsFactor; private $_dynamicsFactor;
private $_drawProbability; private $_drawProbability;
public function __construct($initialMean = self::DEFAULT_INITIAL_MEAN, public function __construct($initialMean = self::DEFAULT_INITIAL_MEAN,
@ -30,7 +40,6 @@ class GameInfo
$this->_drawProbability = $drawProbability; $this->_drawProbability = $drawProbability;
} }
public function getInitialMean() public function getInitialMean()
{ {
return $this->_initialMean; return $this->_initialMean;
@ -60,4 +69,4 @@ class GameInfo
{ {
return new Rating($this->_initialMean, $this->_initialStandardDeviation); return new Rating($this->_initialMean, $this->_initialStandardDeviation);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
use Exception; use Exception;
@ -12,21 +14,21 @@ class Guard
public static function argumentNotNull($value, $parameterName) public static function argumentNotNull($value, $parameterName)
{ {
if ($value == null) { if ($value == null) {
throw new Exception($parameterName . " can not be null"); throw new Exception($parameterName.' can not be null');
} }
} }
public static function argumentIsValidIndex($index, $count, $parameterName) public static function argumentIsValidIndex($index, $count, $parameterName)
{ {
if (($index < 0) || ($index >= $count)) { 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($value, $min, $max, $parameterName) public static function argumentInRangeInclusive($value, $min, $max, $parameterName)
{ {
if (($value < $min) || ($value > $max)) { 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.']');
} }
} }
} }

@ -1,17 +1,21 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Basic hashmap that supports object keys. * Basic hashmap that supports object keys.
*/ */
class HashMap class HashMap
{ {
private $_hashToValue = array(); private $_hashToValue = [];
private $_hashToKey = array();
private $_hashToKey = [];
public function getValue($key) public function getValue($key)
{ {
$hash = self::getHash($key); $hash = self::getHash($key);
$hashValue = $this->_hashToValue[$hash]; $hashValue = $this->_hashToValue[$hash];
return $hashValue; return $hashValue;
} }
@ -20,18 +24,21 @@ class HashMap
$hash = self::getHash($key); $hash = self::getHash($key);
$this->_hashToKey[$hash] = $key; $this->_hashToKey[$hash] = $key;
$this->_hashToValue[$hash] = $value; $this->_hashToValue[$hash] = $value;
return $this; return $this;
} }
public function getAllKeys() public function getAllKeys()
{ {
$keys = array_values($this->_hashToKey); $keys = array_values($this->_hashToKey);
return $keys; return $keys;
} }
public function getAllValues() public function getAllValues()
{ {
$values = array_values($this->_hashToValue); $values = array_values($this->_hashToValue);
return $values; return $values;
} }
@ -48,4 +55,4 @@ class HashMap
return $key; return $key;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Indicates support for allowing partial play (where a player only plays a part of the time). * Indicates support for allowing partial play (where a player only plays a part of the time).
@ -9,4 +11,4 @@ interface ISupportPartialPlay
* Indicates the percent of the time the player should be weighted where 0.0 indicates the player didn't play and 1.0 indicates the player played 100% of the time. * Indicates the percent of the time the player should be weighted where 0.0 indicates the player didn't play and 1.0 indicates the player played 100% of the time.
*/ */
public function getPartialPlayPercentage(); public function getPartialPlayPercentage();
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
interface ISupportPartialUpdate interface ISupportPartialUpdate
{ {
@ -6,4 +8,4 @@ interface ISupportPartialUpdate
* Indicated how much of a skill update a player should receive where 0.0 represents no update and 1.0 represents 100% of the update. * Indicated how much of a skill update a player should receive where 0.0 represents no update and 1.0 represents 100% of the update.
*/ */
public function getPartialUpdatePercentage(); public function getPartialUpdatePercentage();
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
/** /**
* Basic math functions. * Basic math functions.
@ -8,10 +10,10 @@
*/ */
class BasicMath class BasicMath
{ {
/** /**
* Squares the input (x^2 = x * x) * Squares the input (x^2 = x * x)
* @param number $x Value to square (x) *
* @param number $x Value to square (x)
* @return number The squared value (x^2) * @return number The squared value (x^2)
*/ */
public static function square($x) public static function square($x)
@ -21,13 +23,15 @@ class BasicMath
/** /**
* Sums the items in $itemsToSum * Sums the items in $itemsToSum
* @param array $itemsToSum The items to sum, *
* @param callback $callback The function to apply to each array element before summing. * @param array $itemsToSum The items to sum,
* @param callable $callback The function to apply to each array element before summing.
* @return number The sum. * @return number The sum.
*/ */
public static function sum(array $itemsToSum, $callback) public static function sum(array $itemsToSum, $callback)
{ {
$mappedItems = array_map($callback, $itemsToSum); $mappedItems = array_map($callback, $itemsToSum);
return array_sum($mappedItems); return array_sum($mappedItems);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
class DiagonalMatrix extends Matrix class DiagonalMatrix extends Matrix
{ {
@ -20,4 +22,4 @@ class DiagonalMatrix extends Matrix
} }
} }
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
/** /**
* Computes Gaussian (bell curve) values. * Computes Gaussian (bell curve) values.
@ -9,12 +11,15 @@
class GaussianDistribution class GaussianDistribution
{ {
private $_mean; private $_mean;
private $_standardDeviation; private $_standardDeviation;
// precision and precisionMean are used because they make multiplying and dividing simpler // precision and precisionMean are used because they make multiplying and dividing simpler
// (the the accompanying math paper for more details) // (the the accompanying math paper for more details)
private $_precision; private $_precision;
private $_precisionMean; private $_precisionMean;
private $_variance; private $_variance;
public function __construct($mean = 0.0, $standardDeviation = 1.0) public function __construct($mean = 0.0, $standardDeviation = 1.0)
@ -76,6 +81,7 @@ class GaussianDistribution
$result->_variance = $this->_variance; $result->_variance = $this->_variance;
$result->_precision = $this->_precision; $result->_precision = $this->_precision;
$result->_precisionMean = $this->_precisionMean; $result->_precisionMean = $this->_precisionMean;
return $result; return $result;
} }
@ -94,6 +100,7 @@ class GaussianDistribution
$result->_standardDeviation = \INF; $result->_standardDeviation = \INF;
$result->_mean = \NAN; $result->_mean = \NAN;
} }
return $result; return $result;
} }
@ -129,6 +136,7 @@ class GaussianDistribution
$meanDifference = $left->_mean - $right->_mean; $meanDifference = $left->_mean - $right->_mean;
$logSqrt2Pi = log(sqrt(2 * M_PI)); $logSqrt2Pi = log(sqrt(2 * M_PI));
return -$logSqrt2Pi - (log($varianceSum) / 2.0) - (BasicMath::square($meanDifference) / (2.0 * $varianceSum)); return -$logSqrt2Pi - (log($varianceSum) / 2.0) - (BasicMath::square($meanDifference) / (2.0 * $varianceSum));
} }
@ -165,6 +173,7 @@ class GaussianDistribution
$multiplier = 1.0 / ($standardDeviation * sqrt(2 * M_PI)); $multiplier = 1.0 / ($standardDeviation * sqrt(2 * M_PI));
$expPart = exp((-1.0 * BasicMath::square($x - $mean)) / (2 * BasicMath::square($standardDeviation))); $expPart = exp((-1.0 * BasicMath::square($x - $mean)) / (2 * BasicMath::square($standardDeviation)));
$result = $multiplier * $expPart; $result = $multiplier * $expPart;
return $result; return $result;
} }
@ -172,6 +181,7 @@ class GaussianDistribution
{ {
$invsqrt2 = -0.707106781186547524400844362104; $invsqrt2 = -0.707106781186547524400844362104;
$result = GaussianDistribution::errorFunctionCumulativeTo($invsqrt2 * $x); $result = GaussianDistribution::errorFunctionCumulativeTo($invsqrt2 * $x);
return 0.5 * $result; return 0.5 * $result;
} }
@ -183,7 +193,7 @@ class GaussianDistribution
$t = 2.0 / (2.0 + $z); $t = 2.0 / (2.0 + $z);
$ty = 4 * $t - 2; $ty = 4 * $t - 2;
$coefficients = array( $coefficients = [
-1.3026537197817094, -1.3026537197817094,
6.4196979235649026e-1, 6.4196979235649026e-1,
1.9476473204185836e-2, 1.9476473204185836e-2,
@ -211,7 +221,7 @@ class GaussianDistribution
-1.523e-15, -1.523e-15,
-9.4e-17, -9.4e-17,
1.21e-16, 1.21e-16,
-2.8e-17); -2.8e-17, ];
$ncof = count($coefficients); $ncof = count($coefficients);
$d = 0.0; $d = 0.0;
@ -224,6 +234,7 @@ class GaussianDistribution
} }
$ans = $t * exp(-$z * $z + 0.5 * ($coefficients[0] + $ty * $d) - $dd); $ans = $t * exp(-$z * $z + 0.5 * ($coefficients[0] + $ty * $d) - $dd);
return ($x >= 0.0) ? $ans : (2.0 - $ans); return ($x >= 0.0) ? $ans : (2.0 - $ans);
} }
@ -258,6 +269,6 @@ class GaussianDistribution
public function __toString() public function __toString()
{ {
return sprintf("mean=%.4f standardDeviation=%.4f", $this->_mean, $this->_standardDeviation); return sprintf('mean=%.4f standardDeviation=%.4f', $this->_mean, $this->_standardDeviation);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
class IdentityMatrix extends DiagonalMatrix class IdentityMatrix extends DiagonalMatrix
{ {
@ -6,4 +8,4 @@ class IdentityMatrix extends DiagonalMatrix
{ {
parent::__construct(array_fill(0, $rows, 1)); parent::__construct(array_fill(0, $rows, 1));
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
use Exception; use Exception;
@ -7,7 +9,9 @@ class Matrix
const ERROR_TOLERANCE = 0.0000000001; const ERROR_TOLERANCE = 0.0000000001;
private $_matrixRowData; private $_matrixRowData;
private $_rowCount; private $_rowCount;
private $_columnCount; private $_columnCount;
public function __construct($rows = 0, $columns = 0, $matrixData = null) public function __construct($rows = 0, $columns = 0, $matrixData = null)
@ -19,7 +23,7 @@ class Matrix
public static function fromColumnValues($rows, $columns, $columnValues) public static function fromColumnValues($rows, $columns, $columnValues)
{ {
$data = array(); $data = [];
$result = new Matrix($rows, $columns, $data); $result = new Matrix($rows, $columns, $data);
for ($currentColumn = 0; $currentColumn < $columns; $currentColumn++) { for ($currentColumn = 0; $currentColumn < $columns; $currentColumn++) {
@ -73,7 +77,7 @@ class Matrix
public function getTranspose() public function getTranspose()
{ {
// Just flip everything // Just flip everything
$transposeMatrix = array(); $transposeMatrix = [];
$rowMatrixData = $this->_matrixRowData; $rowMatrixData = $this->_matrixRowData;
for ($currentRowTransposeMatrix = 0; for ($currentRowTransposeMatrix = 0;
@ -98,8 +102,8 @@ class Matrix
public function getDeterminant() public function getDeterminant()
{ {
// Basic argument checking // Basic argument checking
if (!$this->isSquare()) { if (! $this->isSquare()) {
throw new Exception("Matrix must be square!"); throw new Exception('Matrix must be square!');
} }
if ($this->_rowCount == 1) { if ($this->_rowCount == 1) {
@ -117,6 +121,7 @@ class Matrix
$b = $this->_matrixRowData[0][1]; $b = $this->_matrixRowData[0][1];
$c = $this->_matrixRowData[1][0]; $c = $this->_matrixRowData[1][0];
$d = $this->_matrixRowData[1][1]; $d = $this->_matrixRowData[1][1];
return $a * $d - $b * $c; return $a * $d - $b * $c;
} }
@ -141,8 +146,8 @@ class Matrix
public function getAdjugate() public function getAdjugate()
{ {
if (!$this->isSquare()) { if (! $this->isSquare()) {
throw new Exception("Matrix must be square!"); throw new Exception('Matrix must be square!');
} }
// See http://en.wikipedia.org/wiki/Adjugate_matrix // See http://en.wikipedia.org/wiki/Adjugate_matrix
@ -165,7 +170,7 @@ class Matrix
} }
// The idea is that it's the transpose of the cofactors // The idea is that it's the transpose of the cofactors
$result = array(); $result = [];
for ($currentColumn = 0; $currentColumn < $this->_columnCount; $currentColumn++) { for ($currentColumn = 0; $currentColumn < $this->_columnCount; $currentColumn++) {
for ($currentRow = 0; $currentRow < $this->_rowCount; $currentRow++) { for ($currentRow = 0; $currentRow < $this->_rowCount; $currentRow++) {
@ -194,7 +199,7 @@ class Matrix
{ {
$rows = $matrix->getRowCount(); $rows = $matrix->getRowCount();
$columns = $matrix->getColumnCount(); $columns = $matrix->getColumnCount();
$newValues = array(); $newValues = [];
for ($currentRow = 0; $currentRow < $rows; $currentRow++) { for ($currentRow = 0; $currentRow < $rows; $currentRow++) {
for ($currentColumn = 0; $currentColumn < $columns; $currentColumn++) { for ($currentColumn = 0; $currentColumn < $columns; $currentColumn++) {
@ -212,12 +217,12 @@ class Matrix
|| ||
($left->getColumnCount() != $right->getColumnCount()) ($left->getColumnCount() != $right->getColumnCount())
) { ) {
throw new Exception("Matrices must be of the same size"); throw new Exception('Matrices must be of the same size');
} }
// simple addition of each item // simple addition of each item
$resultMatrix = array(); $resultMatrix = [];
for ($currentRow = 0; $currentRow < $left->getRowCount(); $currentRow++) { for ($currentRow = 0; $currentRow < $left->getRowCount(); $currentRow++) {
for ($currentColumn = 0; $currentColumn < $right->getColumnCount(); $currentColumn++) { for ($currentColumn = 0; $currentColumn < $right->getColumnCount(); $currentColumn++) {
@ -237,13 +242,13 @@ class Matrix
// See http://en.wikipedia.org/wiki/Matrix_multiplication for details // See http://en.wikipedia.org/wiki/Matrix_multiplication for details
if ($left->getColumnCount() != $right->getRowCount()) { if ($left->getColumnCount() != $right->getRowCount()) {
throw new Exception("The width of the left matrix must match the height of the right matrix"); throw new Exception('The width of the left matrix must match the height of the right matrix');
} }
$resultRows = $left->getRowCount(); $resultRows = $left->getRowCount();
$resultColumns = $right->getColumnCount(); $resultColumns = $right->getColumnCount();
$resultMatrix = array(); $resultMatrix = [];
for ($currentRow = 0; $currentRow < $resultRows; $currentRow++) { for ($currentRow = 0; $currentRow < $resultRows; $currentRow++) {
for ($currentColumn = 0; $currentColumn < $resultColumns; $currentColumn++) { for ($currentColumn = 0; $currentColumn < $resultColumns; $currentColumn++) {
@ -268,7 +273,7 @@ class Matrix
// See http://en.wikipedia.org/wiki/Minor_(linear_algebra) // See http://en.wikipedia.org/wiki/Minor_(linear_algebra)
// I'm going to use a horribly naïve algorithm... because I can :) // I'm going to use a horribly naïve algorithm... because I can :)
$result = array(); $result = [];
$actualRow = 0; $actualRow = 0;
@ -334,4 +339,4 @@ class Matrix
return true; return true;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
// The whole purpose of this class is to make the code for the SkillCalculator(s) // The whole purpose of this class is to make the code for the SkillCalculator(s)
// look a little cleaner // look a little cleaner
@ -8,13 +10,13 @@ use Exception;
class Range class Range
{ {
private $_min; private $_min;
private $_max; private $_max;
public function __construct($min, $max) public function __construct($min, $max)
{ {
if ($min > $max) if ($min > $max) {
{ throw new Exception('min > max');
throw new Exception("min > max");
} }
$this->_min = $min; $this->_min = $min;
@ -50,11 +52,11 @@ class Range
public static function atLeast($minimumValue) public static function atLeast($minimumValue)
{ {
return static::create($minimumValue, PHP_INT_MAX ); return static::create($minimumValue, PHP_INT_MAX);
} }
public function isInRange($value) public function isInRange($value)
{ {
return ($this->_min <= $value) && ($value <= $this->_max); return ($this->_min <= $value) && ($value <= $this->_max);
} }
} }

@ -1,14 +1,16 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
class SquareMatrix extends Matrix class SquareMatrix extends Matrix
{ {
public function __construct() public function __construct()
{ {
$allValues = func_get_args(); $allValues = func_get_args();
$rows = (int)sqrt(count($allValues)); $rows = (int) sqrt(count($allValues));
$cols = $rows; $cols = $rows;
$matrixData = array(); $matrixData = [];
$allValuesIndex = 0; $allValuesIndex = 0;
for ($currentRow = 0; $currentRow < $rows; $currentRow++) { for ($currentRow = 0; $currentRow < $rows; $currentRow++) {
@ -19,4 +21,4 @@ class SquareMatrix extends Matrix
parent::__construct($rows, $cols, $matrixData); parent::__construct($rows, $cols, $matrixData);
} }
} }

@ -1,13 +1,15 @@
<?php namespace DNW\Skills\Numerics; <?php
namespace DNW\Skills\Numerics;
class Vector extends Matrix class Vector extends Matrix
{ {
public function __construct(array $vectorValues) public function __construct(array $vectorValues)
{ {
$columnValues = array(); $columnValues = [];
foreach ($vectorValues as $currentVectorValue) { foreach ($vectorValues as $currentVectorValue) {
$columnValues[] = array($currentVectorValue); $columnValues[] = [$currentVectorValue];
} }
parent::__construct(count($vectorValues), 1, $columnValues); parent::__construct(count($vectorValues), 1, $columnValues);
} }
} }

@ -1,24 +1,29 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Represents a comparison between two players. * 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.
*/ */
class PairwiseComparison class PairwiseComparison
{ {
const WIN = 1; const WIN = 1;
const DRAW = 0; const DRAW = 0;
const LOSE = -1; const LOSE = -1;
public static function getRankFromComparison($comparison) public static function getRankFromComparison($comparison)
{ {
switch ($comparison) { switch ($comparison) {
case PairwiseComparison::WIN: case PairwiseComparison::WIN:
return array(1, 2); return [1, 2];
case PairwiseComparison::LOSE: case PairwiseComparison::LOSE:
return array(2, 1); return [2, 1];
default: default:
return array(1, 1); return [1, 1];
} }
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
class PartialPlay class PartialPlay
{ {
@ -6,7 +8,7 @@ class PartialPlay
{ {
// If the player doesn't support the interface, assume 1.0 == 100% // If the player doesn't support the interface, assume 1.0 == 100%
$supportsPartialPlay = $player instanceof ISupportPartialPlay; $supportsPartialPlay = $player instanceof ISupportPartialPlay;
if (!$supportsPartialPlay) { if (! $supportsPartialPlay) {
return 1.0; return 1.0;
} }
@ -20,4 +22,4 @@ class PartialPlay
return $partialPlayPercentage; return $partialPlayPercentage;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Represents a player who has a Rating. * Represents a player who has a Rating.
@ -6,26 +8,29 @@
class Player implements ISupportPartialPlay, ISupportPartialUpdate class Player implements ISupportPartialPlay, ISupportPartialUpdate
{ {
const DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time const DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time
const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0; // = receive 100% update const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0; // = receive 100% update
private $_Id; private $_Id;
private $_PartialPlayPercentage; private $_PartialPlayPercentage;
private $_PartialUpdatePercentage; private $_PartialUpdatePercentage;
/** /**
* Constructs a player. * Constructs a player.
* *
* @param mixed $id The identifier for the player, such as a name. * @param mixed $id The identifier for the player, such as a name.
* @param number $partialPlayPercentage The weight percentage to give this player when calculating a new rank. * @param number $partialPlayPercentage The weight percentage to give this player when calculating a new rank.
* @param number $partialUpdatePercentage Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update. * @param number $partialUpdatePercentage Indicated how much of a skill update a player should receive where 0 represents no update and 1.0 represents 100% of the update.
*/ */
public function __construct($id, public function __construct($id,
$partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE, $partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
$partialUpdatePercentage = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE) $partialUpdatePercentage = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE)
{ {
// If they don't want to give a player an id, that's ok... // If they don't want to give a player an id, that's ok...
Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, "partialPlayPercentage"); Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, 'partialPlayPercentage');
Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, "partialUpdatePercentage"); Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, 'partialUpdatePercentage');
$this->_Id = $id; $this->_Id = $id;
$this->_PartialPlayPercentage = $partialPlayPercentage; $this->_PartialPlayPercentage = $partialPlayPercentage;
$this->_PartialUpdatePercentage = $partialUpdatePercentage; $this->_PartialUpdatePercentage = $partialUpdatePercentage;
@ -57,6 +62,6 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
public function __toString() public function __toString()
{ {
return (string)$this->_Id; return (string) $this->_Id;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
use DNW\Skills\Numerics\Range; use DNW\Skills\Numerics\Range;
@ -13,4 +15,4 @@ class PlayersRange extends Range
{ {
return new PlayersRange($min, $max); return new PlayersRange($min, $max);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
/** /**
* Helper class to sort ranks in non-decreasing order. * Helper class to sort ranks in non-decreasing order.
@ -8,13 +10,14 @@ class RankSorter
/** /**
* Performs an in-place sort of the items in according to the ranks in non-decreasing order. * Performs an in-place sort of the items in according to the ranks in non-decreasing order.
* *
* @param array $teams The items to sort according to the order specified by ranks. * @param array $teams The items to sort according to the order specified by ranks.
* @param array $teamRanks The ranks for each item where 1 is first place. * @param array $teamRanks The ranks for each item where 1 is first place.
* @return array * @return array
*/ */
public static function sort(array &$teams, array &$teamRanks) public static function sort(array &$teams, array &$teamRanks)
{ {
array_multisort($teamRanks, $teams); array_multisort($teamRanks, $teams);
return $teams; return $teams;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
// Container for a player's rating. // Container for a player's rating.
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
@ -8,14 +10,17 @@ class Rating
const CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3; const CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3;
private $_conservativeStandardDeviationMultiplier; private $_conservativeStandardDeviationMultiplier;
private $_mean; private $_mean;
private $_standardDeviation; private $_standardDeviation;
/** /**
* Constructs a rating. * Constructs a rating.
* @param double $mean The statistical mean value of the rating (also known as mu). *
* @param double $standardDeviation The standard deviation of the rating (also known as s). * @param float $mean The statistical mean value of the rating (also known as mu).
* @param float|int $conservativeStandardDeviationMultiplier optional The number of standardDeviations to subtract from the mean to achieve a conservative rating. * @param float $standardDeviation The standard deviation of the rating (also known as s).
* @param float|int $conservativeStandardDeviationMultiplier optional The number of standardDeviations to subtract from the mean to achieve a conservative rating.
*/ */
public function __construct($mean, $standardDeviation, $conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER) public function __construct($mean, $standardDeviation, $conservativeStandardDeviationMultiplier = self::CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER)
{ {
@ -51,7 +56,7 @@ class Rating
public function getPartialUpdate(Rating $prior, Rating $fullPosterior, $updatePercentage) public function getPartialUpdate(Rating $prior, Rating $fullPosterior, $updatePercentage)
{ {
$priorGaussian = new GaussianDistribution($prior->getMean(), $prior->getStandardDeviation()); $priorGaussian = new GaussianDistribution($prior->getMean(), $prior->getStandardDeviation());
$posteriorGaussian = new GaussianDistribution($fullPosterior->getMean(), $fullPosterior . getStandardDeviation()); $posteriorGaussian = new GaussianDistribution($fullPosterior->getMean(), $fullPosterior.getStandardDeviation());
// From a clarification email from Ralf Herbrich: // From a clarification email from Ralf Herbrich:
// "the idea is to compute a linear interpolation between the prior and posterior skills of each player // "the idea is to compute a linear interpolation between the prior and posterior skills of each player
@ -60,7 +65,7 @@ class Rating
$precisionDifference = $posteriorGaussian->getPrecision() - $priorGaussian->getPrecision(); $precisionDifference = $posteriorGaussian->getPrecision() - $priorGaussian->getPrecision();
$partialPrecisionDifference = $updatePercentage * $precisionDifference; $partialPrecisionDifference = $updatePercentage * $precisionDifference;
$precisionMeanDifference = $posteriorGaussian->getPrecisionMean() - $priorGaussian . getPrecisionMean(); $precisionMeanDifference = $posteriorGaussian->getPrecisionMean() - $priorGaussian.getPrecisionMean();
$partialPrecisionMeanDifference = $updatePercentage * $precisionMeanDifference; $partialPrecisionMeanDifference = $updatePercentage * $precisionMeanDifference;
$partialPosteriorGaussion = GaussianDistribution::fromPrecisionMean( $partialPosteriorGaussion = GaussianDistribution::fromPrecisionMean(
@ -73,6 +78,6 @@ class Rating
public function __toString() public function __toString()
{ {
return sprintf("mean=%.4f, standardDeviation=%.4f", $this->_mean, $this->_standardDeviation); return sprintf('mean=%.4f, standardDeviation=%.4f', $this->_mean, $this->_standardDeviation);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
class RatingContainer class RatingContainer
{ {

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
use Exception; use Exception;
@ -8,7 +10,9 @@ use Exception;
abstract class SkillCalculator abstract class SkillCalculator
{ {
private $_supportedOptions; private $_supportedOptions;
private $_playersPerTeamAllowed; private $_playersPerTeamAllowed;
private $_totalTeamsAllowed; private $_totalTeamsAllowed;
protected function __construct($supportedOptions, TeamsRange $totalTeamsAllowed, PlayersRange $playerPerTeamAllowed) protected function __construct($supportedOptions, TeamsRange $totalTeamsAllowed, PlayersRange $playerPerTeamAllowed)
@ -20,24 +24,24 @@ abstract class SkillCalculator
/** /**
* Calculates new ratings based on the prior ratings and team ranks. * 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. * @return All the players and their new ratings.
*/ */
public abstract function calculateNewRatings(GameInfo $gameInfo, abstract public function calculateNewRatings(GameInfo $gameInfo,
array $teamsOfPlayerToRatings, array $teamsOfPlayerToRatings,
array $teamRanks); array $teamRanks);
/** /**
* Calculates the match quality as the likelihood of all teams drawing. * Calculates the match quality as the likelihood of all teams drawing.
* *
* @param GameInfo $gameInfo Parameters for the game. * @param GameInfo $gameInfo Parameters for the game.
* @param array $teamsOfPlayerToRatings A mapping of team players and their ratings. * @param array $teamsOfPlayerToRatings A mapping of team players and their ratings.
* @return The quality of the match between the teams as a percentage (0% = bad, 100% = well matched). * @return The quality of the match between the teams as a percentage (0% = bad, 100% = well matched).
*/ */
public abstract function calculateMatchQuality(GameInfo $gameInfo, array $teamsOfPlayerToRatings); abstract public function calculateMatchQuality(GameInfo $gameInfo, array $teamsOfPlayerToRatings);
public function isSupported($option) public function isSupported($option)
{ {
@ -49,21 +53,19 @@ abstract class SkillCalculator
self::validateTeamCountAndPlayersCountPerTeamWithRanges($teamsOfPlayerToRatings, $this->_totalTeamsAllowed, $this->_playersPerTeamAllowed); self::validateTeamCountAndPlayersCountPerTeamWithRanges($teamsOfPlayerToRatings, $this->_totalTeamsAllowed, $this->_playersPerTeamAllowed);
} }
private static function validateTeamCountAndPlayersCountPerTeamWithRanges(array $teams, private static function validateTeamCountAndPlayersCountPerTeamWithRanges(array $teams, TeamsRange $totalTeams, PlayersRange $playersPerTeam)
TeamsRange $totalTeams,
PlayersRange $playersPerTeam)
{ {
$countOfTeams = 0; $countOfTeams = 0;
foreach ($teams as $currentTeam) { foreach ($teams as $currentTeam) {
if (!$playersPerTeam->isInRange(count($currentTeam))) { if (! $playersPerTeam->isInRange(count($currentTeam))) {
throw new Exception("Player count is not in range"); throw new Exception('Player count is not in range');
} }
$countOfTeams++; $countOfTeams++;
} }
if (!$totalTeams->isInRange($countOfTeams)) { if (! $totalTeams->isInRange($countOfTeams)) {
throw new Exception("Team range is not in range"); throw new Exception('Team range is not in range');
} }
} }
} }
@ -71,6 +73,8 @@ abstract class SkillCalculator
class SkillCalculatorSupportedOptions class SkillCalculatorSupportedOptions
{ {
const NONE = 0x00; const NONE = 0x00;
const PARTIAL_PLAY = 0x01; const PARTIAL_PLAY = 0x01;
const PARTIAL_UPDATE = 0x02; const PARTIAL_UPDATE = 0x02;
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
class Team extends RatingContainer class Team extends RatingContainer
{ {
@ -6,8 +8,7 @@ class Team extends RatingContainer
{ {
parent::__construct(); parent::__construct();
if(!is_null($player)) if (! is_null($player)) {
{
$this->addPlayer($player, $rating); $this->addPlayer($player, $rating);
} }
} }
@ -15,6 +16,7 @@ class Team extends RatingContainer
public function addPlayer(Player $player, Rating $rating) public function addPlayer(Player $player, Rating $rating)
{ {
$this->setRating($player, $rating); $this->setRating($player, $rating);
return $this; return $this;
} }
} }

@ -1,11 +1,13 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
class Teams class Teams
{ {
public static function concat(/*variable arguments*/) public static function concat(/*variable arguments*/)
{ {
$args = func_get_args(); $args = func_get_args();
$result = array(); $result = [];
foreach ($args as $currentTeam) { foreach ($args as $currentTeam) {
$localCurrentTeam = $currentTeam; $localCurrentTeam = $currentTeam;
@ -14,4 +16,4 @@ class Teams
return $result; return $result;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills; <?php
namespace DNW\Skills;
use DNW\Skills\Numerics\Range; use DNW\Skills\Numerics\Range;
@ -13,4 +15,4 @@ class TeamsRange extends Range
{ {
return new TeamsRange($min, $max); return new TeamsRange($min, $max);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
@ -16,4 +18,4 @@ final class DrawMargin
// n1 and n2 are the number of players on each team // n1 and n2 are the number of players on each team
return GaussianDistribution::inverseCumulativeTo(.5 * ($drawProbability + 1), 0, 1) * sqrt(1 + 1) * $beta; return GaussianDistribution::inverseCumulativeTo(.5 * ($drawProbability + 1), 0, 1) * sqrt(1 + 1) * $beta;
} }
} }

@ -1,9 +1,9 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo; use DNW\Skills\GameInfo;
use DNW\Skills\Guard; use DNW\Skills\Guard;
use DNW\Skills\ISupportPartialPlay;
use DNW\Skills\ISupportPartialUpdate;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Numerics\DiagonalMatrix; use DNW\Skills\Numerics\DiagonalMatrix;
use DNW\Skills\Numerics\Matrix; use DNW\Skills\Numerics\Matrix;
@ -29,7 +29,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
array $teams, array $teams,
array $teamRanks) array $teamRanks)
{ {
Guard::argumentNotNull($gameInfo, "gameInfo"); Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams); $this->validateTeamCountAndPlayersCountPerTeam($teams);
RankSorter::sort($teams, $teamRanks); RankSorter::sort($teams, $teamRanks);
@ -109,7 +109,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// Helper function that gets a list of values for all player ratings // Helper function that gets a list of values for all player ratings
private static function getPlayerRatingValues(array $teamAssignmentsList, $playerRatingFunction) private static function getPlayerRatingValues(array $teamAssignmentsList, $playerRatingFunction)
{ {
$playerRatingValues = array(); $playerRatingValues = [];
foreach ($teamAssignmentsList as $currentTeam) { foreach ($teamAssignmentsList as $currentTeam) {
foreach ($currentTeam->getAllRatings() as $currentRating) { foreach ($currentTeam->getAllRatings() as $currentRating) {
@ -138,7 +138,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// | -0.75 0.75 | // | -0.75 0.75 |
// | 0.00 -1.00 | // | 0.00 -1.00 |
$playerAssignments = array(); $playerAssignments = [];
$totalPreviousPlayers = 0; $totalPreviousPlayers = 0;
$teamAssignmentsListCount = count($teamAssignmentsList); $teamAssignmentsListCount = count($teamAssignmentsList);
@ -150,7 +150,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// Need to add in 0's for all the previous players, since they're not // Need to add in 0's for all the previous players, since they're not
// on this team // on this team
$playerAssignments[$currentColumn] = ($totalPreviousPlayers > 0) ? \array_fill(0, $totalPreviousPlayers, 0) : array(); $playerAssignments[$currentColumn] = ($totalPreviousPlayers > 0) ? \array_fill(0, $totalPreviousPlayers, 0) : [];
foreach ($currentTeam->getAllPlayers() as $currentPlayer) { foreach ($currentTeam->getAllPlayers() as $currentPlayer) {
$playerAssignments[$currentColumn][] = PartialPlay::getPartialPlayPercentage($currentPlayer); $playerAssignments[$currentColumn][] = PartialPlay::getPartialPlayPercentage($currentPlayer);
@ -179,4 +179,4 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
return $playerTeamAssignmentsMatrix; return $playerTeamAssignmentsMatrix;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Factor; use DNW\Skills\FactorGraphs\Factor;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
@ -14,8 +16,9 @@ abstract class GaussianFactor extends Factor
/** /**
* Sends the factor-graph message with and returns the log-normalization constant. * Sends the factor-graph message with and returns the log-normalization constant.
* @param Message $message *
* @param Variable $variable * @param Message $message
* @param Variable $variable
* @return float|int * @return float|int
*/ */
protected function sendMessageVariable(Message $message, Variable $variable) protected function sendMessageVariable(Message $message, Variable $variable)
@ -24,6 +27,7 @@ abstract class GaussianFactor extends Factor
$messageValue = $message->getValue(); $messageValue = $message->getValue();
$logZ = GaussianDistribution::logProductNormalization($marginal, $messageValue); $logZ = GaussianDistribution::logProductNormalization($marginal, $messageValue);
$variable->setValue(GaussianDistribution::multiply($marginal, $messageValue)); $variable->setValue(GaussianDistribution::multiply($marginal, $messageValue));
return $logZ; return $logZ;
} }
@ -33,7 +37,8 @@ abstract class GaussianFactor extends Factor
$binding = parent::createVariableToMessageBindingWithMessage($variable, $binding = parent::createVariableToMessageBindingWithMessage($variable,
new Message( new Message(
$newDistribution, $newDistribution,
sprintf("message from %s to %s", $this, $variable))); sprintf('message from %s to %s', $this, $variable)));
return $binding; return $binding;
} }
} }

@ -1,9 +1,11 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
/** /**
* Factor representing a team difference that has exceeded the draw margin. * Factor representing a team difference that has exceeded the draw margin.
@ -16,7 +18,7 @@ class GaussianGreaterThanFactor extends GaussianFactor
public function __construct($epsilon, Variable $variable) public function __construct($epsilon, Variable $variable)
{ {
parent::__construct(\sprintf("%s > %.2f", $variable, $epsilon)); parent::__construct(\sprintf('%s > %.2f', $variable, $epsilon));
$this->_epsilon = $epsilon; $this->_epsilon = $epsilon;
$this->createVariableToMessageBinding($variable); $this->createVariableToMessageBinding($variable);
} }
@ -31,6 +33,7 @@ class GaussianGreaterThanFactor extends GaussianFactor
$messages = $this->getMessages(); $messages = $this->getMessages();
$message = $messages[0]->getValue(); $message = $messages[0]->getValue();
$messageFromVariable = GaussianDistribution::divide($marginal, $message); $messageFromVariable = GaussianDistribution::divide($marginal, $message);
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message) return -GaussianDistribution::logProductNormalization($messageFromVariable, $message)
+ +
log( log(
@ -39,7 +42,6 @@ class GaussianGreaterThanFactor extends GaussianFactor
$messageFromVariable->getStandardDeviation() $messageFromVariable->getStandardDeviation()
) )
); );
} }
protected function updateMessageVariable(Message $message, Variable $variable) protected function updateMessageVariable(Message $message, Variable $variable)
@ -82,4 +84,4 @@ class GaussianGreaterThanFactor extends GaussianFactor
// Return the difference in the new marginal // Return the difference in the new marginal
return GaussianDistribution::subtract($newMarginal, $oldMarginal); return GaussianDistribution::subtract($newMarginal, $oldMarginal);
} }
} }

@ -1,10 +1,12 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use Exception;
use DNW\Skills\FactorGraphs\KeyedVariable; use DNW\Skills\FactorGraphs\KeyedVariable;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
use Exception;
/** /**
* Connects two variables and adds uncertainty. * Connects two variables and adds uncertainty.
@ -17,7 +19,7 @@ class GaussianLikelihoodFactor extends GaussianFactor
public function __construct($betaSquared, Variable $variable1, Variable $variable2) public function __construct($betaSquared, Variable $variable1, Variable $variable2)
{ {
parent::__construct(sprintf("Likelihood of %s going to %s", $variable2, $variable1)); parent::__construct(sprintf('Likelihood of %s going to %s', $variable2, $variable1));
$this->_precision = 1.0 / $betaSquared; $this->_precision = 1.0 / $betaSquared;
$this->createVariableToMessageBinding($variable1); $this->createVariableToMessageBinding($variable1);
$this->createVariableToMessageBinding($variable2); $this->createVariableToMessageBinding($variable2);
@ -80,4 +82,4 @@ class GaussianLikelihoodFactor extends GaussianFactor
throw new Exception(); throw new Exception();
} }
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
@ -15,10 +17,10 @@ class GaussianPriorFactor extends GaussianFactor
public function __construct($mean, $variance, Variable $variable) public function __construct($mean, $variance, Variable $variable)
{ {
parent::__construct(sprintf("Prior value going to %s", $variable)); parent::__construct(sprintf('Prior value going to %s', $variable));
$this->_newMessage = new GaussianDistribution($mean, sqrt($variance)); $this->_newMessage = new GaussianDistribution($mean, sqrt($variance));
$newMessage = new Message(GaussianDistribution::fromPrecisionMean(0, 0), $newMessage = new Message(GaussianDistribution::fromPrecisionMean(0, 0),
sprintf("message from %s to %s", $this, $variable)); sprintf('message from %s to %s', $this, $variable));
$this->createVariableToMessageBindingWithMessage($variable, $newMessage); $this->createVariableToMessageBindingWithMessage($variable, $newMessage);
} }
@ -34,6 +36,7 @@ class GaussianPriorFactor extends GaussianFactor
$variable->setValue($newMarginal); $variable->setValue($newMarginal);
$message->setValue($this->_newMessage); $message->setValue($this->_newMessage);
return GaussianDistribution::subtract($oldMarginal, $newMarginal); return GaussianDistribution::subtract($oldMarginal, $newMarginal);
} }
} }

@ -1,8 +1,10 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\Guard;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\Guard;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
@ -13,18 +15,19 @@ use DNW\Skills\Numerics\GaussianDistribution;
*/ */
class GaussianWeightedSumFactor extends GaussianFactor class GaussianWeightedSumFactor extends GaussianFactor
{ {
private $_variableIndexOrdersForWeights = array(); private $_variableIndexOrdersForWeights = [];
// This following is used for convenience, for example, the first entry is [0, 1, 2] // This following is used for convenience, for example, the first entry is [0, 1, 2]
// corresponding to v[0] = a1*v[1] + a2*v[2] // corresponding to v[0] = a1*v[1] + a2*v[2]
private $_weights; private $_weights;
private $_weightsSquared; private $_weightsSquared;
public function __construct(Variable $sumVariable, array $variablesToSum, array $variableWeights = null) public function __construct(Variable $sumVariable, array $variablesToSum, array $variableWeights = null)
{ {
parent::__construct(self::createName($sumVariable, $variablesToSum, $variableWeights)); parent::__construct(self::createName($sumVariable, $variablesToSum, $variableWeights));
$this->_weights = array(); $this->_weights = [];
$this->_weightsSquared = array(); $this->_weightsSquared = [];
// The first weights are a straightforward copy // The first weights are a straightforward copy
// v_0 = a_1*v_1 + a_2*v_2 + ... + a_n * v_n // v_0 = a_1*v_1 + a_2*v_2 + ... + a_n * v_n
@ -40,7 +43,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
$variablesToSumLength = count($variablesToSum); $variablesToSumLength = count($variablesToSum);
// 0..n-1 // 0..n-1
$this->_variableIndexOrdersForWeights[0] = array(); $this->_variableIndexOrdersForWeights[0] = [];
for ($i = 0; $i < ($variablesToSumLength + 1); $i++) { for ($i = 0; $i < ($variablesToSumLength + 1); $i++) {
$this->_variableIndexOrdersForWeights[0][] = $i; $this->_variableIndexOrdersForWeights[0][] = $i;
} }
@ -178,6 +181,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
// Return the difference in the new marginal // Return the difference in the new marginal
$finalDiff = GaussianDistribution::subtract($newMarginal, $marginal0); $finalDiff = GaussianDistribution::subtract($newMarginal, $marginal0);
return $finalDiff; return $finalDiff;
} }
@ -186,10 +190,10 @@ class GaussianWeightedSumFactor extends GaussianFactor
$allMessages = $this->getMessages(); $allMessages = $this->getMessages();
$allVariables = $this->getVariables(); $allVariables = $this->getVariables();
Guard::argumentIsValidIndex($messageIndex, count($allMessages), "messageIndex"); Guard::argumentIsValidIndex($messageIndex, count($allMessages), 'messageIndex');
$updatedMessages = array(); $updatedMessages = [];
$updatedVariables = array(); $updatedVariables = [];
$indicesToUse = $this->_variableIndexOrdersForWeights[$messageIndex]; $indicesToUse = $this->_variableIndexOrdersForWeights[$messageIndex];
@ -211,7 +215,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
private static function createName($sumVariable, $variablesToSum, $weights) private static function createName($sumVariable, $variablesToSum, $weights)
{ {
// TODO: Perf? Use PHP equivalent of StringBuilder? implode on arrays? // TODO: Perf? Use PHP equivalent of StringBuilder? implode on arrays?
$result = (string)$sumVariable; $result = (string) $sumVariable;
$result .= ' = '; $result .= ' = ';
$totalVars = count($variablesToSum); $totalVars = count($variablesToSum);
@ -222,15 +226,15 @@ class GaussianWeightedSumFactor extends GaussianFactor
$result .= '-'; $result .= '-';
} }
$absValue = sprintf("%.2f", \abs($weights[$i])); // 0.00? $absValue = sprintf('%.2f', \abs($weights[$i])); // 0.00?
$result .= $absValue; $result .= $absValue;
$result .= "*["; $result .= '*[';
$result .= (string)$variablesToSum[$i]; $result .= (string) $variablesToSum[$i];
$result .= ']'; $result .= ']';
$isLast = ($i == ($totalVars - 1)); $isLast = ($i == ($totalVars - 1));
if (!$isLast) { if (! $isLast) {
if ($weights[$i + 1] >= 0) { if ($weights[$i + 1] >= 0) {
$result .= ' + '; $result .= ' + ';
} else { } else {
@ -241,4 +245,4 @@ class GaussianWeightedSumFactor extends GaussianFactor
return $result; return $result;
} }
} }

@ -1,9 +1,11 @@
<?php namespace DNW\Skills\TrueSkill\Factors; <?php
namespace DNW\Skills\TrueSkill\Factors;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
use DNW\Skills\FactorGraphs\Message; use DNW\Skills\FactorGraphs\Message;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
/** /**
* Factor representing a team difference that has not exceeded the draw margin. * Factor representing a team difference that has not exceeded the draw margin.
@ -16,7 +18,7 @@ class GaussianWithinFactor extends GaussianFactor
public function __construct($epsilon, Variable $variable) public function __construct($epsilon, Variable $variable)
{ {
parent::__construct(sprintf("%s <= %.2f", $variable, $epsilon)); parent::__construct(sprintf('%s <= %.2f', $variable, $epsilon));
$this->_epsilon = $epsilon; $this->_epsilon = $epsilon;
$this->createVariableToMessageBinding($variable); $this->createVariableToMessageBinding($variable);
} }
@ -57,7 +59,7 @@ class GaussianWithinFactor extends GaussianFactor
$denominator = 1.0 - TruncatedGaussianCorrectionFunctions::wWithinMargin($dOnSqrtC, $epsilonTimesSqrtC); $denominator = 1.0 - TruncatedGaussianCorrectionFunctions::wWithinMargin($dOnSqrtC, $epsilonTimesSqrtC);
$newPrecision = $c / $denominator; $newPrecision = $c / $denominator;
$newPrecisionMean = ( $d + $newPrecisionMean = ($d +
$sqrtC * $sqrtC *
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC) TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)
) / $denominator; ) / $denominator;
@ -75,4 +77,4 @@ class GaussianWithinFactor extends GaussianFactor
// Return the difference in the new marginal // Return the difference in the new marginal
return GaussianDistribution::subtract($newMarginal, $oldMarginal); return GaussianDistribution::subtract($newMarginal, $oldMarginal);
} }
} }

@ -1,15 +1,18 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use Exception;
use DNW\Skills\FactorGraphs\ScheduleLoop; use DNW\Skills\FactorGraphs\ScheduleLoop;
use DNW\Skills\FactorGraphs\ScheduleSequence; use DNW\Skills\FactorGraphs\ScheduleSequence;
use DNW\Skills\FactorGraphs\ScheduleStep; use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph; use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use Exception;
// The whole purpose of this is to do a loop on the bottom // The whole purpose of this is to do a loop on the bottom
class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
{ {
private $_TeamDifferencesComparisonLayer; private $_TeamDifferencesComparisonLayer;
private $_TeamPerformancesToTeamPerformanceDifferencesLayer; private $_TeamPerformancesToTeamPerformanceDifferencesLayer;
public function __construct(TrueSkillFactorGraph $parentGraph, public function __construct(TrueSkillFactorGraph $parentGraph,
@ -65,16 +68,16 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1]; $lastDifferencesFactor = $localFactors[$totalTeamDifferences - 1];
$innerSchedule = new ScheduleSequence( $innerSchedule = new ScheduleSequence(
"inner schedule", 'inner schedule',
array( [
$loop, $loop,
new ScheduleStep( new ScheduleStep(
"teamPerformanceToPerformanceDifferenceFactors[0] @ 1", 'teamPerformanceToPerformanceDifferenceFactors[0] @ 1',
$firstDifferencesFactor, 1), $firstDifferencesFactor, 1),
new ScheduleStep( new ScheduleStep(
sprintf("teamPerformanceToPerformanceDifferenceFactors[teamTeamDifferences = %d - 1] @ 2", $totalTeamDifferences), sprintf('teamPerformanceToPerformanceDifferenceFactors[teamTeamDifferences = %d - 1] @ 2', $totalTeamDifferences),
$lastDifferencesFactor, 2) $lastDifferencesFactor, 2),
) ]
); );
return $innerSchedule; return $innerSchedule;
@ -87,27 +90,27 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0]; $firstPerfToTeamDiff = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[0];
$firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0]; $firstTeamDiffComparison = $teamDifferencesComparisonLayerLocalFactors[0];
$itemsToSequence = array( $itemsToSequence = [
new ScheduleStep( new ScheduleStep(
"send team perf to perf differences", 'send team perf to perf differences',
$firstPerfToTeamDiff, $firstPerfToTeamDiff,
0), 0),
new ScheduleStep( new ScheduleStep(
"send to greater than or within factor", 'send to greater than or within factor',
$firstTeamDiffComparison, $firstTeamDiffComparison,
0) 0),
); ];
return $this->scheduleSequence( return $this->scheduleSequence(
$itemsToSequence, $itemsToSequence,
"loop of just two teams inner sequence"); 'loop of just two teams inner sequence');
} }
private function createMultipleTeamInnerPriorLoopSchedule() private function createMultipleTeamInnerPriorLoopSchedule()
{ {
$totalTeamDifferences = count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors()); $totalTeamDifferences = count($this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors());
$forwardScheduleList = array(); $forwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) { for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(); $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
@ -118,24 +121,24 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$currentForwardSchedulePiece = $currentForwardSchedulePiece =
$this->scheduleSequence( $this->scheduleSequence(
array( [
new ScheduleStep( new ScheduleStep(
sprintf("team perf to perf diff %d", $i), sprintf('team perf to perf diff %d', $i),
$currentTeamPerfToTeamPerfDiff, 0), $currentTeamPerfToTeamPerfDiff, 0),
new ScheduleStep( new ScheduleStep(
sprintf("greater than or within result factor %d", $i), sprintf('greater than or within result factor %d', $i),
$currentTeamDiffComparison, 0), $currentTeamDiffComparison, 0),
new ScheduleStep( new ScheduleStep(
sprintf("team perf to perf diff factors [%d], 2", $i), sprintf('team perf to perf diff factors [%d], 2', $i),
$currentTeamPerfToTeamPerfDiff, 2) $currentTeamPerfToTeamPerfDiff, 2),
), sprintf("current forward schedule piece %d", $i)); ], sprintf('current forward schedule piece %d', $i));
$forwardScheduleList[] = $currentForwardSchedulePiece; $forwardScheduleList[] = $currentForwardSchedulePiece;
} }
$forwardSchedule = new ScheduleSequence("forward schedule", $forwardScheduleList); $forwardSchedule = new ScheduleSequence('forward schedule', $forwardScheduleList);
$backwardScheduleList = array(); $backwardScheduleList = [];
for ($i = 0; $i < $totalTeamDifferences - 1; $i++) { for ($i = 0; $i < $totalTeamDifferences - 1; $i++) {
$teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors(); $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors = $this->_TeamPerformancesToTeamPerformanceDifferencesLayer->getLocalFactors();
@ -146,35 +149,35 @@ class IteratedTeamDifferencesInnerLayer extends TrueSkillFactorGraphLayer
$performancesToDifferencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i]; $performancesToDifferencesFactor = $teamPerformancesToTeamPerformanceDifferencesLayerLocalFactors[$totalTeamDifferences - 1 - $i];
$currentBackwardSchedulePiece = new ScheduleSequence( $currentBackwardSchedulePiece = new ScheduleSequence(
"current backward schedule piece", 'current backward schedule piece',
array( [
new ScheduleStep( new ScheduleStep(
sprintf("teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 0", $i), sprintf('teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 0', $i),
$differencesFactor, 0), $differencesFactor, 0),
new ScheduleStep( new ScheduleStep(
sprintf("greaterThanOrWithinResultFactors[totalTeamDifferences - 1 - %d] @ 0", $i), sprintf('greaterThanOrWithinResultFactors[totalTeamDifferences - 1 - %d] @ 0', $i),
$comparisonFactor, 0), $comparisonFactor, 0),
new ScheduleStep( new ScheduleStep(
sprintf("teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 1", $i), sprintf('teamPerformanceToPerformanceDifferenceFactors[totalTeamDifferences - 1 - %d] @ 1', $i),
$performancesToDifferencesFactor, 1) $performancesToDifferencesFactor, 1),
)); ]);
$backwardScheduleList[] = $currentBackwardSchedulePiece; $backwardScheduleList[] = $currentBackwardSchedulePiece;
} }
$backwardSchedule = new ScheduleSequence("backward schedule", $backwardScheduleList); $backwardSchedule = new ScheduleSequence('backward schedule', $backwardScheduleList);
$forwardBackwardScheduleToLoop = $forwardBackwardScheduleToLoop =
new ScheduleSequence( new ScheduleSequence(
"forward Backward Schedule To Loop", 'forward Backward Schedule To Loop',
array($forwardSchedule, $backwardSchedule)); [$forwardSchedule, $backwardSchedule]);
$initialMaxDelta = 0.0001; $initialMaxDelta = 0.0001;
$loop = new ScheduleLoop( $loop = new ScheduleLoop(
sprintf("loop with max delta of %f", $initialMaxDelta), sprintf('loop with max delta of %f', $initialMaxDelta),
$forwardBackwardScheduleToLoop, $forwardBackwardScheduleToLoop,
$initialMaxDelta); $initialMaxDelta);
return $loop; return $loop;
} }
} }

@ -1,9 +1,9 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\PartialPlay;
use DNW\Skills\FactorGraphs\ScheduleLoop;
use DNW\Skills\FactorGraphs\ScheduleSequence;
use DNW\Skills\FactorGraphs\ScheduleStep; use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\PartialPlay;
use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor; use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph; use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
@ -26,7 +26,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
// REVIEW: Does it make sense to have groups of one? // REVIEW: Does it make sense to have groups of one?
$outputVariablesGroups = &$this->getOutputVariablesGroups(); $outputVariablesGroups = &$this->getOutputVariablesGroups();
$outputVariablesGroups[] = array($teamPerformance); $outputVariablesGroups[] = [$teamPerformance];
} }
} }
@ -37,10 +37,11 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$sequence = $this->scheduleSequence( $sequence = $this->scheduleSequence(
array_map( array_map(
function ($weightedSumFactor) { function ($weightedSumFactor) {
return new ScheduleStep("Perf to Team Perf Step", $weightedSumFactor, 0); return new ScheduleStep('Perf to Team Perf Step', $weightedSumFactor, 0);
}, },
$localFactors), $localFactors),
"all player perf to team perf schedule"); 'all player perf to team perf schedule');
return $sequence; return $sequence;
} }
@ -49,6 +50,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$weights = array_map( $weights = array_map(
function ($v) { function ($v) {
$player = $v->getKey(); $player = $v->getKey();
return PartialPlay::getPartialPlayPercentage($player); return PartialPlay::getPartialPlayPercentage($player);
}, },
$teamMembers); $teamMembers);
@ -57,32 +59,33 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$sumVariable, $sumVariable,
$teamMembers, $teamMembers,
$weights); $weights);
} }
public function createPosteriorSchedule() public function createPosteriorSchedule()
{ {
$allFactors = array(); $allFactors = [];
$localFactors = $this->getLocalFactors(); $localFactors = $this->getLocalFactors();
foreach ($localFactors as $currentFactor) { foreach ($localFactors as $currentFactor) {
$localCurrentFactor = $currentFactor; $localCurrentFactor = $currentFactor;
$numberOfMessages = $localCurrentFactor->getNumberOfMessages(); $numberOfMessages = $localCurrentFactor->getNumberOfMessages();
for ($currentIteration = 1; $currentIteration < $numberOfMessages; $currentIteration++) { for ($currentIteration = 1; $currentIteration < $numberOfMessages; $currentIteration++) {
$allFactors[] = new ScheduleStep("team sum perf @" . $currentIteration, $allFactors[] = new ScheduleStep('team sum perf @'.$currentIteration,
$localCurrentFactor, $currentIteration); $localCurrentFactor, $currentIteration);
} }
} }
return $this->scheduleSequence($allFactors, "all of the team's sum iterations"); return $this->scheduleSequence($allFactors, "all of the team's sum iterations");
} }
private function createOutputVariable($team) private function createOutputVariable($team)
{ {
$memberNames = array_map(function ($currentPlayer) { $memberNames = array_map(function ($currentPlayer) {
return (string)($currentPlayer->getKey()); return (string) ($currentPlayer->getKey());
}, $team); }, $team);
$teamMemberNames = \join(", ", $memberNames); $teamMemberNames = \implode(', ', $memberNames);
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team[" . $teamMemberNames . "]'s performance"); $outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team['.$teamMemberNames."]'s performance");
return $outputVariable; return $outputVariable;
} }
} }

@ -1,11 +1,13 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Rating;
use DNW\Skills\FactorGraphs\ScheduleStep; use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Rating;
use DNW\Skills\TrueSkill\Factors\GaussianPriorFactor; use DNW\Skills\TrueSkill\Factors\GaussianPriorFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
// We intentionally have no Posterior schedule since the only purpose here is to // We intentionally have no Posterior schedule since the only purpose here is to
// start the process. // start the process.
@ -24,7 +26,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
$teams = $this->_teams; $teams = $this->_teams;
foreach ($teams as $currentTeam) { foreach ($teams as $currentTeam) {
$localCurrentTeam = $currentTeam; $localCurrentTeam = $currentTeam;
$currentTeamSkills = array(); $currentTeamSkills = [];
$currentTeamAllPlayers = $localCurrentTeam->getAllPlayers(); $currentTeamAllPlayers = $localCurrentTeam->getAllPlayers();
foreach ($currentTeamAllPlayers as $currentTeamPlayer) { foreach ($currentTeamAllPlayers as $currentTeamPlayer) {
@ -44,13 +46,14 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
public function createPriorSchedule() public function createPriorSchedule()
{ {
$localFactors = $this->getLocalFactors(); $localFactors = $this->getLocalFactors();
return $this->scheduleSequence( return $this->scheduleSequence(
array_map( array_map(
function ($prior) { function ($prior) {
return new ScheduleStep("Prior to Skill Step", $prior, 0); return new ScheduleStep('Prior to Skill Step', $prior, 0);
}, },
$localFactors), $localFactors),
"All priors"); 'All priors');
} }
private function createPriorFactor($player, Rating $priorRating, Variable $skillsVariable) private function createPriorFactor($player, Rating $priorRating, Variable $skillsVariable)
@ -67,7 +70,8 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{ {
$parentFactorGraph = $this->getParentFactorGraph(); $parentFactorGraph = $this->getParentFactorGraph();
$variableFactory = $parentFactorGraph->getVariableFactory(); $variableFactory = $parentFactorGraph->getVariableFactory();
$skillOutputVariable = $variableFactory->createKeyedVariable($key, $key . "'s skill"); $skillOutputVariable = $variableFactory->createKeyedVariable($key, $key."'s skill");
return $skillOutputVariable; return $skillOutputVariable;
} }
} }

@ -1,10 +1,12 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\FactorGraphs\KeyedVariable; use DNW\Skills\FactorGraphs\KeyedVariable;
use DNW\Skills\FactorGraphs\ScheduleStep;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor; use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
{ {
@ -19,7 +21,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
$outputVariablesGroups = &$this->getOutputVariablesGroups(); $outputVariablesGroups = &$this->getOutputVariablesGroups();
foreach ($inputVariablesGroups as $currentTeam) { foreach ($inputVariablesGroups as $currentTeam) {
$currentTeamPlayerPerformances = array(); $currentTeamPlayerPerformances = [];
foreach ($currentTeam as $playerSkillVariable) { foreach ($currentTeam as $playerSkillVariable) {
$localPlayerSkillVariable = $playerSkillVariable; $localPlayerSkillVariable = $playerSkillVariable;
@ -45,31 +47,34 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
private function createOutputVariable($key) private function createOutputVariable($key)
{ {
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance"); $outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key."'s performance");
return $outputVariable; return $outputVariable;
} }
public function createPriorSchedule() public function createPriorSchedule()
{ {
$localFactors = $this->getLocalFactors(); $localFactors = $this->getLocalFactors();
return $this->scheduleSequence( return $this->scheduleSequence(
array_map( array_map(
function ($likelihood) { function ($likelihood) {
return new ScheduleStep("Skill to Perf step", $likelihood, 0); return new ScheduleStep('Skill to Perf step', $likelihood, 0);
}, },
$localFactors), $localFactors),
"All skill to performance sending"); 'All skill to performance sending');
} }
public function createPosteriorSchedule() public function createPosteriorSchedule()
{ {
$localFactors = $this->getLocalFactors(); $localFactors = $this->getLocalFactors();
return $this->scheduleSequence( return $this->scheduleSequence(
array_map( array_map(
function ($likelihood) { function ($likelihood) {
return new ScheduleStep("name", $likelihood, 1); return new ScheduleStep('name', $likelihood, 1);
}, },
$localFactors), $localFactors),
"All skill to performance sending"); 'All skill to performance sending');
} }
} }

@ -1,13 +1,16 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\TrueSkill\DrawMargin; use DNW\Skills\TrueSkill\DrawMargin;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianGreaterThanFactor; use DNW\Skills\TrueSkill\Factors\GaussianGreaterThanFactor;
use DNW\Skills\TrueSkill\Factors\GaussianWithinFactor; use DNW\Skills\TrueSkill\Factors\GaussianWithinFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
{ {
private $_epsilon; private $_epsilon;
private $_teamRanks; private $_teamRanks;
public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks) public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks)
@ -35,4 +38,4 @@ class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
$this->addLayerFactor($factor); $this->addLayerFactor($factor);
} }
} }
} }

@ -1,8 +1,10 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\Variable; use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor; use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
{ {
@ -17,8 +19,7 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
$inputVariablesGroupsCount = count($inputVariablesGroups); $inputVariablesGroupsCount = count($inputVariablesGroups);
$outputVariablesGroup = &$this->getOutputVariablesGroups(); $outputVariablesGroup = &$this->getOutputVariablesGroups();
for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++) for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++) {
{
$strongerTeam = $inputVariablesGroups[$i][0]; $strongerTeam = $inputVariablesGroups[$i][0];
$weakerTeam = $inputVariablesGroups[$i + 1][0]; $weakerTeam = $inputVariablesGroups[$i + 1][0];
@ -27,7 +28,7 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
$this->addLayerFactor($newDifferencesFactor); $this->addLayerFactor($newDifferencesFactor);
// REVIEW: Does it make sense to have groups of one? // REVIEW: Does it make sense to have groups of one?
$outputVariablesGroup[] = array($currentDifference); $outputVariablesGroup[] = [$currentDifference];
} }
} }
@ -35,14 +36,16 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
Variable $weakerTeam, Variable $weakerTeam,
Variable $output) Variable $output)
{ {
$teams = array($strongerTeam, $weakerTeam); $teams = [$strongerTeam, $weakerTeam];
$weights = array(1.0, -1.0); $weights = [1.0, -1.0];
return new GaussianWeightedSumFactor($output, $teams, $weights); return new GaussianWeightedSumFactor($output, $teams, $weights);
} }
private function createOutputVariable() private function createOutputVariable()
{ {
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team performance difference"); $outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team performance difference');
return $outputVariable; return $outputVariable;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill\Layers; <?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\FactorGraphLayer; use DNW\Skills\FactorGraphs\FactorGraphLayer;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph; use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
@ -9,4 +11,4 @@ abstract class TrueSkillFactorGraphLayer extends FactorGraphLayer
{ {
parent::__construct($parentGraph); parent::__construct($parentGraph);
} }
} }

@ -1,13 +1,15 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\Rating;
use DNW\Skills\RatingContainer;
use DNW\Skills\FactorGraphs\FactorGraph; use DNW\Skills\FactorGraphs\FactorGraph;
use DNW\Skills\FactorGraphs\FactorList; use DNW\Skills\FactorGraphs\FactorList;
use DNW\Skills\FactorGraphs\ScheduleSequence; use DNW\Skills\FactorGraphs\ScheduleSequence;
use DNW\Skills\FactorGraphs\VariableFactory; use DNW\Skills\FactorGraphs\VariableFactory;
use DNW\Skills\GameInfo;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\Rating;
use DNW\Skills\RatingContainer;
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;
@ -18,7 +20,9 @@ use DNW\Skills\TrueSkill\Layers\TeamPerformancesToTeamPerformanceDifferencesLaye
class TrueSkillFactorGraph extends FactorGraph class TrueSkillFactorGraph extends FactorGraph
{ {
private $_gameInfo; private $_gameInfo;
private $_layers; private $_layers;
private $_priorLayer; private $_priorLayer;
public function __construct(GameInfo $gameInfo, array $teams, array $teamRanks) public function __construct(GameInfo $gameInfo, array $teams, array $teamRanks)
@ -31,15 +35,15 @@ class TrueSkillFactorGraph extends FactorGraph
}); });
$this->setVariableFactory($newFactory); $this->setVariableFactory($newFactory);
$this->_layers = array( $this->_layers = [
$this->_priorLayer, $this->_priorLayer,
new PlayerSkillsToPerformancesLayer($this), new PlayerSkillsToPerformancesLayer($this),
new PlayerPerformancesToTeamPerformancesLayer($this), new PlayerPerformancesToTeamPerformancesLayer($this),
new IteratedTeamDifferencesInnerLayer( new IteratedTeamDifferencesInnerLayer(
$this, $this,
new TeamPerformancesToTeamPerformanceDifferencesLayer($this), new TeamPerformancesToTeamPerformanceDifferencesLayer($this),
new TeamDifferencesComparisonLayer($this, $teamRanks)) new TeamDifferencesComparisonLayer($this, $teamRanks)),
); ];
} }
public function getGameInfo() public function getGameInfo()
@ -83,12 +87,13 @@ class TrueSkillFactorGraph extends FactorGraph
} }
$logZ = $factorList->getLogNormalization(); $logZ = $factorList->getLogNormalization();
return exp($logZ); return exp($logZ);
} }
private function createFullSchedule() private function createFullSchedule()
{ {
$fullSchedule = array(); $fullSchedule = [];
$layers = $this->_layers; $layers = $this->_layers;
foreach ($layers as $currentLayer) { foreach ($layers as $currentLayer) {
@ -107,7 +112,7 @@ class TrueSkillFactorGraph extends FactorGraph
} }
} }
return new ScheduleSequence("Full schedule", $fullSchedule); return new ScheduleSequence('Full schedule', $fullSchedule);
} }
public function getUpdatedRatings() public function getUpdatedRatings()
@ -127,4 +132,4 @@ class TrueSkillFactorGraph extends FactorGraph
return $result; return $result;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
@ -13,7 +15,7 @@ class TruncatedGaussianCorrectionFunctions
* correction of a single-sided truncated Gaussian with unit variance." * correction of a single-sided truncated Gaussian with unit variance."
* *
* @param $teamPerformanceDifference * @param $teamPerformanceDifference
* @param number $drawMargin In the paper, it's referred to as just "ε". * @param number $drawMargin In the paper, it's referred to as just "ε".
* @param $c * @param $c
* @return float * @return float
*/ */
@ -57,10 +59,12 @@ class TruncatedGaussianCorrectionFunctions
if ($teamPerformanceDifference < 0.0) { if ($teamPerformanceDifference < 0.0) {
return 1.0; return 1.0;
} }
return 0.0; return 0.0;
} }
$vWin = self::vExceedsMargin($teamPerformanceDifference, $drawMargin); $vWin = self::vExceedsMargin($teamPerformanceDifference, $drawMargin);
return $vWin * ($vWin + $teamPerformanceDifference - $drawMargin); return $vWin * ($vWin + $teamPerformanceDifference - $drawMargin);
} }
@ -126,4 +130,4 @@ class TruncatedGaussianCorrectionFunctions
* *
GaussianDistribution::at(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue)) / $denominator; GaussianDistribution::at(-$drawMargin - $teamPerformanceDifferenceAbsoluteValue)) / $denominator;
} }
} }

@ -1,15 +1,17 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo; use DNW\Skills\GameInfo;
use DNW\Skills\Guard; use DNW\Skills\Guard;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\PairwiseComparison; use DNW\Skills\PairwiseComparison;
use DNW\Skills\PlayersRange;
use DNW\Skills\RankSorter; use DNW\Skills\RankSorter;
use DNW\Skills\Rating; use DNW\Skills\Rating;
use DNW\Skills\RatingContainer; use DNW\Skills\RatingContainer;
use DNW\Skills\SkillCalculator; use DNW\Skills\SkillCalculator;
use DNW\Skills\SkillCalculatorSupportedOptions; use DNW\Skills\SkillCalculatorSupportedOptions;
use DNW\Skills\PlayersRange;
use DNW\Skills\TeamsRange; use DNW\Skills\TeamsRange;
/** /**
@ -30,7 +32,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
array $teamRanks) array $teamRanks)
{ {
// Basic argument checking // Basic argument checking
Guard::argumentNotNull($gameInfo, "gameInfo"); Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams); $this->validateTeamCountAndPlayersCountPerTeam($teams);
// Make sure things are in order // Make sure things are in order
@ -83,8 +85,7 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
$winningMean = $selfRating->getMean(); $winningMean = $selfRating->getMean();
$losingMean = $opponentRating->getMean(); $losingMean = $opponentRating->getMean();
switch ($comparison) switch ($comparison) {
{
case PairwiseComparison::WIN: case PairwiseComparison::WIN:
case PairwiseComparison::DRAW: case PairwiseComparison::DRAW:
// NOP // NOP
@ -97,37 +98,34 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
$meanDelta = $winningMean - $losingMean; $meanDelta = $winningMean - $losingMean;
if ($comparison != PairwiseComparison::DRAW) if ($comparison != PairwiseComparison::DRAW) {
{
// non-draw case // non-draw case
$v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c); $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c);
$w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c);
$rankMultiplier = (int) $comparison; $rankMultiplier = (int) $comparison;
} } else {
else
{
$v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c); $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c);
$w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c);
$rankMultiplier = 1; $rankMultiplier = 1;
} }
$meanMultiplier = (BasicMath::square($selfRating->getStandardDeviation()) + BasicMath::square($gameInfo->getDynamicsFactor()))/$c; $meanMultiplier = (BasicMath::square($selfRating->getStandardDeviation()) + BasicMath::square($gameInfo->getDynamicsFactor())) / $c;
$varianceWithDynamics = BasicMath::square($selfRating->getStandardDeviation()) + BasicMath::square($gameInfo->getDynamicsFactor()); $varianceWithDynamics = BasicMath::square($selfRating->getStandardDeviation()) + BasicMath::square($gameInfo->getDynamicsFactor());
$stdDevMultiplier = $varianceWithDynamics/BasicMath::square($c); $stdDevMultiplier = $varianceWithDynamics / BasicMath::square($c);
$newMean = $selfRating->getMean() + ($rankMultiplier*$meanMultiplier*$v); $newMean = $selfRating->getMean() + ($rankMultiplier * $meanMultiplier * $v);
$newStdDev = sqrt($varianceWithDynamics*(1 - $w*$stdDevMultiplier)); $newStdDev = sqrt($varianceWithDynamics * (1 - $w * $stdDevMultiplier));
return new Rating($newMean, $newStdDev); return new Rating($newMean, $newStdDev);
} }
/** /**
* {@inheritdoc } * {@inheritdoc}
*/ */
public function calculateMatchQuality(GameInfo $gameInfo, array $teams) public function calculateMatchQuality(GameInfo $gameInfo, array $teams)
{ {
Guard::argumentNotNull($gameInfo, "gameInfo"); Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams); $this->validateTeamCountAndPlayersCountPerTeam($teams);
$team1 = $teams[0]; $team1 = $teams[0];
@ -146,18 +144,18 @@ class TwoPlayerTrueSkillCalculator extends SkillCalculator
// This is the square root part of the equation: // This is the square root part of the equation:
$sqrtPart = sqrt( $sqrtPart = sqrt(
(2*$betaSquared) (2 * $betaSquared)
/ /
(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared) (2 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared)
); );
// This is the exponent part of the equation: // This is the exponent part of the equation:
$expPart = exp( $expPart = exp(
(-1*BasicMath::square($player1Rating->getMean() - $player2Rating->getMean())) (-1 * BasicMath::square($player1Rating->getMean() - $player2Rating->getMean()))
/ /
(2*(2*$betaSquared + $player1SigmaSquared + $player2SigmaSquared)) (2 * (2 * $betaSquared + $player1SigmaSquared + $player2SigmaSquared))
); );
return $sqrtPart*$expPart; return $sqrtPart * $expPart;
} }
} }

@ -1,19 +1,19 @@
<?php namespace DNW\Skills\TrueSkill; <?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo; use DNW\Skills\GameInfo;
use DNW\Skills\Guard; use DNW\Skills\Guard;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\PairwiseComparison; use DNW\Skills\PairwiseComparison;
use DNW\Skills\PlayersRange;
use DNW\Skills\RankSorter; use DNW\Skills\RankSorter;
use DNW\Skills\Rating; use DNW\Skills\Rating;
use DNW\Skills\RatingContainer; use DNW\Skills\RatingContainer;
use DNW\Skills\SkillCalculator; use DNW\Skills\SkillCalculator;
use DNW\Skills\SkillCalculatorSupportedOptions; use DNW\Skills\SkillCalculatorSupportedOptions;
use DNW\Skills\PlayersRange;
use DNW\Skills\TeamsRange;
use DNW\Skills\Team; use DNW\Skills\Team;
use DNW\Skills\TeamsRange;
/** /**
* Calculates new ratings for only two teams where each team has 1 or more players. * Calculates new ratings for only two teams where each team has 1 or more players.
@ -29,7 +29,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
public function calculateNewRatings(GameInfo $gameInfo, array $teams, array $teamRanks) public function calculateNewRatings(GameInfo $gameInfo, array $teams, array $teamRanks)
{ {
Guard::argumentNotNull($gameInfo, "gameInfo"); Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams); $this->validateTeamCountAndPlayersCountPerTeam($teams);
RankSorter::sort($teams, $teamRanks); RankSorter::sort($teams, $teamRanks);
@ -111,7 +111,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
// non-draw case // non-draw case
$v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c); $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c);
$w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c);
$rankMultiplier = (int)$selfToOtherTeamComparison; $rankMultiplier = (int) $selfToOtherTeamComparison;
} else { } else {
// assume draw // assume draw
$v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c); $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c);
@ -143,7 +143,7 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
*/ */
public function calculateMatchQuality(GameInfo $gameInfo, array $teams) public function calculateMatchQuality(GameInfo $gameInfo, array $teams)
{ {
Guard::argumentNotNull($gameInfo, "gameInfo"); 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
@ -189,4 +189,4 @@ class TwoTeamTrueSkillCalculator extends SkillCalculator
return $expPart * $sqrtPart; return $expPart * $sqrtPart;
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\Numerics; <?php
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Tests\TestCase; use DNW\Skills\Tests\TestCase;
@ -11,4 +13,4 @@ class BasicMathTest extends TestCase
$this->assertEquals(1.44, BasicMath::square(1.2)); $this->assertEquals(1.44, BasicMath::square(1.2));
$this->assertEquals(4, BasicMath::square(2)); $this->assertEquals(4, BasicMath::square(2));
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\Numerics; <?php
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\BasicMath; use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Numerics\GaussianDistribution; use DNW\Skills\Numerics\GaussianDistribution;
@ -95,4 +97,4 @@ class GaussianDistributionTest extends TestCase
$absDiff2 = GaussianDistribution::absoluteDifference($m1s2, $m3s4); $absDiff2 = GaussianDistribution::absoluteDifference($m1s2, $m3s4);
$this->assertEqualsWithDelta(0.4330127018922193, $absDiff2, GaussianDistributionTest::ERROR_TOLERANCE); $this->assertEqualsWithDelta(0.4330127018922193, $absDiff2, GaussianDistributionTest::ERROR_TOLERANCE);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\Numerics; <?php
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\IdentityMatrix; use DNW\Skills\Numerics\IdentityMatrix;
use DNW\Skills\Numerics\Matrix; use DNW\Skills\Numerics\Matrix;
@ -48,7 +50,7 @@ class MatrixTest extends TestCase
public function testFourByFourDeterminant() public function testFourByFourDeterminant()
{ {
$a = new SquareMatrix( 1, 2, 3, 4, $a = new SquareMatrix(1, 2, 3, 4,
5, 6, 7, 8, 5, 6, 7, 8,
9, 10, 11, 12, 9, 10, 11, 12,
13, 14, 15, 16); 13, 14, 15, 16);
@ -66,7 +68,7 @@ class MatrixTest extends TestCase
public function testEightByEightDeterminant() public function testEightByEightDeterminant()
{ {
$a = new SquareMatrix( 1, 2, 3, 4, 5, 6, 7, 8, $a = new SquareMatrix(1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32, 25, 26, 27, 28, 29, 30, 31, 32,
@ -134,19 +136,18 @@ class MatrixTest extends TestCase
$a = new SquareMatrix(1, 2, $a = new SquareMatrix(1, 2,
3, 4); 3, 4);
$b = new SquareMatrix( 4, -2, $b = new SquareMatrix(4, -2,
-3, 1); -3, 1);
$this->assertTrue($b->equals($a->getAdjugate())); $this->assertTrue($b->equals($a->getAdjugate()));
$c = new SquareMatrix(-3, 2, -5, $c = new SquareMatrix(-3, 2, -5,
-1, 0, -2, -1, 0, -2,
3, -4, 1); 3, -4, 1);
$d = new SquareMatrix(-8, 18, -4, $d = new SquareMatrix(-8, 18, -4,
-5, 12, -1, -5, 12, -1,
4, -6, 2); 4, -6, 2);
$this->assertTrue($d->equals($c->getAdjugate())); $this->assertTrue($d->equals($c->getAdjugate()));
} }
@ -175,8 +176,7 @@ class MatrixTest extends TestCase
$cInverse = $c->getInverse(); $cInverse = $c->getInverse();
$d = Matrix::scalarMultiply((1.0 / 22), new SquareMatrix(24, -12, -2, $d = Matrix::scalarMultiply((1.0 / 22), new SquareMatrix(24, -12, -2,
5, 3, -5, 5, 3, -5,
-4, 2, 4)); -4, 2, 4));
$this->assertTrue($d->equals($cInverse)); $this->assertTrue($d->equals($cInverse));
$identity3x3 = new IdentityMatrix(3); $identity3x3 = new IdentityMatrix(3);
@ -184,4 +184,4 @@ class MatrixTest extends TestCase
$ccInverse = Matrix::multiply($c, $cInverse); $ccInverse = Matrix::multiply($c, $cInverse);
$this->assertTrue($identity3x3->equals($ccInverse)); $this->assertTrue($identity3x3->equals($ccInverse));
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests; <?php
namespace DNW\Skills\Tests;
use DNW\Skills\RankSorter; use DNW\Skills\RankSorter;
@ -6,13 +8,13 @@ class RankSorterTest extends TestCase
{ {
public function testSort() public function testSort()
{ {
$team1 = array("a" => 1, "b" => 2); $team1 = ['a' => 1, 'b' => 2];
$team2 = array("c" => 3, "d" => 4); $team2 = ['c' => 3, 'd' => 4];
$team3 = array("e" => 5, "f" => 6); $team3 = ['e' => 5, 'f' => 6];
$teams = array($team1, $team2, $team3); $teams = [$team1, $team2, $team3];
$teamRanks = array(3, 1, 2); $teamRanks = [3, 1, 2];
$sortedRanks = RankSorter::sort($teams, $teamRanks); $sortedRanks = RankSorter::sort($teams, $teamRanks);
@ -30,4 +32,4 @@ class RankSorterTest extends TestCase
$this->assertEquals($teams[1], $sortedRanks[1]); $this->assertEquals($teams[1], $sortedRanks[1]);
$this->assertEquals($teams[2], $sortedRanks[2]); $this->assertEquals($teams[2], $sortedRanks[2]);
} }
} }

@ -1,5 +1,7 @@
<?php namespace DNW\Skills\Tests; <?php
namespace DNW\Skills\Tests;
class TestCase extends \PHPUnit\Framework\TestCase class TestCase extends \PHPUnit\Framework\TestCase
{ {
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill; <?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase; use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\DrawMargin; use DNW\Skills\TrueSkill\DrawMargin;
@ -21,4 +23,4 @@ class DrawMarginTest extends TestCase
$actual = DrawMargin::getDrawMarginFromDrawProbability($drawProbability, $beta); $actual = DrawMargin::getDrawMarginFromDrawProbability($drawProbability, $beta);
$this->assertEqualsWithDelta($expected, $actual, DrawMarginTest::ERROR_TOLERANCE); $this->assertEqualsWithDelta($expected, $actual, DrawMarginTest::ERROR_TOLERANCE);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill; <?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase; use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator; use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;
@ -14,4 +16,4 @@ class FactorGraphTeamTrueSkillCalculatorTest extends TestCase
TrueSkillCalculatorTests::testAllMultipleTeamScenarios($this, $calculator); TrueSkillCalculatorTests::testAllMultipleTeamScenarios($this, $calculator);
TrueSkillCalculatorTests::testPartialPlayScenarios($this, $calculator); TrueSkillCalculatorTests::testPartialPlayScenarios($this, $calculator);
} }
} }

@ -1,15 +1,18 @@
<?php namespace DNW\Skills\Tests\TrueSkill; <?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\GameInfo; use DNW\Skills\GameInfo;
use DNW\Skills\Player; use DNW\Skills\Player;
use DNW\Skills\Rating; use DNW\Skills\Rating;
use DNW\Skills\SkillCalculator;
use DNW\Skills\Team; use DNW\Skills\Team;
use DNW\Skills\Teams; use DNW\Skills\Teams;
use DNW\Skills\SkillCalculator;
class TrueSkillCalculatorTests class TrueSkillCalculatorTests
{ {
const ERROR_TOLERANCE_TRUESKILL = 0.085; const ERROR_TOLERANCE_TRUESKILL = 0.085;
const ERROR_TOLERANCE_MATCH_QUALITY = 0.0005; const ERROR_TOLERANCE_MATCH_QUALITY = 0.0005;
// These are the roll-up ones // These are the roll-up ones
@ -79,10 +82,10 @@ class TrueSkillCalculatorTests
$gameInfo = new GameInfo(); $gameInfo = new GameInfo();
$team1 = new Team($player1, $gameInfo->getDefaultRating()); $team1 = new Team($player1, $gameInfo->getDefaultRating());
$team2 = new Team($player2, $gameInfo->getDefaultRating());; $team2 = new Team($player2, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 29.39583201999924, 7.171475587326186, $player1NewRating); self::assertRating($testClass, 29.39583201999924, 7.171475587326186, $player1NewRating);
@ -104,7 +107,7 @@ class TrueSkillCalculatorTests
$team2 = new Team($player2, $gameInfo->getDefaultRating()); $team2 = new Team($player2, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 25.0, 6.4575196623173081, $player1NewRating); self::assertRating($testClass, 25.0, 6.4575196623173081, $player1NewRating);
@ -125,7 +128,7 @@ class TrueSkillCalculatorTests
$team1 = new Team($player1, new Rating(1301.0007, 42.9232)); $team1 = new Team($player1, new Rating(1301.0007, 42.9232));
$team2 = new Team($player2, new Rating(1188.7560, 42.5570)); $team2 = new Team($player2, new Rating(1188.7560, 42.5570));
$newRatings = $calculator->calculateNewRatings($gameInfo, Teams::concat($team1, $team2), array(1, 2)); $newRatings = $calculator->calculateNewRatings($gameInfo, Teams::concat($team1, $team2), [1, 2]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 1304.7820836053318, 42.843513887848658, $player1NewRating); self::assertRating($testClass, 1304.7820836053318, 42.843513887848658, $player1NewRating);
@ -148,7 +151,7 @@ class TrueSkillCalculatorTests
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
// Winners // Winners
self::assertRating($testClass, 31.662, 7.137, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 31.662, 7.137, $newRatingsWinLose->getRating($player1));
@ -180,7 +183,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player3, $gameInfo->getDefaultRating()); $team2->addPlayer($player3, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 33.730, 7.317, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 33.730, 7.317, $newRatingsWinLose->getRating($player1));
@ -215,7 +218,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, $gameInfo->getDefaultRating()); $team2->addPlayer($player4, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 28.108, 7.774, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 28.108, 7.774, $newRatingsWinLose->getRating($player1));
@ -245,7 +248,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player3, new Rating(25, 8)); $team2->addPlayer($player3, new Rating(25, 8));
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 42.744, 5.602, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 42.744, 5.602, $newRatingsWinLose->getRating($player1));
@ -276,7 +279,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, $gameInfo->getDefaultRating()); $team2->addPlayer($player4, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 36.337, 7.527, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 36.337, 7.527, $newRatingsWinLose->getRating($player1));
@ -296,7 +299,7 @@ class TrueSkillCalculatorTests
$gameInfo = new GameInfo(); $gameInfo = new GameInfo();
$team1 = new Team(); $team1 = new Team();
$team1->addPlayer($player1, $gameInfo->getDefaultRating());; $team1->addPlayer($player1, $gameInfo->getDefaultRating());
$player2 = new Player(2); $player2 = new Player(2);
$player3 = new Player(3); $player3 = new Player(3);
@ -306,7 +309,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player3, $gameInfo->getDefaultRating()); $team2->addPlayer($player3, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
// Winners // Winners
self::assertRating($testClass, 31.660, 7.138, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 31.660, 7.138, $newRatingsWinLose->getRating($player1));
@ -337,7 +340,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, $gameInfo->getDefaultRating()); $team2->addPlayer($player4, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
// Winners // Winners
self::assertRating($testClass, 34.990, 7.455, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 34.990, 7.455, $newRatingsWinLose->getRating($player1));
@ -377,7 +380,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player8, $gameInfo->getDefaultRating()); $team2->addPlayer($player8, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 40.582, 7.917, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 40.582, 7.917, $newRatingsWinLose->getRating($player1));
@ -405,7 +408,6 @@ class TrueSkillCalculatorTests
$team1->addPlayer($player2, new Rating(27, 6)); $team1->addPlayer($player2, new Rating(27, 6));
$team1->addPlayer($player3, new Rating(26, 5)); $team1->addPlayer($player3, new Rating(26, 5));
$player4 = new Player(4); $player4 = new Player(4);
$player5 = new Player(5); $player5 = new Player(5);
@ -416,7 +418,7 @@ class TrueSkillCalculatorTests
$gameInfo = new GameInfo(); $gameInfo = new GameInfo();
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLoseExpected = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLoseExpected = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 28.658, 6.770, $newRatingsWinLoseExpected->getRating($player1)); self::assertRating($testClass, 28.658, 6.770, $newRatingsWinLoseExpected->getRating($player1));
@ -427,7 +429,7 @@ class TrueSkillCalculatorTests
self::assertRating($testClass, 29.785, 3.958, $newRatingsWinLoseExpected->getRating($player4)); self::assertRating($testClass, 29.785, 3.958, $newRatingsWinLoseExpected->getRating($player4));
self::assertRating($testClass, 30.879, 2.983, $newRatingsWinLoseExpected->getRating($player5)); self::assertRating($testClass, 30.879, 2.983, $newRatingsWinLoseExpected->getRating($player5));
$newRatingsWinLoseUpset = $calculator->calculateNewRatings($gameInfo, Teams::concat($team1, $team2), array(2, 1)); $newRatingsWinLoseUpset = $calculator->calculateNewRatings($gameInfo, Teams::concat($team1, $team2), [2, 1]);
// Winners // Winners
self::assertRating($testClass, 32.012, 3.877, $newRatingsWinLoseUpset->getRating($player4)); self::assertRating($testClass, 32.012, 3.877, $newRatingsWinLoseUpset->getRating($player4));
@ -460,7 +462,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, new Rating(30, 3)); $team2->addPlayer($player4, new Rating(30, 3));
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
// Winners // Winners
self::assertRating($testClass, 21.570, 6.556, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 21.570, 6.556, $newRatingsWinLose->getRating($player1));
@ -492,7 +494,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, new Rating(40, 5)); $team2->addPlayer($player4, new Rating(40, 5));
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 29.698, 7.008, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 29.698, 7.008, $newRatingsWinLose->getRating($player1));
@ -518,7 +520,7 @@ class TrueSkillCalculatorTests
$team1->addPlayer($player1, $gameInfo->getDefaultRating()); $team1->addPlayer($player1, $gameInfo->getDefaultRating());
$team1->addPlayer($player2, $gameInfo->getDefaultRating()); $team1->addPlayer($player2, $gameInfo->getDefaultRating());
$team1->addPlayer($player3, $gameInfo->getDefaultRating()); $team1->addPlayer($player3, $gameInfo->getDefaultRating());
$team1->addPlayer($player4, $gameInfo->getDefaultRating());; $team1->addPlayer($player4, $gameInfo->getDefaultRating());
$player5 = new Player(5); $player5 = new Player(5);
$player6 = new Player(6); $player6 = new Player(6);
@ -533,7 +535,7 @@ class TrueSkillCalculatorTests
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
// Winners // Winners
self::assertRating($testClass, 27.198, 8.059, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 27.198, 8.059, $newRatingsWinLose->getRating($player1));
@ -569,7 +571,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($player4, $gameInfo->getDefaultRating()); $team2->addPlayer($player4, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1]);
// Winners // Winners
self::assertRating($testClass, 25, 7.455, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 25, 7.455, $newRatingsWinLose->getRating($player1));
@ -582,7 +584,6 @@ class TrueSkillCalculatorTests
self::assertMatchQuality($testClass, 0.447, $calculator->calculateMatchQuality($gameInfo, $teams)); self::assertMatchQuality($testClass, 0.447, $calculator->calculateMatchQuality($gameInfo, $teams));
} }
private static function threeTeamsOfOneNotDrawn($testClass, SkillCalculator $calculator) private static function threeTeamsOfOneNotDrawn($testClass, SkillCalculator $calculator)
{ {
$player1 = new Player(1); $player1 = new Player(1);
@ -596,7 +597,7 @@ class TrueSkillCalculatorTests
$team3 = new Team($player3, $gameInfo->getDefaultRating()); $team3 = new Team($player3, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2, $team3); $teams = Teams::concat($team1, $team2, $team3);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2, 3)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 3]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 31.675352419172107, 6.6559853776206905, $player1NewRating); self::assertRating($testClass, 31.675352419172107, 6.6559853776206905, $player1NewRating);
@ -623,7 +624,7 @@ class TrueSkillCalculatorTests
$team3 = new Team($player3, $gameInfo->getDefaultRating()); $team3 = new Team($player3, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2, $team3); $teams = Teams::concat($team1, $team2, $team3);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1, 1)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1, 1]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 25.000, 5.698, $player1NewRating); self::assertRating($testClass, 25.000, 5.698, $player1NewRating);
@ -652,7 +653,7 @@ class TrueSkillCalculatorTests
$teams = Teams::concat($team1, $team2, $team3, $team4); $teams = Teams::concat($team1, $team2, $team3, $team4);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2, 3, 4)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 3, 4]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 33.206680965631264, 6.3481091698077057, $player1NewRating); self::assertRating($testClass, 33.206680965631264, 6.3481091698077057, $player1NewRating);
@ -685,7 +686,7 @@ class TrueSkillCalculatorTests
$team5 = new Team($player5, $gameInfo->getDefaultRating()); $team5 = new Team($player5, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2, $team3, $team4, $team5); $teams = Teams::concat($team1, $team2, $team3, $team4, $team5);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2, 3, 4, 5)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 3, 4, 5]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 34.363135705841188, 6.1361528798112692, $player1NewRating); self::assertRating($testClass, 34.363135705841188, 6.1361528798112692, $player1NewRating);
@ -727,7 +728,7 @@ class TrueSkillCalculatorTests
$team8 = new Team($player8, $gameInfo->getDefaultRating()); $team8 = new Team($player8, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2, $team3, $team4, $team5, $team6, $team7, $team8); $teams = Teams::concat($team1, $team2, $team3, $team4, $team5, $team6, $team7, $team8);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 1, 1, 1, 1, 1, 1, 1)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 1, 1, 1, 1, 1, 1, 1]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 25.000, 4.592, $player1NewRating); self::assertRating($testClass, 25.000, 4.592, $player1NewRating);
@ -779,7 +780,7 @@ class TrueSkillCalculatorTests
$team8 = new Team($player8, new Rating(45, 1)); $team8 = new Team($player8, new Rating(45, 1));
$teams = Teams::concat($team1, $team2, $team3, $team4, $team5, $team6, $team7, $team8); $teams = Teams::concat($team1, $team2, $team3, $team4, $team5, $team6, $team7, $team8);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2, 3, 4, 5, 6, 7, 8)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 3, 4, 5, 6, 7, 8]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 35.135, 4.506, $player1NewRating); self::assertRating($testClass, 35.135, 4.506, $player1NewRating);
@ -854,7 +855,7 @@ class TrueSkillCalculatorTests
$newRatings = $calculator->calculateNewRatings( $newRatings = $calculator->calculateNewRatings(
$gameInfo, $teams, $gameInfo, $teams,
array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)); [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
$player1NewRating = $newRatings->getRating($player1); $player1NewRating = $newRatings->getRating($player1);
self::assertRating($testClass, 40.53945776946920, 5.27581643889050, $player1NewRating); self::assertRating($testClass, 40.53945776946920, 5.27581643889050, $player1NewRating);
@ -935,7 +936,7 @@ class TrueSkillCalculatorTests
$team3->addPlayer($player8, new Rating(30, 2)); $team3->addPlayer($player8, new Rating(30, 2));
$teams = Teams::concat($team1, $team2, $team3); $teams = Teams::concat($team1, $team2, $team3);
$newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2, 2)); $newRatingsWinLose = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2, 2]);
// Winners // Winners
self::assertRating($testClass, 40.877, 3.840, $newRatingsWinLose->getRating($player1)); self::assertRating($testClass, 40.877, 3.840, $newRatingsWinLose->getRating($player1));
@ -969,7 +970,7 @@ class TrueSkillCalculatorTests
$team2->addPlayer($p3, $gameInfo->getDefaultRating()); $team2->addPlayer($p3, $gameInfo->getDefaultRating());
$teams = Teams::concat($team1, $team2); $teams = Teams::concat($team1, $team2);
$newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, [1, 2]);
$p1NewRating = $newRatings->getRating($p1); $p1NewRating = $newRatings->getRating($p1);
$p2NewRating = $newRatings->getRating($p2); $p2NewRating = $newRatings->getRating($p2);
@ -994,4 +995,4 @@ class TrueSkillCalculatorTests
{ {
$testClass->assertEquals($expectedMatchQuality, $actualMatchQuality, '', self::ERROR_TOLERANCE_MATCH_QUALITY); $testClass->assertEquals($expectedMatchQuality, $actualMatchQuality, '', self::ERROR_TOLERANCE_MATCH_QUALITY);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill; <?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase; use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator; use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;
@ -12,4 +14,4 @@ class TwoPlayerTrueSkillCalculatorTest extends TestCase
// We only support two players // We only support two players
TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator); TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator);
} }
} }

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill; <?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase; use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator; use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator;
@ -13,4 +15,4 @@ class TwoTeamTrueSkillCalculatorTest extends TestCase
TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator); TrueSkillCalculatorTests::testAllTwoPlayerScenarios($this, $calculator);
TrueSkillCalculatorTests::testAllTwoTeamScenarios($this, $calculator); TrueSkillCalculatorTests::testAllTwoTeamScenarios($this, $calculator);
} }
} }