2019-05-28 17:04:53 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace JeroenED\Libpairtwo;
|
|
|
|
|
2019-05-28 18:07:43 +02:00
|
|
|
use JeroenED\Libpairtwo\Enums\Color;
|
2019-05-28 17:04:53 +02:00
|
|
|
use JeroenED\Libpairtwo\Models\Tournament;
|
2019-05-28 18:07:43 +02:00
|
|
|
use JeroenED\Libpairtwo\Enums\Result;
|
2019-05-28 17:04:53 +02:00
|
|
|
|
|
|
|
abstract class Tiebreaks extends Tournament
|
|
|
|
{
|
2019-05-29 15:48:23 +02:00
|
|
|
|
2019-05-28 17:04:53 +02:00
|
|
|
/**
|
2019-05-28 18:07:43 +02:00
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 17:04:53 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculateKeizer(Player $player): ?float
|
2019-05-28 17:04:53 +02:00
|
|
|
{
|
2019-05-29 15:48:23 +02:00
|
|
|
return $player->getBinaryData('ScoreAmerican');
|
2019-05-28 18:07:43 +02:00
|
|
|
}
|
|
|
|
|
2019-05-29 15:48:23 +02:00
|
|
|
|
2019-05-28 18:07:43 +02:00
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 18:07:43 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculateAmerican(Player $player): ?float
|
2019-05-28 18:07:43 +02:00
|
|
|
{
|
2019-05-29 15:48:23 +02:00
|
|
|
return $player->getBinaryData('ScoreAmerican');
|
2019-05-28 18:07:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 18:07:43 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculatePoints(Player $player): ?float
|
2019-05-28 18:07:43 +02:00
|
|
|
{
|
2019-05-30 21:13:14 +02:00
|
|
|
return $player->getPoints();
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|
|
|
|
|
2019-05-28 18:07:43 +02:00
|
|
|
|
2019-05-28 17:04:53 +02:00
|
|
|
/**
|
2019-05-28 18:07:43 +02:00
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 17:04:53 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculateBaumbach(Player $player): ?float
|
2019-05-28 17:04:53 +02:00
|
|
|
{
|
2019-05-28 18:07:43 +02:00
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
2019-05-30 20:54:53 +02:00
|
|
|
if (array_search($pairing->getResult(), Constants::Won) !== false) {
|
2019-05-28 18:07:43 +02:00
|
|
|
$totalwins++;
|
|
|
|
}
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|
2019-05-29 15:48:23 +02:00
|
|
|
return $totalwins;
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|
|
|
|
|
2019-05-29 15:48:23 +02:00
|
|
|
|
2019-05-28 17:04:53 +02:00
|
|
|
/**
|
2019-05-28 18:07:43 +02:00
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 18:07:43 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculateBlackPlayed(Player $player): ?float
|
2019-05-28 18:07:43 +02:00
|
|
|
{
|
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
2019-05-30 20:54:53 +02:00
|
|
|
if (array_search($pairing->getColor(), Constants::Black) !== false) {
|
2019-05-28 18:07:43 +02:00
|
|
|
$totalwins++;
|
|
|
|
}
|
|
|
|
}
|
2019-05-29 15:48:23 +02:00
|
|
|
return $totalwins;
|
2019-05-28 18:07:43 +02:00
|
|
|
}
|
2019-05-29 15:48:23 +02:00
|
|
|
|
2019-05-28 18:07:43 +02:00
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-29 15:48:23 +02:00
|
|
|
* @return float|null
|
2019-05-28 17:04:53 +02:00
|
|
|
*/
|
2019-05-29 15:48:23 +02:00
|
|
|
protected function calculateBlackWin(Player $player): ?float
|
2019-05-28 17:04:53 +02:00
|
|
|
{
|
2019-05-28 18:07:43 +02:00
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
2019-05-30 20:54:53 +02:00
|
|
|
if (array_search($pairing->getColor(), Constants::Black) !== false && array_search($pairing->getResult(), Constants::Won) !== false) {
|
2019-05-28 18:07:43 +02:00
|
|
|
$totalwins++;
|
|
|
|
}
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|
2019-05-29 15:48:23 +02:00
|
|
|
return $totalwins;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
|
|
|
* @param array $opponents
|
|
|
|
* @param int $key
|
|
|
|
* @return float|null
|
|
|
|
*/
|
|
|
|
protected function calculateMutualResult(Player $player, array $opponents, int $key): ?float
|
|
|
|
{
|
|
|
|
$interestingplayers = $opponents;
|
|
|
|
if ($key != 0) {
|
|
|
|
$interestingplayers = [];
|
|
|
|
foreach ($opponents as $opponent) {
|
|
|
|
if (($opponent->getTiebreaks()[$key - 1] == $player->getTiebreaks()[$key - 1]) && ($player != $opponent)) {
|
|
|
|
$interestingplayers[] = $opponent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$points = 0;
|
|
|
|
$totalmatches = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
|
|
|
if (array_search($pairing->getOpponent(), $interestingplayers) !== false) {
|
2019-05-30 20:54:53 +02:00
|
|
|
if (array_search($pairing->getResult(), Constants::Won) !== false) {
|
2019-05-29 15:48:23 +02:00
|
|
|
$points = $points + 1;
|
2019-05-30 20:54:53 +02:00
|
|
|
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
|
2019-05-29 15:48:23 +02:00
|
|
|
$points = $points + 0.5;
|
|
|
|
}
|
|
|
|
$totalmatches++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($totalmatches != count($interestingplayers)) {
|
|
|
|
$points = null;
|
|
|
|
}
|
|
|
|
return $points;
|
|
|
|
}
|
|
|
|
|
2019-05-30 21:30:28 +02:00
|
|
|
|
2019-05-29 17:56:30 +02:00
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-30 21:30:28 +02:00
|
|
|
* @param int $cut
|
2019-05-29 17:56:30 +02:00
|
|
|
* @return float
|
|
|
|
*/
|
2019-05-31 22:45:26 +02:00
|
|
|
protected function calculateAverageRating(Player $player, string $type, int $cut = 0): ?float
|
2019-05-29 17:56:30 +02:00
|
|
|
{
|
2019-05-29 15:48:23 +02:00
|
|
|
$pairings = $player->getPairings();
|
2019-05-30 08:33:52 +02:00
|
|
|
$allratings = [];
|
2019-05-29 15:48:23 +02:00
|
|
|
foreach ($pairings as $pairing) {
|
2019-05-30 20:54:53 +02:00
|
|
|
if (array_search($pairing->getResult(), Constants::NotPlayed) === false) {
|
2019-05-31 22:45:26 +02:00
|
|
|
$toadd = $pairing->getOpponent()->getElo($type);
|
2019-05-29 17:56:30 +02:00
|
|
|
if ($toadd != 0) {
|
2019-05-30 08:33:52 +02:00
|
|
|
$allratings[] = $toadd;
|
2019-05-29 17:56:30 +02:00
|
|
|
}
|
|
|
|
}
|
2019-05-29 15:48:23 +02:00
|
|
|
}
|
2019-05-30 08:33:52 +02:00
|
|
|
sort($allratings);
|
|
|
|
$allratings = array_slice($allratings, $cut);
|
|
|
|
return round(array_sum($allratings) / count($allratings));
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|
2019-05-30 21:07:05 +02:00
|
|
|
|
2019-05-30 21:30:28 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $cut
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:30:28 +02:00
|
|
|
*/
|
2019-05-31 22:45:26 +02:00
|
|
|
protected function calculateAveragePerformance(Player $player, string $type, int $cut = 0): ?float
|
2019-05-30 21:30:28 +02:00
|
|
|
{
|
|
|
|
$pairings = $player->getPairings();
|
|
|
|
$allratings = [];
|
|
|
|
foreach ($pairings as $pairing) {
|
|
|
|
if (array_search($pairing->getResult(), Constants::NotPlayed) === false) {
|
2019-06-01 13:37:50 +02:00
|
|
|
$toadd = $pairing->getOpponent()->getPerformance($type, $this->getNonRatedElo());
|
2019-05-30 21:30:28 +02:00
|
|
|
if ($toadd != 0) {
|
|
|
|
$allratings[] = $toadd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sort($allratings);
|
|
|
|
$allratings = array_slice($allratings, $cut);
|
|
|
|
return round(array_sum($allratings) / count($allratings));
|
|
|
|
}
|
|
|
|
|
2019-05-30 21:33:27 +02:00
|
|
|
|
2019-05-30 21:07:05 +02:00
|
|
|
/**
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $cut
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:07:05 +02:00
|
|
|
*/
|
2019-05-30 21:33:27 +02:00
|
|
|
protected function calculateKoya(Player $player, int $cut = 50): ?float
|
2019-05-30 21:07:05 +02:00
|
|
|
{
|
|
|
|
$tiebreak = 0;
|
2019-05-30 21:16:12 +02:00
|
|
|
foreach ($player->getPairings() as $plkey => $plpairing) {
|
2019-05-30 21:07:05 +02:00
|
|
|
if (($plpairing->getOpponent()->getNoOfWins() / count($plpairing->getOpponent()->getPairings()) * 100) >= $cut) {
|
|
|
|
$tiebreak += $plpairing->getOpponent()->getNoOfWins();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-05-30 21:13:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $cutlowest
|
|
|
|
* @param int $cuthighest
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:13:14 +02:00
|
|
|
*/
|
2019-05-30 21:33:27 +02:00
|
|
|
protected function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0): ?float
|
2019-05-30 21:13:14 +02:00
|
|
|
{
|
|
|
|
$tiebreak = 0;
|
|
|
|
$intpairings = $player->getPairings();
|
|
|
|
|
|
|
|
usort($intpairings, function ($a, $b) {
|
2019-05-31 10:33:17 +02:00
|
|
|
if (is_null($a->getOpponent())) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (is_null($b->getOpponent())) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($b->getOpponent()->getElo('Nation') == $a->getOpponent()->getElo('Nation')) {
|
2019-05-30 21:13:14 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2019-05-31 10:33:17 +02:00
|
|
|
return ($b->getOpponent()->getElo('Nation') > $a->getOpponent()->getElo('Nation')) ? 1 : -1;
|
2019-05-30 21:13:14 +02:00
|
|
|
});
|
|
|
|
|
2019-05-31 15:43:54 +02:00
|
|
|
array_slice($intpairings, $cutlowest);
|
|
|
|
array_slice($intpairings, 0 - $cuthighest);
|
2019-05-30 21:13:14 +02:00
|
|
|
|
2019-05-30 21:16:12 +02:00
|
|
|
foreach ($intpairings as $intkey => $intpairing) {
|
2019-06-01 13:37:50 +02:00
|
|
|
if (!is_null($intpairing->getOpponent())) {
|
|
|
|
$tiebreak += $intpairing->getOpponent()->getPoints();
|
|
|
|
}
|
|
|
|
}
|
2019-05-30 21:13:14 +02:00
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-05-30 21:16:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:16:12 +02:00
|
|
|
*/
|
2019-05-30 21:33:27 +02:00
|
|
|
protected function calculateSonneborn(Player $player): ?float
|
2019-05-30 21:16:12 +02:00
|
|
|
{
|
|
|
|
$tiebreak = 0;
|
|
|
|
foreach ($player->getPairings() as $key => $pairing) {
|
2019-05-31 10:33:17 +02:00
|
|
|
if ($pairing->getOpponent()) {
|
|
|
|
if (array_search($pairing->getResult(), Constants::Won) !== false) {
|
|
|
|
$tiebreak += $pairing->getOpponent()->getPoints();
|
|
|
|
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
|
|
|
|
$tiebreak += $pairing->getOpponent()->getPoints() / 2;
|
|
|
|
}
|
2019-05-30 21:16:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-05-30 21:20:14 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:20:14 +02:00
|
|
|
*/
|
2019-05-30 21:33:27 +02:00
|
|
|
protected function calculateKashdan(Player $player): ?float
|
2019-05-30 21:20:14 +02:00
|
|
|
{
|
|
|
|
$tiebreak = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
|
|
|
$toadd = 0;
|
|
|
|
if (array_search($pairing->getResult(), Constants::Won) !== false) {
|
|
|
|
$toadd = 3;
|
|
|
|
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
|
|
|
|
$toadd = 2;
|
|
|
|
} elseif (array_search($pairing->getResult(), Constants::Lost) !== false) {
|
|
|
|
$toadd = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (array_search(Constants::NotPlayed, $pairing->getResult()) !== false) {
|
|
|
|
$toadd = 0;
|
|
|
|
}
|
|
|
|
$tiebreak += $toadd;
|
|
|
|
}
|
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-05-30 21:25:37 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @param Player $player
|
2019-05-30 21:33:27 +02:00
|
|
|
* @return float|null
|
2019-05-30 21:25:37 +02:00
|
|
|
*/
|
2019-05-30 21:33:27 +02:00
|
|
|
protected function calculateCumulative(Player $player): ?float
|
2019-05-30 21:25:37 +02:00
|
|
|
{
|
|
|
|
$tiebreak = 0;
|
|
|
|
foreach ($player->getPairings() as $pairing) {
|
|
|
|
$toadd = 0;
|
|
|
|
if (array_search($pairing->getResult(), Constants::Won) !== false) {
|
|
|
|
$toadd = 1;
|
|
|
|
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
|
|
|
|
$toadd = 0.5;
|
|
|
|
}
|
|
|
|
$tiebreak += $tiebreak + $toadd;
|
|
|
|
}
|
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-05-28 17:04:53 +02:00
|
|
|
}
|