mirror of
https://github.com/JeroenED/libpairtwo.git
synced 2024-12-22 12:21:22 +01:00
Merge branch 'task/more-tiebreaks' into develop
This commit is contained in:
commit
f5b0fd024d
17
src/Constants.php
Normal file
17
src/Constants.php
Normal 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 ];
|
||||
}
|
@ -96,4 +96,57 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,6 @@ use JeroenED\Libpairtwo\Enums\Result;
|
||||
|
||||
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
|
||||
@ -43,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(), self::Won) !== false) {
|
||||
$points = $points + 1;
|
||||
} elseif (array_search($pairing->getResult(), self::Draw) !== false) {
|
||||
$points = $points + 0.5;
|
||||
}
|
||||
}
|
||||
return $points;
|
||||
return $player->getPoints();
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +48,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 +64,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 +79,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 +108,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++;
|
||||
@ -137,18 +122,20 @@ abstract class Tiebreaks extends Tournament
|
||||
return $points;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
* @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;
|
||||
$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;
|
||||
@ -159,4 +146,135 @@ abstract class Tiebreaks extends Tournament
|
||||
$allratings = array_slice($allratings, $cut);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -296,6 +296,30 @@ class Tournament extends Tiebreaks
|
||||
case Tiebreak::AroCut:
|
||||
return $this->calculateAverageRating($player, 1);
|
||||
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:
|
||||
return null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user