From 374e339353ce285c9a31f97f1d7402e57af89bf6 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 20:54:53 +0200 Subject: [PATCH 01/11] moving constant arrays to a separate class --- src/Constants.php | 17 +++++++++++++++++ src/Tiebreaks.php | 23 ++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 src/Constants.php diff --git a/src/Constants.php b/src/Constants.php new file mode 100644 index 0000000..4fa0c64 --- /dev/null +++ b/src/Constants.php @@ -0,0 +1,17 @@ +getPairings() as $pairing) { - if (array_search($pairing->getResult(), self::Won) !== false) { + if (array_search($pairing->getResult(), Constants::Won) !== false) { $points = $points + 1; - } elseif (array_search($pairing->getResult(), self::Draw) !== false) { + } elseif (array_search($pairing->getResult(), Constants::Draw) !== false) { $points = $points + 0.5; } } @@ -63,7 +56,7 @@ abstract class Tiebreaks extends Tournament { $totalwins = 0; foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getResult(), self::Won) !== false) { + if (array_search($pairing->getResult(), Constants::Won) !== false) { $totalwins++; } } @@ -79,7 +72,7 @@ abstract class Tiebreaks extends Tournament { $totalwins = 0; foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getColor(), self::Black) !== false) { + if (array_search($pairing->getColor(), Constants::Black) !== false) { $totalwins++; } } @@ -94,7 +87,7 @@ abstract class Tiebreaks extends Tournament { $totalwins = 0; foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getColor(), self::Black) !== false && array_search($pairing->getResult(), Self::Won) !== false) { + if (array_search($pairing->getColor(), Constants::Black) !== false && array_search($pairing->getResult(), Constants::Won) !== false) { $totalwins++; } } @@ -123,9 +116,9 @@ abstract class Tiebreaks extends Tournament $totalmatches = 0; foreach ($player->getPairings() as $pairing) { if (array_search($pairing->getOpponent(), $interestingplayers) !== false) { - if (array_search($pairing->getResult(), self::Won) !== false) { + if (array_search($pairing->getResult(), Constants::Won) !== false) { $points = $points + 1; - } elseif (array_search($pairing->getResult(), self::Draw) !== false) { + } elseif (array_search($pairing->getResult(), Constants::Draw) !== false) { $points = $points + 0.5; } $totalmatches++; @@ -148,7 +141,7 @@ abstract class Tiebreaks extends Tournament $totalopponents = 0; $allratings = []; foreach ($pairings as $pairing) { - if (array_search($pairing->getResult(), self::NotPlayed) === false) { + if (array_search($pairing->getResult(), Constants::NotPlayed) === false) { $toadd = $pairing->getOpponent()->getElos()['home']; if ($toadd != 0) { $allratings[] = $toadd; From 9bf31b7ec503b906033c4c5801f499f1921d31c5 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:01:30 +0200 Subject: [PATCH 02/11] Added some useful functions --- src/Player.php | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/Player.php b/src/Player.php index 8096861..d750870 100644 --- a/src/Player.php +++ b/src/Player.php @@ -96,4 +96,35 @@ class Player extends PlayerModel $this->setIds($currentIds); return $this; } + + /** + * @return int + */ + public function getNoOfWins() + { + $wins = 0; + foreach ($this->getPairings() as $pairing) { + if (array_search($pairing->getResult(), Constants::Won) !== false) { + $wins++; + } + } + return $wins; + } + + /** + * @param Player $player + * @return float|null + */ + public function getPoints(): float + { + $points = 0; + foreach ($this->getPairings() as $pairing) { + if (array_search($pairing->getResult(), Constants::Won) !== false) { + $points = $points + 1; + } elseif (array_search($pairing->getResult(), Constants::Draw) !== false) { + $points = $points + 0.5; + } + } + return $points; + } } From 4672c912981a6a7a6dff3ec81b51f22490b783b8 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:02:31 +0200 Subject: [PATCH 03/11] Moved points tiebreak to return Player::getPoints() --- src/Tiebreaks.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 01fd80c..3f4c8c7 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -36,15 +36,7 @@ abstract class Tiebreaks extends Tournament */ protected function calculatePoints(Player $player): ?float { - $points = 0; - foreach ($player->getPairings() as $pairing) { - if (array_search($pairing->getResult(), Constants::Won) !== false) { - $points = $points + 1; - } elseif (array_search($pairing->getResult(), Constants::Draw) !== false) { - $points = $points + 0.5; - } - } - return $points; + return $player->getPoints(); } From 6d4eeff2340139c2bdf61fa6ce5f8218e2815fe6 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:07:05 +0200 Subject: [PATCH 04/11] Implemented koya tiebreak --- src/Tiebreaks.php | 16 ++++++++++++++++ src/Tournament.php | 3 +++ 2 files changed, 19 insertions(+) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 3f4c8c7..11d7dcc 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -144,4 +144,20 @@ abstract class Tiebreaks extends Tournament $allratings = array_slice($allratings, $cut); return round(array_sum($allratings) / count($allratings)); } + + /** + * @param Player $player + * @param int $cut + * @return int + */ + protected function calculateKoya(Player $player, int $cut = 50) + { + $tiebreak = 0; + foreach ($player->getPairings() as $plkey=>$plpairing) { + if (($plpairing->getOpponent()->getNoOfWins() / count($plpairing->getOpponent()->getPairings()) * 100) >= $cut) { + $tiebreak += $plpairing->getOpponent()->getNoOfWins(); + } + } + return $tiebreak; + } } diff --git a/src/Tournament.php b/src/Tournament.php index 09e1107..1c8eac7 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -296,6 +296,9 @@ class Tournament extends Tiebreaks case Tiebreak::AroCut: return $this->calculateAverageRating($player, 1); break; + case Tiebreak::Koya: + return $this->calculateKoya($player); + break; default: return null; } From 587a7a2e086bf45258776cd7bdf50e84924dedda Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:10:31 +0200 Subject: [PATCH 05/11] Implemented Player::getPerformance() --- src/Player.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Player.php b/src/Player.php index d750870..2bc5b45 100644 --- a/src/Player.php +++ b/src/Player.php @@ -127,4 +127,27 @@ class Player extends PlayerModel } return $points; } + + + /** + * @return float + */ + public function getPerformance() + { + $total = 0; + $opponents = 0; + foreach ($this->getPairings() as $pairing) { + if (array_search($pairing->getResult(), Constants::Notplayed)) { + if (array_search(self::Won, $pairing->getResult())) { + $total += $pairing->getOpponent()->getElo('home') + 400; + } elseif (array_search(self::Lost, $pairing->getResult())) { + $total += $pairing->getOpponent()->getElo('home') - 400; + } elseif (array_search(self::Draw, $pairing->getResult())) { + $total += $pairing->getOpponent()->getElo('home'); + } + $opponents++; + } + return round($total / $opponents); + } + } } From eba962a11c482457ead5dfc1596779da098df0c5 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:13:14 +0200 Subject: [PATCH 06/11] Implemented buchholz --- src/Tiebreaks.php | 30 +++++++++++++++++++++++++++++- src/Tournament.php | 9 +++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 11d7dcc..5f07958 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -36,7 +36,7 @@ abstract class Tiebreaks extends Tournament */ protected function calculatePoints(Player $player): ?float { - return $player->getPoints(); + return $player->getPoints(); } @@ -160,4 +160,32 @@ abstract class Tiebreaks extends Tournament } return $tiebreak; } + + + /** + * @param Player $player + * @param int $cutlowest + * @param int $cuthighest + * @return int + */ + protected function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0) + { + $tiebreak = 0; + $intpairings = $player->getPairings(); + + usort($intpairings, function ($a, $b) { + if ($b->getOpponent()->getElo('home') == $a->getOpponent()->getElo('home')) { + return 0; + } + return ($b->getOpponent()->getElo('home') > $a->getOpponent()->getElo('home')) ? 1 : -1; + }); + + array_splice($intpairings, $cutlowest); + array_splice($intpairings, 0 - $cuthighest); + + foreach ($intpairings as $intkey=>$intpairing) { + $tiebreak += $intpairing->getOpponent()->getPoints(); + } + return $tiebreak; + } } diff --git a/src/Tournament.php b/src/Tournament.php index 1c8eac7..bd735b4 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -299,6 +299,15 @@ class Tournament extends Tiebreaks case Tiebreak::Koya: return $this->calculateKoya($player); break; + case Tiebreak::Buchholz: + return $this->calculateBuchholz($player); + break; + case Tiebreak::BuchholzCut: + return $this->calculateBuchholz($player, 1); + break; + case Tiebreak::BuchholzMed: + return $this->calculateBuchholz($player, 1, 1); + break; default: return null; } From 5128d2762e63dd87538d7a3274b7a26c492fdecd Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:16:12 +0200 Subject: [PATCH 07/11] Implemented Sonneborn-Berger --- src/Tiebreaks.php | 22 ++++++++++++++++++++-- src/Tournament.php | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 5f07958..19259a3 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -153,7 +153,7 @@ abstract class Tiebreaks extends Tournament protected function calculateKoya(Player $player, int $cut = 50) { $tiebreak = 0; - foreach ($player->getPairings() as $plkey=>$plpairing) { + foreach ($player->getPairings() as $plkey => $plpairing) { if (($plpairing->getOpponent()->getNoOfWins() / count($plpairing->getOpponent()->getPairings()) * 100) >= $cut) { $tiebreak += $plpairing->getOpponent()->getNoOfWins(); } @@ -183,9 +183,27 @@ abstract class Tiebreaks extends Tournament array_splice($intpairings, $cutlowest); array_splice($intpairings, 0 - $cuthighest); - foreach ($intpairings as $intkey=>$intpairing) { + foreach ($intpairings as $intkey => $intpairing) { $tiebreak += $intpairing->getOpponent()->getPoints(); } return $tiebreak; } + + + /** + * @param Player $player + * @return float|int|null + */ + protected function calculateSonneborn(Player $player) + { + $tiebreak = 0; + foreach ($player->getPairings() as $key => $pairing) { + 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; + } + } + return $tiebreak; + } } diff --git a/src/Tournament.php b/src/Tournament.php index bd735b4..0d468af 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -308,6 +308,9 @@ class Tournament extends Tiebreaks case Tiebreak::BuchholzMed: return $this->calculateBuchholz($player, 1, 1); break; + case Tiebreak::Sonneborn: + return $this->calculateSonneborn($player); + break; default: return null; } From 07c3a8ad21dacabbd9cd0a10ec548ecf7a141c98 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:20:14 +0200 Subject: [PATCH 08/11] Implemented kashdan --- src/Tiebreaks.php | 26 ++++++++++++++++++++++++++ src/Tournament.php | 3 +++ 2 files changed, 29 insertions(+) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 19259a3..5c308fd 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -206,4 +206,30 @@ abstract class Tiebreaks extends Tournament } return $tiebreak; } + + + /** + * @param Player $player + * @return int + */ + protected function calculateKashdan(Player $player) + { + $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; + } } diff --git a/src/Tournament.php b/src/Tournament.php index 0d468af..2f09001 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -311,6 +311,9 @@ class Tournament extends Tiebreaks case Tiebreak::Sonneborn: return $this->calculateSonneborn($player); break; + case Tiebreak::Kashdan: + return $this->calculateKashdan($player); + break; default: return null; } From 0179e52eb2b66fb336403a117a5c1ec396957472 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:25:37 +0200 Subject: [PATCH 09/11] Added cumulative tiebreak --- src/Tiebreaks.php | 19 +++++++++++++++++++ src/Tournament.php | 3 +++ 2 files changed, 22 insertions(+) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 5c308fd..652b789 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -232,4 +232,23 @@ abstract class Tiebreaks extends Tournament } return $tiebreak; } + + /** + * @param Player $player + * @return float|int + */ + protected function calculateCumulative(Player $player) + { + $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; + } } diff --git a/src/Tournament.php b/src/Tournament.php index 2f09001..9841ec8 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -314,6 +314,9 @@ class Tournament extends Tiebreaks case Tiebreak::Kashdan: return $this->calculateKashdan($player); break; + case Tiebreak::Cumulative: + return $this->calculateCumulative($player); + break; default: return null; } From d57a2d053a07e4984fadc022b76a2e1e8b7ea089 Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:30:28 +0200 Subject: [PATCH 10/11] Added average performance tiebreak --- src/Tiebreaks.php | 25 +++++++++++++++++++++++++ src/Tournament.php | 3 +++ 2 files changed, 28 insertions(+) diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index 652b789..efdb580 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -122,8 +122,10 @@ abstract class Tiebreaks extends Tournament return $points; } + /** * @param Player $player + * @param int $cut * @return float */ protected function calculateAverageRating(Player $player, int $cut = 0) @@ -145,6 +147,29 @@ abstract class Tiebreaks extends Tournament return round(array_sum($allratings) / count($allratings)); } + + /** + * @param Player $player + * @param int $cut + * @return float + */ + protected function calculateAveragePerformance(Player $player, int $cut = 0) + { + $pairings = $player->getPairings(); + $allratings = []; + foreach ($pairings as $pairing) { + if (array_search($pairing->getResult(), Constants::NotPlayed) === false) { + $toadd = $pairing->getOpponent()->getPerformance(); + if ($toadd != 0) { + $allratings[] = $toadd; + } + } + } + sort($allratings); + $allratings = array_slice($allratings, $cut); + return round(array_sum($allratings) / count($allratings)); + } + /** * @param Player $player * @param int $cut diff --git a/src/Tournament.php b/src/Tournament.php index 9841ec8..9d45bf7 100644 --- a/src/Tournament.php +++ b/src/Tournament.php @@ -317,6 +317,9 @@ class Tournament extends Tiebreaks case Tiebreak::Cumulative: return $this->calculateCumulative($player); break; + case Tiebreak::Performance: + return $this->calculateAveragePerformance($player); + break; default: return null; } From 4f5f370c12f6689f9244865af5f20f9288d4b31d Mon Sep 17 00:00:00 2001 From: Jeroen De Meerleer Date: Thu, 30 May 2019 21:33:27 +0200 Subject: [PATCH 11/11] Set correct return types --- src/Player.php | 7 +++---- src/Tiebreaks.php | 27 ++++++++++++++------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Player.php b/src/Player.php index 2bc5b45..173e8d2 100644 --- a/src/Player.php +++ b/src/Player.php @@ -112,8 +112,7 @@ class Player extends PlayerModel } /** - * @param Player $player - * @return float|null + * @return float */ public function getPoints(): float { @@ -130,9 +129,9 @@ class Player extends PlayerModel /** - * @return float + * @return int */ - public function getPerformance() + public function getPerformance(): int { $total = 0; $opponents = 0; diff --git a/src/Tiebreaks.php b/src/Tiebreaks.php index efdb580..234e27c 100644 --- a/src/Tiebreaks.php +++ b/src/Tiebreaks.php @@ -128,7 +128,7 @@ abstract class Tiebreaks extends Tournament * @param int $cut * @return float */ - protected function calculateAverageRating(Player $player, int $cut = 0) + protected function calculateAverageRating(Player $player, int $cut = 0): ?float { $pairings = $player->getPairings(); $totalrating = 0; @@ -151,9 +151,9 @@ abstract class Tiebreaks extends Tournament /** * @param Player $player * @param int $cut - * @return float + * @return float|null */ - protected function calculateAveragePerformance(Player $player, int $cut = 0) + protected function calculateAveragePerformance(Player $player, int $cut = 0): ?float { $pairings = $player->getPairings(); $allratings = []; @@ -170,12 +170,13 @@ abstract class Tiebreaks extends Tournament return round(array_sum($allratings) / count($allratings)); } + /** * @param Player $player * @param int $cut - * @return int + * @return float|null */ - protected function calculateKoya(Player $player, int $cut = 50) + protected function calculateKoya(Player $player, int $cut = 50): ?float { $tiebreak = 0; foreach ($player->getPairings() as $plkey => $plpairing) { @@ -191,9 +192,9 @@ abstract class Tiebreaks extends Tournament * @param Player $player * @param int $cutlowest * @param int $cuthighest - * @return int + * @return float|null */ - protected function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0) + protected function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0): ?float { $tiebreak = 0; $intpairings = $player->getPairings(); @@ -217,9 +218,9 @@ abstract class Tiebreaks extends Tournament /** * @param Player $player - * @return float|int|null + * @return float|null */ - protected function calculateSonneborn(Player $player) + protected function calculateSonneborn(Player $player): ?float { $tiebreak = 0; foreach ($player->getPairings() as $key => $pairing) { @@ -235,9 +236,9 @@ abstract class Tiebreaks extends Tournament /** * @param Player $player - * @return int + * @return float|null */ - protected function calculateKashdan(Player $player) + protected function calculateKashdan(Player $player): ?float { $tiebreak = 0; foreach ($player->getPairings() as $pairing) { @@ -260,9 +261,9 @@ abstract class Tiebreaks extends Tournament /** * @param Player $player - * @return float|int + * @return float|null */ - protected function calculateCumulative(Player $player) + protected function calculateCumulative(Player $player): ?float { $tiebreak = 0; foreach ($player->getPairings() as $pairing) {