Merge branch 'task/more-tiebreaks' into develop

This commit is contained in:
Jeroen De Meerleer 2019-05-30 21:33:33 +02:00
commit f5b0fd024d
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
4 changed files with 235 additions and 23 deletions

17
src/Constants.php Normal file
View File

@ -0,0 +1,17 @@
<?php
namespace JeroenED\Libpairtwo;
use JeroenED\Libpairtwo\Enums\Color;
use JeroenED\Libpairtwo\Enums\Result;
class Constants
{
const Won = [ Result::won, Result::wonforfait, Result::wonbye, Result::wonadjourned ];
const Draw = [ Result::draw, Result::drawadjourned];
const Lost = [ Result::absent, Result::bye, Result::lost, Result::adjourned ];
const NotPlayed = [ Result::bye, Result::wonbye, Result::absent ];
const Black = [ Color::black ];
const White = [ Color::white ];
}

View File

@ -96,4 +96,57 @@ class Player extends PlayerModel
$this->setIds($currentIds); $this->setIds($currentIds);
return $this; 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;
}
/**
* @return float
*/
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;
}
/**
* @return int
*/
public function getPerformance(): int
{
$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);
}
}
} }

View File

@ -9,13 +9,6 @@ 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 ];
private const Draw = [ Result::draw, Result::drawadjourned];
private const Lost = [ Result::absent, Result::bye, Result::lost, Result::adjourned ];
private const NotPlayed = [ Result::bye, Result::wonbye, Result::absent ];
private const Black = [ Color::black ];
private const White = [ Color::white ];
/** /**
* @param Player $player * @param Player $player
@ -43,15 +36,7 @@ abstract class Tiebreaks extends Tournament
*/ */
protected function calculatePoints(Player $player): ?float protected function calculatePoints(Player $player): ?float
{ {
$points = 0; return $player->getPoints();
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;
} }
@ -63,7 +48,7 @@ abstract class Tiebreaks extends Tournament
{ {
$totalwins = 0; $totalwins = 0;
foreach ($player->getPairings() as $pairing) { foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getResult(), self::Won) !== false) { if (array_search($pairing->getResult(), Constants::Won) !== false) {
$totalwins++; $totalwins++;
} }
} }
@ -79,7 +64,7 @@ abstract class Tiebreaks extends Tournament
{ {
$totalwins = 0; $totalwins = 0;
foreach ($player->getPairings() as $pairing) { foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getColor(), self::Black) !== false) { if (array_search($pairing->getColor(), Constants::Black) !== false) {
$totalwins++; $totalwins++;
} }
} }
@ -94,7 +79,7 @@ abstract class Tiebreaks extends Tournament
{ {
$totalwins = 0; $totalwins = 0;
foreach ($player->getPairings() as $pairing) { 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++; $totalwins++;
} }
} }
@ -123,9 +108,9 @@ abstract class Tiebreaks extends Tournament
$totalmatches = 0; $totalmatches = 0;
foreach ($player->getPairings() as $pairing) { foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getOpponent(), $interestingplayers) !== false) { 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; $points = $points + 1;
} elseif (array_search($pairing->getResult(), self::Draw) !== false) { } elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
$points = $points + 0.5; $points = $points + 0.5;
} }
$totalmatches++; $totalmatches++;
@ -137,18 +122,20 @@ abstract class Tiebreaks extends Tournament
return $points; return $points;
} }
/** /**
* @param Player $player * @param Player $player
* @param int $cut
* @return float * @return float
*/ */
protected function calculateAverageRating(Player $player, int $cut = 0) protected function calculateAverageRating(Player $player, int $cut = 0): ?float
{ {
$pairings = $player->getPairings(); $pairings = $player->getPairings();
$totalrating = 0; $totalrating = 0;
$totalopponents = 0; $totalopponents = 0;
$allratings = []; $allratings = [];
foreach ($pairings as $pairing) { 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']; $toadd = $pairing->getOpponent()->getElos()['home'];
if ($toadd != 0) { if ($toadd != 0) {
$allratings[] = $toadd; $allratings[] = $toadd;
@ -159,4 +146,135 @@ abstract class Tiebreaks extends Tournament
$allratings = array_slice($allratings, $cut); $allratings = array_slice($allratings, $cut);
return round(array_sum($allratings) / count($allratings)); return round(array_sum($allratings) / count($allratings));
} }
/**
* @param Player $player
* @param int $cut
* @return float|null
*/
protected function calculateAveragePerformance(Player $player, int $cut = 0): ?float
{
$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
* @return float|null
*/
protected function calculateKoya(Player $player, int $cut = 50): ?float
{
$tiebreak = 0;
foreach ($player->getPairings() as $plkey => $plpairing) {
if (($plpairing->getOpponent()->getNoOfWins() / count($plpairing->getOpponent()->getPairings()) * 100) >= $cut) {
$tiebreak += $plpairing->getOpponent()->getNoOfWins();
}
}
return $tiebreak;
}
/**
* @param Player $player
* @param int $cutlowest
* @param int $cuthighest
* @return float|null
*/
protected function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0): ?float
{
$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;
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateSonneborn(Player $player): ?float
{
$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;
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateKashdan(Player $player): ?float
{
$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;
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateCumulative(Player $player): ?float
{
$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;
}
} }

View File

@ -296,6 +296,30 @@ class Tournament extends Tiebreaks
case Tiebreak::AroCut: case Tiebreak::AroCut:
return $this->calculateAverageRating($player, 1); return $this->calculateAverageRating($player, 1);
break; break;
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;
case Tiebreak::Sonneborn:
return $this->calculateSonneborn($player);
break;
case Tiebreak::Kashdan:
return $this->calculateKashdan($player);
break;
case Tiebreak::Cumulative:
return $this->calculateCumulative($player);
break;
case Tiebreak::Performance:
return $this->calculateAveragePerformance($player);
break;
default: default:
return null; return null;
} }