diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 0c88693..f5a1e0c 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -10,104 +10,139 @@ use JeroenED\Libpairtwo\Enums\Result; abstract class Tiebreaks extends Tournament { - /** - * @param int $key - * @param Player $player - * @return float - */ - protected function calculateKeizer(int $key, Player $player): float - { - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $player->getBinaryData('ScoreAmerican'); - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; - } + private const Won = [ Result::won, Result::wonforfait, Result::wonbye, Result::wonadjourned ]; + private const Draw = [ Result::draw, Result::drawadjourned]; + private const Lost = [ Result::absent, Result::bye, Result::lost, Result::adjourned ]; + private const Black = [ Color::black ]; + private const White = [ Color::white ]; + /** - * @param int $key * @param Player $player - * @return float + * @return float|null */ - protected function calculateAmerican(int $key, Player $player): float + protected function calculateKeizer(Player $player): ?float { - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $player->getBinaryData('ScoreAmerican'); - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; + return $player->getBinaryData('ScoreAmerican'); } /** - * @param int $key * @param Player $player - * @return float + * @return float|null */ - protected function calculatePoints(int $key, Player $player): float + protected function calculateAmerican(Player $player): ?float { - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $player->getBinaryData('Points'); - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; + return $player->getBinaryData('ScoreAmerican'); } /** - * @param int $key * @param Player $player - * @return float + * @return float|null */ - protected function calculateBaumbach(int $key, Player $player): float + protected function calculatePoints(Player $player): ?float + { + $points = 0; + foreach ($player->getPairings() as $pairing) { + if (array_search($pairing->getResult(), self::Won) !== false) { + $points = $points + 1; + } elseif (array_search($pairing->getResult(), self::Draw) !== false) { + $points = $points + 0.5; + } + } + return $points; + } + + + /** + * @param Player $player + * @return float|null + */ + protected function calculateBaumbach(Player $player): ?float { - $wonArray = [Result::won, Result::wonadjourned, Result::wonbye, Result::wonforfait]; $totalwins = 0; foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getResult(), $wonArray) !== false) { + if (array_search($pairing->getResult(), self::Won) !== false) { $totalwins++; } } - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $totalwins; - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; + return $totalwins; + } + + + /** + * @param Player $player + * @return float|null + */ + protected function calculateBlackPlayed(Player $player): ?float + { + $totalwins = 0; + foreach ($player->getPairings() as $pairing) { + if (array_search($pairing->getColor(), self::Black) !== false) { + $totalwins++; + } + } + return $totalwins; } /** - * @param int $key * @param Player $player - * @return float + * @return float|null */ - protected function calculateBlackPlayed(int $key, Player $player): float + protected function calculateBlackWin(Player $player): ?float { - $blackArray = [Color::black]; $totalwins = 0; foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getColor(), $blackArray) !== false) { + if (array_search($pairing->getColor(), self::Black) !== false && array_search($pairing->getResult(), Self::Won) !== false) { $totalwins++; } } - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $totalwins; - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; + return $totalwins; } + + /** - * @param int $key * @param Player $player - * @return float + * @param array $opponents + * @param int $key + * @return float|null */ - protected function calculateBlackWin(int $key, Player $player): float + protected function calculateMutualResult(Player $player, array $opponents, int $key): ?float { - $wonArray = [Result::won, Result::wonadjourned, Result::wonbye, Result::wonforfait]; - $blackArray = [Color::black]; - $totalwins = 0; - foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getColor(), $blackArray) !== false && array_search($pairing->getResult(), $wonArray) !== false) { - $totalwins++; + $interestingplayers = $opponents; + if ($key != 0) { + $interestingplayers = []; + foreach ($opponents as $opponent) { + if (($opponent->getTiebreaks()[$key - 1] == $player->getTiebreaks()[$key - 1]) && ($player != $opponent)) { + $interestingplayers[] = $opponent; + } } } - $currentTiebreaks = $player->getTiebreaks(); - $currentTiebreaks[$key] = $totalwins; - $player->setTiebreaks($currentTiebreaks); - return $currentTiebreaks[$key]; + $points = 0; + $totalmatches = 0; + foreach ($player->getPairings() as $pairing) { + if (array_search($pairing->getOpponent(), $interestingplayers) !== false) { + if (array_search($pairing->getResult(), self::Won) !== false) { + $points = $points + 1; + } elseif (array_search($pairing->getResult(), self::Draw) !== false) { + $points = $points + 0.5; + } + $totalmatches++; + } + } + if ($totalmatches != count($interestingplayers)) { + $points = null; + } + return $points; + } + + protected function calculateAverageRating(Player $player) { + $pairings = $player->getPairings(); + $totalrating = 0; + $opponents; + foreach ($pairings as $pairing) { + if ($pairing->getOpponent()->getElos['national']) + } } } diff --git a/src/Tournament.php b/src/Tournament.php index b0d696d..b106839 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -207,54 +207,91 @@ class Tournament extends Tiebreaks public function getRanking() { $players = $this->getPlayers(); - - usort($players, array($this, "SortTiebreak")); - - return $players; + foreach ($this->getTiebreaks() as $tbkey=>$tiebreak) { + foreach ($players as $pkey => $player) { + $break = $this->calculateTiebreak($tiebreak, $player, $tbkey); + $tiebreaks = $player->getTiebreaks(); + $tiebreaks[$tbkey] = $break; + $player->setTiebreaks($tiebreaks); + $this->updatePlayer($pkey, $player); + } + } + $sortedplayers[0] = $players; + foreach ($this->getTiebreaks() as $tbkey=>$tiebreak) { + $newgroupkey = 0; + $tosortplayers = $sortedplayers; + $sortedplayers = []; + foreach ($tosortplayers as $groupkey=>$sortedplayerselem) { + usort($tosortplayers[$groupkey], $this->SortTiebreak($tbkey)); + foreach ($tosortplayers[$groupkey] as $playerkey => $player) { + if (!is_null($player->getTiebreaks()[$tbkey])) { + if ($playerkey != 0) { + $newgroupkey++; + if ($player->getTiebreaks()[$tbkey] == $tosortplayers[$groupkey][$playerkey - 1]->getTiebreaks()[$tbkey]) { + $newgroupkey--; + } + } + } + $sortedplayers[$newgroupkey][] = $player; + } + $newgroupkey++; + } + } + $finalarray = []; + foreach ($sortedplayers as $sort1) { + foreach ($sort1 as $player) { + $finalarray[] = $player; + } + } + return $finalarray; } /** * @param Player $a * @param Player $b - * @return int + * @return \Closure */ - private function sortTiebreak(Player $a, Player $b) + + private function sortTiebreak(int $key) { - $result = 0; - foreach ($this->getTiebreaks() as $key=>$tiebreak) { - $result = $this->CalculateTiebreak($key, $b, $a) - $this->CalculateTiebreak($key, $a, $b); - if ($result != 0) { - return $result; + return function (Player $a, Player $b) use ($key) { + if (($b->getTiebreaks()[$key] == $a->getTiebreaks()[$key]) || ($a->getTiebreaks()[$key] === false) || ($b->getTiebreaks()[$key] === false)) { + return 0; } - } + return ($b->getTiebreaks()[$key] > $a->getTiebreaks()[$key]) ? +1 : -1; + }; } /** - * @return float + * @return float|bool */ - private function calculateTiebreak(int $key, Player $player, Player $opponent): float + private function calculateTiebreak(Tiebreak $tiebreak, Player $player, int $tbkey = 0): ?float { - $tiebreak = $this->getTiebreaks()[$key]; switch ($tiebreak) { case Tiebreak::Keizer: - return $this->calculateKeizer($key, $player); + return $this->calculateKeizer($player); break; case Tiebreak::American: - return $this->calculateAmerican($key, $player); + return $this->calculateAmerican($player); break; case Tiebreak::Points: - return $this->calculatePoints($key, $player); + return $this->calculatePoints($player); break; case Tiebreak::Baumbach: - return $this->calculateBaumbach($key, $player); + return $this->calculateBaumbach($player); break; case Tiebreak::BlackPlayed: - return $this->calculateBlackPlayed($key, $player); + return $this->calculateBlackPlayed($player); break; case Tiebreak::BlackWin: - return $this->calculateBlackWin($key, $player); + return $this->calculateBlackWin($player); break; + case Tiebreak::Between: + return $this->calculateMutualResult($player, $this->getPlayers(), $tbkey); + break; + default: + return null; } } }