Working tiebreaks

Also:
* Added mutual result
* Reimplemented points tiebreak
This commit is contained in:
Jeroen De Meerleer 2019-05-29 15:48:23 +02:00
parent 35c4b8524d
commit 526be12303
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
2 changed files with 150 additions and 78 deletions

View File

@ -10,104 +10,139 @@ use JeroenED\Libpairtwo\Enums\Result;
abstract class Tiebreaks extends Tournament abstract class Tiebreaks extends Tournament
{ {
/** private const Won = [ Result::won, Result::wonforfait, Result::wonbye, Result::wonadjourned ];
* @param int $key private const Draw = [ Result::draw, Result::drawadjourned];
* @param Player $player private const Lost = [ Result::absent, Result::bye, Result::lost, Result::adjourned ];
* @return float private const Black = [ Color::black ];
*/ private const White = [ Color::white ];
protected function calculateKeizer(int $key, Player $player): float
{
$currentTiebreaks = $player->getTiebreaks();
$currentTiebreaks[$key] = $player->getBinaryData('ScoreAmerican');
$player->setTiebreaks($currentTiebreaks);
return $currentTiebreaks[$key];
}
/** /**
* @param int $key
* @param Player $player * @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(); return $player->getBinaryData('ScoreAmerican');
$currentTiebreaks[$key] = $player->getBinaryData('ScoreAmerican');
$player->setTiebreaks($currentTiebreaks);
return $currentTiebreaks[$key];
} }
/** /**
* @param int $key
* @param Player $player * @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(); return $player->getBinaryData('ScoreAmerican');
$currentTiebreaks[$key] = $player->getBinaryData('Points');
$player->setTiebreaks($currentTiebreaks);
return $currentTiebreaks[$key];
} }
/** /**
* @param int $key
* @param Player $player * @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; $totalwins = 0;
foreach ($player->getPairings() as $pairing) { foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getResult(), $wonArray) !== false) { if (array_search($pairing->getResult(), self::Won) !== false) {
$totalwins++; $totalwins++;
} }
} }
$currentTiebreaks = $player->getTiebreaks(); return $totalwins;
$currentTiebreaks[$key] = $totalwins; }
$player->setTiebreaks($currentTiebreaks);
return $currentTiebreaks[$key];
/**
* @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 * @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; $totalwins = 0;
foreach ($player->getPairings() as $pairing) { 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++; $totalwins++;
} }
} }
$currentTiebreaks = $player->getTiebreaks(); return $totalwins;
$currentTiebreaks[$key] = $totalwins;
$player->setTiebreaks($currentTiebreaks);
return $currentTiebreaks[$key];
} }
/** /**
* @param int $key
* @param Player $player * @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]; $interestingplayers = $opponents;
$blackArray = [Color::black]; if ($key != 0) {
$totalwins = 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) { foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getColor(), $blackArray) !== false && array_search($pairing->getResult(), $wonArray) !== false) { if (array_search($pairing->getOpponent(), $interestingplayers) !== false) {
$totalwins++; if (array_search($pairing->getResult(), self::Won) !== false) {
$points = $points + 1;
} elseif (array_search($pairing->getResult(), self::Draw) !== false) {
$points = $points + 0.5;
}
$totalmatches++;
} }
} }
$currentTiebreaks = $player->getTiebreaks(); if ($totalmatches != count($interestingplayers)) {
$currentTiebreaks[$key] = $totalwins; $points = null;
$player->setTiebreaks($currentTiebreaks); }
return $currentTiebreaks[$key]; return $points;
}
protected function calculateAverageRating(Player $player) {
$pairings = $player->getPairings();
$totalrating = 0;
$opponents;
foreach ($pairings as $pairing) {
if ($pairing->getOpponent()->getElos['national'])
}
} }
} }

View File

@ -207,54 +207,91 @@ class Tournament extends Tiebreaks
public function getRanking() public function getRanking()
{ {
$players = $this->getPlayers(); $players = $this->getPlayers();
foreach ($this->getTiebreaks() as $tbkey=>$tiebreak) {
usort($players, array($this, "SortTiebreak")); foreach ($players as $pkey => $player) {
$break = $this->calculateTiebreak($tiebreak, $player, $tbkey);
return $players; $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 $a
* @param Player $b * @param Player $b
* @return int * @return \Closure
*/ */
private function sortTiebreak(Player $a, Player $b)
private function sortTiebreak(int $key)
{ {
$result = 0; return function (Player $a, Player $b) use ($key) {
foreach ($this->getTiebreaks() as $key=>$tiebreak) { if (($b->getTiebreaks()[$key] == $a->getTiebreaks()[$key]) || ($a->getTiebreaks()[$key] === false) || ($b->getTiebreaks()[$key] === false)) {
$result = $this->CalculateTiebreak($key, $b, $a) - $this->CalculateTiebreak($key, $a, $b); return 0;
if ($result != 0) {
return $result;
}
} }
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) { switch ($tiebreak) {
case Tiebreak::Keizer: case Tiebreak::Keizer:
return $this->calculateKeizer($key, $player); return $this->calculateKeizer($player);
break; break;
case Tiebreak::American: case Tiebreak::American:
return $this->calculateAmerican($key, $player); return $this->calculateAmerican($player);
break; break;
case Tiebreak::Points: case Tiebreak::Points:
return $this->calculatePoints($key, $player); return $this->calculatePoints($player);
break; break;
case Tiebreak::Baumbach: case Tiebreak::Baumbach:
return $this->calculateBaumbach($key, $player); return $this->calculateBaumbach($player);
break; break;
case Tiebreak::BlackPlayed: case Tiebreak::BlackPlayed:
return $this->calculateBlackPlayed($key, $player); return $this->calculateBlackPlayed($player);
break; break;
case Tiebreak::BlackWin: case Tiebreak::BlackWin:
return $this->calculateBlackWin($key, $player); return $this->calculateBlackWin($player);
break; break;
case Tiebreak::Between:
return $this->calculateMutualResult($player, $this->getPlayers(), $tbkey);
break;
default:
return null;
} }
} }
} }