function updateStats($time, $team1players, $team2players, $scores, $enableLogging = true) { $scores = explode(',', $scores); if (count($scores) == 2 && $scores[0] == $scores[1]) { return 'Draws are not supported.'; } $team1players = explode(',', $team1players); if (count($team1players) == 2) { if ($team1players[0] == 0) { $team1players = array($team1players[1]); } elseif ($team1players[1] == 0) { $team1players = array($team1players[0]); } } $team2players = explode(',', $team2players); if (count($team2players) == 2) { if ($team2players[0] == 0) { $team2players = array($team2players[1]); } elseif ($team2players[1] == 0) { $team2players = array($team2players[0]); } } if ($enableLogging) { file_put_contents('games.log', $time . "\t" . join(',', $team1players) . "\t" . join(',', $team2players) . "\t" . join(',', $scores) . "\n", FILE_APPEND); } $gameInfo = new GameInfo(); $ratings = loadRatings(); $team1 = new Team(); foreach ($team1players as $playerId) { $player = new Player($playerId); $team1->addPlayer($player, $ratings[$playerId]); } $team2 = new Team(); foreach ($team2players as $playerId) { $player = new Player($playerId); $team2->addPlayer($player, $ratings[$playerId]); } $teams = Teams::concat($team1, $team2); $calculator = new TwoTeamTrueSkillCalculator(); $winner = count($scores) == 1 ? $scores : ($scores[0] > $scores[1] ? 1 : 2); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, $winner == 1 ? array(1, 2) : array(2, 1)); foreach ($newRatings->getAllPlayers() as $player) { $rating = $newRatings->getRating($player); $ratings[$player->getId()] = $rating; } $stats = array(); foreach ($ratings as $playerId => $rating) { $stats[] = $playerId . "\t" . $rating->getMean() . "\t" . $rating->getStandardDeviation(); file_put_contents('players.stats', $time . "\t" . $playerId . "\t" . $rating->getConservativeRating() . "\n", FILE_APPEND); } file_put_contents('games.stats', join("\n", $stats)); return 'OK'; }
private static function updatePlayerRatings(GameInfo $gameInfo, RatingContainer &$newPlayerRatings, Team $selfTeam, Team $otherTeam, $selfToOtherTeamComparison) { $drawMargin = DrawMargin::getDrawMarginFromDrawProbability($gameInfo->getDrawProbability(), $gameInfo->getBeta()); $betaSquared = square($gameInfo->getBeta()); $tauSquared = square($gameInfo->getDynamicsFactor()); $totalPlayers = $selfTeam->count() + $otherTeam->count(); $meanGetter = function ($currentRating) { return $currentRating->getMean(); }; $selfMeanSum = sum($selfTeam->getAllRatings(), $meanGetter); $otherTeamMeanSum = sum($otherTeam->getAllRatings(), $meanGetter); $varianceGetter = function ($currentRating) { return square($currentRating->getStandardDeviation()); }; $c = sqrt(sum($selfTeam->getAllRatings(), $varianceGetter) + sum($otherTeam->getAllRatings(), $varianceGetter) + $totalPlayers * $betaSquared); $winningMean = $selfMeanSum; $losingMean = $otherTeamMeanSum; switch ($selfToOtherTeamComparison) { case PairwiseComparison::WIN: case PairwiseComparison::DRAW: // NOP break; case PairwiseComparison::LOSE: $winningMean = $otherTeamMeanSum; $losingMean = $selfMeanSum; break; } $meanDelta = $winningMean - $losingMean; if ($selfToOtherTeamComparison != PairwiseComparison::DRAW) { // non-draw case $v = TruncatedGaussianCorrectionFunctions::vExceedsMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wExceedsMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = (int) $selfToOtherTeamComparison; } else { // assume draw $v = TruncatedGaussianCorrectionFunctions::vWithinMarginScaled($meanDelta, $drawMargin, $c); $w = TruncatedGaussianCorrectionFunctions::wWithinMarginScaled($meanDelta, $drawMargin, $c); $rankMultiplier = 1; } $selfTeamAllPlayers =& $selfTeam->getAllPlayers(); foreach ($selfTeamAllPlayers as &$selfTeamCurrentPlayer) { $localSelfTeamCurrentPlayer =& $selfTeamCurrentPlayer; $previousPlayerRating = $selfTeam->getRating($localSelfTeamCurrentPlayer); $meanMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / $c; $stdDevMultiplier = (square($previousPlayerRating->getStandardDeviation()) + $tauSquared) / square($c); $playerMeanDelta = $rankMultiplier * $meanMultiplier * $v; $newMean = $previousPlayerRating->getMean() + $playerMeanDelta; $newStdDev = sqrt((square($previousPlayerRating->getStandardDeviation()) + $tauSquared) * (1 - $w * $stdDevMultiplier)); $newPlayerRatings->setRating($localSelfTeamCurrentPlayer, new Rating($newMean, $newStdDev)); } }
function matchScore($team1players, $team2players, $ratings) { $team1 = new Team(); foreach ($team1players as $playerId) { $player = new Player($playerId); $team1->addPlayer($player, $ratings[$playerId]); } $team2 = new Team(); foreach ($team2players as $playerId) { $player = new Player($playerId); $team2->addPlayer($player, $ratings[$playerId]); } $teams = array($team1, $team2); $gameInfo = new GameInfo(); $calculator = new TwoTeamTrueSkillCalculator(); return $calculator->calculateMatchQuality($gameInfo, $teams); }
private static function oneOnTwoBalancedPartialPlay($testClass, SkillCalculator $calculator) { $gameInfo = new GameInfo(); $p1 = new Player(1); $team1 = new Team($p1, $gameInfo->getDefaultRating()); $p2 = new Player(2, 0.0); $p3 = new Player(3, 1.0); $team2 = new Team(); $team2->addPlayer($p2, $gameInfo->getDefaultRating()); $team2->addPlayer($p3, $gameInfo->getDefaultRating()); $teams = Teams::concat($team1, $team2); $newRatings = $calculator->calculateNewRatings($gameInfo, $teams, array(1, 2)); $p1NewRating = $newRatings->getRating($p1); $p2NewRating = $newRatings->getRating($p2); $p3NewRating = $newRatings->getRating($p3); // This should be roughly the same as a 1 v 1 self::assertRating($testClass, 29.39648040436841, 7.1713980703143205, $p1NewRating); self::assertRating($testClass, 24.999560351959563, 8.333749978770932, $p2NewRating); self::assertRating($testClass, 20.603519595631585, 7.1713980703143205, $p3NewRating); $matchQuality = $calculator->calculateMatchQuality($gameInfo, $teams); self::assertMatchQuality($testClass, 0.44721358745011336, $matchQuality); }