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"],
"version": "1.0.0",
"require": {
"php": "^8.1"
"php": "^8.1",
"laravel/pint": "^0.2.3"
},
"require-dev": {
"phpunit/phpunit": "^9.0"

71
composer.lock generated

@ -4,8 +4,75 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "c016c54cac9a371fa358f63b592c310d",
"packages": [],
"content-hash": "27116ea101bf0dd938fe452b46b9c1b7",
"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": [
{
"name": "doctrine/instantiator",

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

@ -1,20 +1,24 @@
<?php namespace DNW\Skills\FactorGraphs;
<?php
namespace DNW\Skills\FactorGraphs;
use Exception;
use DNW\Skills\Guard;
use DNW\Skills\HashMap;
use Exception;
abstract class Factor
{
private $_messages = array();
private $_messages = [];
private $_messageToVariableBinding;
private $_name;
private $_variables = array();
private $_variables = [];
protected function __construct($name)
{
$this->_name = "Factor[" . $name . "]";
$this->_name = 'Factor['.$name.']';
$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
*
* @param $messageIndex
*
* @throws Exception
*/
public function updateMessageIndex($messageIndex)
{
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), "messageIndex");
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), 'messageIndex');
$message = $this->_messages[$messageIndex];
$variable = $this->_messageToVariableBinding->getValue($message);
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
*
* @param $messageIndex
* @return
*
* @throws Exception
*/
public function sendMessageIndex($messageIndex)
{
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), "messageIndex");
Guard::argumentIsValidIndex($messageIndex, count($this->_messages), 'messageIndex');
$message = $this->_messages[$messageIndex];
$variable = $this->_messageToVariableBinding->getValue($message);
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)
{
$this->_messageToVariableBinding->setValue($message, $variable);
$this->_messages[] = $message;
$this->_variables[] = $variable;
return $message;
}

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

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

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs;
<?php
namespace DNW\Skills\FactorGraphs;
class KeyedVariable extends Variable
{

@ -1,8 +1,11 @@
<?php namespace DNW\Skills\FactorGraphs;
<?php
namespace DNW\Skills\FactorGraphs;
class Message
{
private $_name;
private $_value;
public function __construct($value = null, $name = null)
@ -23,6 +26,6 @@ class Message
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
{
@ -9,7 +11,7 @@ abstract class Schedule
$this->_name = $name;
}
public abstract function visit($depth = -1, $maxDepth = 0);
abstract public function visit($depth = -1, $maxDepth = 0);
public function __toString()
{

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\FactorGraphs;
<?php
namespace DNW\Skills\FactorGraphs;
class ScheduleSequence extends Schedule
{

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

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

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

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
use Exception;
@ -12,21 +14,21 @@ class Guard
public static function argumentNotNull($value, $parameterName)
{
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)
{
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)
{
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.
*/
class HashMap
{
private $_hashToValue = array();
private $_hashToKey = array();
private $_hashToValue = [];
private $_hashToKey = [];
public function getValue($key)
{
$hash = self::getHash($key);
$hashValue = $this->_hashToValue[$hash];
return $hashValue;
}
@ -20,18 +24,21 @@ class HashMap
$hash = self::getHash($key);
$this->_hashToKey[$hash] = $key;
$this->_hashToValue[$hash] = $value;
return $this;
}
public function getAllKeys()
{
$keys = array_values($this->_hashToKey);
return $keys;
}
public function getAllValues()
{
$values = array_values($this->_hashToValue);
return $values;
}

@ -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).

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Numerics;
<?php
namespace DNW\Skills\Numerics;
/**
* Basic math functions.
@ -8,10 +10,10 @@
*/
class BasicMath
{
/**
* 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)
*/
public static function square($x)
@ -21,13 +23,15 @@ class BasicMath
/**
* 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.
*/
public static function sum(array $itemsToSum, $callback)
{
$mappedItems = array_map($callback, $itemsToSum);
return array_sum($mappedItems);
}
}

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

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

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

@ -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)
// look a little cleaner
@ -8,13 +10,13 @@ use Exception;
class Range
{
private $_min;
private $_max;
public function __construct($min, $max)
{
if ($min > $max)
{
throw new Exception("min > max");
if ($min > $max) {
throw new Exception('min > max');
}
$this->_min = $min;
@ -50,7 +52,7 @@ class Range
public static function atLeast($minimumValue)
{
return static::create($minimumValue, PHP_INT_MAX );
return static::create($minimumValue, PHP_INT_MAX);
}
public function isInRange($value)

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

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

@ -1,24 +1,29 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
/**
* Represents a comparison between two players.
*
* @internal The actual values for the enum were chosen so that the also correspond to the multiplier for updates to means.
*/
class PairwiseComparison
{
const WIN = 1;
const DRAW = 0;
const LOSE = -1;
public static function getRankFromComparison($comparison)
{
switch ($comparison) {
case PairwiseComparison::WIN:
return array(1, 2);
return [1, 2];
case PairwiseComparison::LOSE:
return array(2, 1);
return [2, 1];
default:
return array(1, 1);
return [1, 1];
}
}
}

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
/**
* Represents a player who has a Rating.
@ -6,26 +8,29 @@
class Player implements ISupportPartialPlay, ISupportPartialUpdate
{
const DEFAULT_PARTIAL_PLAY_PERCENTAGE = 1.0; // = 100% play time
const DEFAULT_PARTIAL_UPDATE_PERCENTAGE = 1.0; // = receive 100% update
private $_Id;
private $_PartialPlayPercentage;
private $_PartialUpdatePercentage;
/**
* Constructs a player.
*
* @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 $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 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 $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,
$partialPlayPercentage = self::DEFAULT_PARTIAL_PLAY_PERCENTAGE,
$partialUpdatePercentage = self::DEFAULT_PARTIAL_UPDATE_PERCENTAGE)
{
// If they don't want to give a player an id, that's ok...
Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, "partialPlayPercentage");
Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, "partialUpdatePercentage");
Guard::argumentInRangeInclusive($partialPlayPercentage, 0.0, 1.0, 'partialPlayPercentage');
Guard::argumentInRangeInclusive($partialUpdatePercentage, 0, 1.0, 'partialUpdatePercentage');
$this->_Id = $id;
$this->_PartialPlayPercentage = $partialPlayPercentage;
$this->_PartialUpdatePercentage = $partialUpdatePercentage;
@ -57,6 +62,6 @@ class Player implements ISupportPartialPlay, ISupportPartialUpdate
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;

@ -1,4 +1,6 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
/**
* 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.
*
* @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 $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.
* @return array
*/
public static function sort(array &$teams, array &$teamRanks)
{
array_multisort($teamRanks, $teams);
return $teams;
}
}

@ -1,4 +1,6 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
// Container for a player's rating.
use DNW\Skills\Numerics\GaussianDistribution;
@ -8,14 +10,17 @@ class Rating
const CONSERVATIVE_STANDARD_DEVIATION_MULTIPLIER = 3;
private $_conservativeStandardDeviationMultiplier;
private $_mean;
private $_standardDeviation;
/**
* 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|int $conservativeStandardDeviationMultiplier optional The number of standardDeviations to subtract from the mean to achieve a conservative rating.
*
* @param float $mean The statistical mean value of the rating (also known as mu).
* @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)
{
@ -51,7 +56,7 @@ class Rating
public function getPartialUpdate(Rating $prior, Rating $fullPosterior, $updatePercentage)
{
$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:
// "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();
$partialPrecisionDifference = $updatePercentage * $precisionDifference;
$precisionMeanDifference = $posteriorGaussian->getPrecisionMean() - $priorGaussian . getPrecisionMean();
$precisionMeanDifference = $posteriorGaussian->getPrecisionMean() - $priorGaussian.getPrecisionMean();
$partialPrecisionMeanDifference = $updatePercentage * $precisionMeanDifference;
$partialPosteriorGaussion = GaussianDistribution::fromPrecisionMean(
@ -73,6 +78,6 @@ class Rating
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
{

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

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

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills;
<?php
namespace DNW\Skills;
use DNW\Skills\Numerics\Range;

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill;
<?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution;

@ -1,9 +1,9 @@
<?php namespace DNW\Skills\TrueSkill;
<?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\GameInfo;
use DNW\Skills\Guard;
use DNW\Skills\ISupportPartialPlay;
use DNW\Skills\ISupportPartialUpdate;
use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Numerics\DiagonalMatrix;
use DNW\Skills\Numerics\Matrix;
@ -29,7 +29,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
array $teams,
array $teamRanks)
{
Guard::argumentNotNull($gameInfo, "gameInfo");
Guard::argumentNotNull($gameInfo, 'gameInfo');
$this->validateTeamCountAndPlayersCountPerTeam($teams);
RankSorter::sort($teams, $teamRanks);
@ -109,7 +109,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// Helper function that gets a list of values for all player ratings
private static function getPlayerRatingValues(array $teamAssignmentsList, $playerRatingFunction)
{
$playerRatingValues = array();
$playerRatingValues = [];
foreach ($teamAssignmentsList as $currentTeam) {
foreach ($currentTeam->getAllRatings() as $currentRating) {
@ -138,7 +138,7 @@ class FactorGraphTrueSkillCalculator extends SkillCalculator
// | -0.75 0.75 |
// | 0.00 -1.00 |
$playerAssignments = array();
$playerAssignments = [];
$totalPreviousPlayers = 0;
$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
// 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) {
$playerAssignments[$currentColumn][] = PartialPlay::getPartialPlayPercentage($currentPlayer);

@ -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\Message;
@ -14,8 +16,9 @@ abstract class GaussianFactor extends Factor
/**
* 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
*/
protected function sendMessageVariable(Message $message, Variable $variable)
@ -24,6 +27,7 @@ abstract class GaussianFactor extends Factor
$messageValue = $message->getValue();
$logZ = GaussianDistribution::logProductNormalization($marginal, $messageValue);
$variable->setValue(GaussianDistribution::multiply($marginal, $messageValue));
return $logZ;
}
@ -33,7 +37,8 @@ abstract class GaussianFactor extends Factor
$binding = parent::createVariableToMessageBindingWithMessage($variable,
new Message(
$newDistribution,
sprintf("message from %s to %s", $this, $variable)));
sprintf('message from %s to %s', $this, $variable)));
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\Variable;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
/**
* 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)
{
parent::__construct(\sprintf("%s > %.2f", $variable, $epsilon));
parent::__construct(\sprintf('%s > %.2f', $variable, $epsilon));
$this->_epsilon = $epsilon;
$this->createVariableToMessageBinding($variable);
}
@ -31,6 +33,7 @@ class GaussianGreaterThanFactor extends GaussianFactor
$messages = $this->getMessages();
$message = $messages[0]->getValue();
$messageFromVariable = GaussianDistribution::divide($marginal, $message);
return -GaussianDistribution::logProductNormalization($messageFromVariable, $message)
+
log(
@ -39,7 +42,6 @@ class GaussianGreaterThanFactor extends GaussianFactor
$messageFromVariable->getStandardDeviation()
)
);
}
protected function updateMessageVariable(Message $message, Variable $variable)

@ -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\Message;
use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\Numerics\GaussianDistribution;
use Exception;
/**
* Connects two variables and adds uncertainty.
@ -17,7 +19,7 @@ class GaussianLikelihoodFactor extends GaussianFactor
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->createVariableToMessageBinding($variable1);
$this->createVariableToMessageBinding($variable2);

@ -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\Variable;
@ -15,10 +17,10 @@ class GaussianPriorFactor extends GaussianFactor
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));
$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);
}
@ -34,6 +36,7 @@ class GaussianPriorFactor extends GaussianFactor
$variable->setValue($newMarginal);
$message->setValue($this->_newMessage);
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\Variable;
use DNW\Skills\Guard;
use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Numerics\GaussianDistribution;
@ -13,18 +15,19 @@ use DNW\Skills\Numerics\GaussianDistribution;
*/
class GaussianWeightedSumFactor extends GaussianFactor
{
private $_variableIndexOrdersForWeights = array();
private $_variableIndexOrdersForWeights = [];
// 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]
private $_weights;
private $_weightsSquared;
public function __construct(Variable $sumVariable, array $variablesToSum, array $variableWeights = null)
{
parent::__construct(self::createName($sumVariable, $variablesToSum, $variableWeights));
$this->_weights = array();
$this->_weightsSquared = array();
$this->_weights = [];
$this->_weightsSquared = [];
// The first weights are a straightforward copy
// 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);
// 0..n-1
$this->_variableIndexOrdersForWeights[0] = array();
$this->_variableIndexOrdersForWeights[0] = [];
for ($i = 0; $i < ($variablesToSumLength + 1); $i++) {
$this->_variableIndexOrdersForWeights[0][] = $i;
}
@ -178,6 +181,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
// Return the difference in the new marginal
$finalDiff = GaussianDistribution::subtract($newMarginal, $marginal0);
return $finalDiff;
}
@ -186,10 +190,10 @@ class GaussianWeightedSumFactor extends GaussianFactor
$allMessages = $this->getMessages();
$allVariables = $this->getVariables();
Guard::argumentIsValidIndex($messageIndex, count($allMessages), "messageIndex");
Guard::argumentIsValidIndex($messageIndex, count($allMessages), 'messageIndex');
$updatedMessages = array();
$updatedVariables = array();
$updatedMessages = [];
$updatedVariables = [];
$indicesToUse = $this->_variableIndexOrdersForWeights[$messageIndex];
@ -211,7 +215,7 @@ class GaussianWeightedSumFactor extends GaussianFactor
private static function createName($sumVariable, $variablesToSum, $weights)
{
// TODO: Perf? Use PHP equivalent of StringBuilder? implode on arrays?
$result = (string)$sumVariable;
$result = (string) $sumVariable;
$result .= ' = ';
$totalVars = count($variablesToSum);
@ -222,15 +226,15 @@ class GaussianWeightedSumFactor extends GaussianFactor
$result .= '-';
}
$absValue = sprintf("%.2f", \abs($weights[$i])); // 0.00?
$absValue = sprintf('%.2f', \abs($weights[$i])); // 0.00?
$result .= $absValue;
$result .= "*[";
$result .= (string)$variablesToSum[$i];
$result .= '*[';
$result .= (string) $variablesToSum[$i];
$result .= ']';
$isLast = ($i == ($totalVars - 1));
if (!$isLast) {
if (! $isLast) {
if ($weights[$i + 1] >= 0) {
$result .= ' + ';
} else {

@ -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\Variable;
use DNW\Skills\Numerics\GaussianDistribution;
use DNW\Skills\TrueSkill\TruncatedGaussianCorrectionFunctions;
/**
* 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)
{
parent::__construct(sprintf("%s <= %.2f", $variable, $epsilon));
parent::__construct(sprintf('%s <= %.2f', $variable, $epsilon));
$this->_epsilon = $epsilon;
$this->createVariableToMessageBinding($variable);
}
@ -57,7 +59,7 @@ class GaussianWithinFactor extends GaussianFactor
$denominator = 1.0 - TruncatedGaussianCorrectionFunctions::wWithinMargin($dOnSqrtC, $epsilonTimesSqrtC);
$newPrecision = $c / $denominator;
$newPrecisionMean = ( $d +
$newPrecisionMean = ($d +
$sqrtC *
TruncatedGaussianCorrectionFunctions::vWithinMargin($dOnSqrtC, $epsilonTimesSqrtC)
) / $denominator;

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

@ -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\PartialPlay;
use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
@ -26,7 +26,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
// REVIEW: Does it make sense to have groups of one?
$outputVariablesGroups = &$this->getOutputVariablesGroups();
$outputVariablesGroups[] = array($teamPerformance);
$outputVariablesGroups[] = [$teamPerformance];
}
}
@ -37,10 +37,11 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$sequence = $this->scheduleSequence(
array_map(
function ($weightedSumFactor) {
return new ScheduleStep("Perf to Team Perf Step", $weightedSumFactor, 0);
return new ScheduleStep('Perf to Team Perf Step', $weightedSumFactor, 0);
},
$localFactors),
"all player perf to team perf schedule");
'all player perf to team perf schedule');
return $sequence;
}
@ -49,6 +50,7 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$weights = array_map(
function ($v) {
$player = $v->getKey();
return PartialPlay::getPartialPlayPercentage($player);
},
$teamMembers);
@ -57,32 +59,33 @@ class PlayerPerformancesToTeamPerformancesLayer extends TrueSkillFactorGraphLaye
$sumVariable,
$teamMembers,
$weights);
}
public function createPosteriorSchedule()
{
$allFactors = array();
$allFactors = [];
$localFactors = $this->getLocalFactors();
foreach ($localFactors as $currentFactor) {
$localCurrentFactor = $currentFactor;
$numberOfMessages = $localCurrentFactor->getNumberOfMessages();
for ($currentIteration = 1; $currentIteration < $numberOfMessages; $currentIteration++) {
$allFactors[] = new ScheduleStep("team sum perf @" . $currentIteration,
$allFactors[] = new ScheduleStep('team sum perf @'.$currentIteration,
$localCurrentFactor, $currentIteration);
}
}
return $this->scheduleSequence($allFactors, "all of the team's sum iterations");
}
private function createOutputVariable($team)
{
$memberNames = array_map(function ($currentPlayer) {
return (string)($currentPlayer->getKey());
return (string) ($currentPlayer->getKey());
}, $team);
$teamMemberNames = \join(", ", $memberNames);
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team[" . $teamMemberNames . "]'s performance");
$teamMemberNames = \implode(', ', $memberNames);
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team['.$teamMemberNames."]'s performance");
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\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\TrueSkillFactorGraph;
// We intentionally have no Posterior schedule since the only purpose here is to
// start the process.
@ -24,7 +26,7 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
$teams = $this->_teams;
foreach ($teams as $currentTeam) {
$localCurrentTeam = $currentTeam;
$currentTeamSkills = array();
$currentTeamSkills = [];
$currentTeamAllPlayers = $localCurrentTeam->getAllPlayers();
foreach ($currentTeamAllPlayers as $currentTeamPlayer) {
@ -44,13 +46,14 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
public function createPriorSchedule()
{
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function ($prior) {
return new ScheduleStep("Prior to Skill Step", $prior, 0);
return new ScheduleStep('Prior to Skill Step', $prior, 0);
},
$localFactors),
"All priors");
'All priors');
}
private function createPriorFactor($player, Rating $priorRating, Variable $skillsVariable)
@ -67,7 +70,8 @@ class PlayerPriorValuesToSkillsLayer extends TrueSkillFactorGraphLayer
{
$parentFactorGraph = $this->getParentFactorGraph();
$variableFactory = $parentFactorGraph->getVariableFactory();
$skillOutputVariable = $variableFactory->createKeyedVariable($key, $key . "'s skill");
$skillOutputVariable = $variableFactory->createKeyedVariable($key, $key."'s skill");
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\ScheduleStep;
use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianLikelihoodFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
{
@ -19,7 +21,7 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
$outputVariablesGroups = &$this->getOutputVariablesGroups();
foreach ($inputVariablesGroups as $currentTeam) {
$currentTeamPlayerPerformances = array();
$currentTeamPlayerPerformances = [];
foreach ($currentTeam as $playerSkillVariable) {
$localPlayerSkillVariable = $playerSkillVariable;
@ -45,31 +47,34 @@ class PlayerSkillsToPerformancesLayer extends TrueSkillFactorGraphLayer
private function createOutputVariable($key)
{
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key . "'s performance");
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createKeyedVariable($key, $key."'s performance");
return $outputVariable;
}
public function createPriorSchedule()
{
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function ($likelihood) {
return new ScheduleStep("Skill to Perf step", $likelihood, 0);
return new ScheduleStep('Skill to Perf step', $likelihood, 0);
},
$localFactors),
"All skill to performance sending");
'All skill to performance sending');
}
public function createPosteriorSchedule()
{
$localFactors = $this->getLocalFactors();
return $this->scheduleSequence(
array_map(
function ($likelihood) {
return new ScheduleStep("name", $likelihood, 1);
return new ScheduleStep('name', $likelihood, 1);
},
$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\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianGreaterThanFactor;
use DNW\Skills\TrueSkill\Factors\GaussianWithinFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class TeamDifferencesComparisonLayer extends TrueSkillFactorGraphLayer
{
private $_epsilon;
private $_teamRanks;
public function __construct(TrueSkillFactorGraph $parentGraph, array $teamRanks)

@ -1,8 +1,10 @@
<?php namespace DNW\Skills\TrueSkill\Layers;
<?php
namespace DNW\Skills\TrueSkill\Layers;
use DNW\Skills\FactorGraphs\Variable;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
use DNW\Skills\TrueSkill\Factors\GaussianWeightedSumFactor;
use DNW\Skills\TrueSkill\TrueSkillFactorGraph;
class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorGraphLayer
{
@ -17,8 +19,7 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
$inputVariablesGroupsCount = count($inputVariablesGroups);
$outputVariablesGroup = &$this->getOutputVariablesGroups();
for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++)
{
for ($i = 0; $i < $inputVariablesGroupsCount - 1; $i++) {
$strongerTeam = $inputVariablesGroups[$i][0];
$weakerTeam = $inputVariablesGroups[$i + 1][0];
@ -27,7 +28,7 @@ class TeamPerformancesToTeamPerformanceDifferencesLayer extends TrueSkillFactorG
$this->addLayerFactor($newDifferencesFactor);
// 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 $output)
{
$teams = array($strongerTeam, $weakerTeam);
$weights = array(1.0, -1.0);
$teams = [$strongerTeam, $weakerTeam];
$weights = [1.0, -1.0];
return new GaussianWeightedSumFactor($output, $teams, $weights);
}
private function createOutputVariable()
{
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable("Team performance difference");
$outputVariable = $this->getParentFactorGraph()->getVariableFactory()->createBasicVariable('Team performance difference');
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\TrueSkill\TrueSkillFactorGraph;

@ -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\FactorList;
use DNW\Skills\FactorGraphs\ScheduleSequence;
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\PlayerPerformancesToTeamPerformancesLayer;
use DNW\Skills\TrueSkill\Layers\PlayerPriorValuesToSkillsLayer;
@ -18,7 +20,9 @@ use DNW\Skills\TrueSkill\Layers\TeamPerformancesToTeamPerformanceDifferencesLaye
class TrueSkillFactorGraph extends FactorGraph
{
private $_gameInfo;
private $_layers;
private $_priorLayer;
public function __construct(GameInfo $gameInfo, array $teams, array $teamRanks)
@ -31,15 +35,15 @@ class TrueSkillFactorGraph extends FactorGraph
});
$this->setVariableFactory($newFactory);
$this->_layers = array(
$this->_layers = [
$this->_priorLayer,
new PlayerSkillsToPerformancesLayer($this),
new PlayerPerformancesToTeamPerformancesLayer($this),
new IteratedTeamDifferencesInnerLayer(
$this,
new TeamPerformancesToTeamPerformanceDifferencesLayer($this),
new TeamDifferencesComparisonLayer($this, $teamRanks))
);
new TeamDifferencesComparisonLayer($this, $teamRanks)),
];
}
public function getGameInfo()
@ -83,12 +87,13 @@ class TrueSkillFactorGraph extends FactorGraph
}
$logZ = $factorList->getLogNormalization();
return exp($logZ);
}
private function createFullSchedule()
{
$fullSchedule = array();
$fullSchedule = [];
$layers = $this->_layers;
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()

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\TrueSkill;
<?php
namespace DNW\Skills\TrueSkill;
use DNW\Skills\Numerics\GaussianDistribution;
@ -13,7 +15,7 @@ class TruncatedGaussianCorrectionFunctions
* correction of a single-sided truncated Gaussian with unit variance."
*
* @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
* @return float
*/
@ -57,10 +59,12 @@ class TruncatedGaussianCorrectionFunctions
if ($teamPerformanceDifference < 0.0) {
return 1.0;
}
return 0.0;
}
$vWin = self::vExceedsMargin($teamPerformanceDifference, $drawMargin);
return $vWin * ($vWin + $teamPerformanceDifference - $drawMargin);
}

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\Numerics;
<?php
namespace DNW\Skills\Tests\Numerics;
use DNW\Skills\Numerics\BasicMath;
use DNW\Skills\Tests\TestCase;

@ -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\GaussianDistribution;

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests;
<?php
namespace DNW\Skills\Tests;
use DNW\Skills\RankSorter;
@ -6,13 +8,13 @@ class RankSorterTest extends TestCase
{
public function testSort()
{
$team1 = array("a" => 1, "b" => 2);
$team2 = array("c" => 3, "d" => 4);
$team3 = array("e" => 5, "f" => 6);
$team1 = ['a' => 1, 'b' => 2];
$team2 = ['c' => 3, 'd' => 4];
$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);

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests;
<?php
namespace DNW\Skills\Tests;
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\TrueSkill\DrawMargin;

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill;
<?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\FactorGraphTrueSkillCalculator;

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

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill;
<?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\TwoPlayerTrueSkillCalculator;

@ -1,4 +1,6 @@
<?php namespace DNW\Skills\Tests\TrueSkill;
<?php
namespace DNW\Skills\Tests\TrueSkill;
use DNW\Skills\Tests\TestCase;
use DNW\Skills\TrueSkill\TwoTeamTrueSkillCalculator;