libpairtwo/src/Tournament.php

261 lines
6.6 KiB
PHP
Raw Normal View History

2019-02-01 15:53:39 +01:00
<?php
/**
* Created by PhpStorm.
* User: jeroen
* Date: 1/02/19
* Time: 11:18
*/
namespace JeroenED\Libpairtwo;
use JeroenED\Libpairtwo\Enums\Tiebreak;
use JeroenED\Libpairtwo\Enums\Color;
2019-02-01 15:53:39 +01:00
2019-05-28 17:04:53 +02:00
class Tournament extends Tiebreaks
2019-02-01 15:53:39 +01:00
{
/**
2019-03-20 17:33:09 +01:00
* Gets a player by its ID
*
2019-02-11 17:54:50 +01:00
* @param integer $id
2019-02-01 15:53:39 +01:00
* @return Player
*/
2019-02-11 17:54:50 +01:00
public function getPlayerById(int $id)
2019-02-01 15:53:39 +01:00
{
return $this->GetPlayers()[$id];
}
/**
2019-03-20 17:33:09 +01:00
* Adds a player
*
2019-02-01 15:53:39 +01:00
* @param Player $Player
*/
public function addPlayer(Player $Player)
{
$newArray = $this->GetPlayers();
$newArray[] = $Player;
$this->setPlayers($newArray);
}
2019-02-01 17:02:33 +01:00
/**
2019-03-20 17:33:09 +01:00
* Updates player on id to the given Player object
*
2019-02-11 17:54:50 +01:00
* @param int $id
2019-02-01 17:02:33 +01:00
* @param Player $player
*/
2019-02-11 17:54:50 +01:00
public function updatePlayer(int $id, Player $player)
2019-02-01 17:02:33 +01:00
{
$newArray = $this->GetPlayers();
$newArray[$id] = $player;
$this->setPlayers($newArray);
}
/**
* Adds a Tiebreak
*
* @param Tiebreak $tiebreak
*/
public function addTiebreak(Tiebreak $tiebreak)
{
$newArray = $this->getTiebreaks();
$newArray[] = $tiebreak;
$this->setTiebreaks($newArray);
}
/**
2019-03-20 17:33:09 +01:00
* Adds a round with given Round object
*
* @param Round $round
*/
public function addRound(Round $round)
{
$newArray = $this->getRounds();
$newArray[$round->getRoundNo()] = $round;
$this->setRounds($newArray);
}
/**
2019-03-20 17:33:09 +01:00
* Gets a round by its number.
*
* @param int $roundNo
* @return Round
*/
public function getRoundByNo(int $roundNo): Round
{
return $this->getRounds()[$roundNo];
}
2019-02-11 16:43:36 +01:00
/**
2019-03-20 17:33:09 +01:00
* Adds a pairing to the tournament
*
2019-02-11 16:43:36 +01:00
* @param Pairing $pairing
*/
public function addPairing(Pairing $pairing)
{
$newArray = $this->GetPairings();
$newArray[] = $pairing;
$this->setPairings($newArray);
}
/**
2019-03-20 17:33:09 +01:00
* Converts pairings into games with a black and white player
*/
public function pairingsToRounds(): void
{
2019-04-20 16:55:39 +02:00
/** @var Pairing[] $pairings */
$pairings = $this->getPairings();
2019-03-20 12:46:46 +01:00
/** @var Pairing[] */
$cache = array();
foreach ($pairings as $pairing) {
2019-04-20 16:55:39 +02:00
// Add pairing to player
$pairing->getPlayer()->addPairing($pairing);
$round = $pairing->getRound();
$color = $pairing->getColor();
2019-05-01 15:49:12 +02:00
$this->getRoundByNo($round)->addPairing($pairing);
2019-03-20 12:46:46 +01:00
$opponent = null;
2019-03-20 17:33:09 +01:00
foreach ($cache as $key=>$cached) {
2019-03-20 12:46:46 +01:00
if (!is_null($cached)) {
2019-04-20 16:55:39 +02:00
if (($cached->getOpponent() == $pairing->getPlayer()) && ($cached->getRound() == $pairing->getRound())) {
2019-03-20 12:46:46 +01:00
$opponent = $cached;
2019-04-20 16:55:39 +02:00
$cache[$key] = null;
2019-03-20 12:46:46 +01:00
break;
}
}
}
$game = new Game();
if ($color->getValue() == Color::white) {
2019-03-20 12:46:46 +01:00
$game->setWhite($pairing);
$game->setBlack($opponent);
} elseif ($color->getValue() == Color::black) {
2019-03-20 12:46:46 +01:00
$game->setWhite($opponent);
$game->setBlack($pairing);
}
2019-03-20 12:46:46 +01:00
if (is_null($game->getWhite()) || is_null($game->getBlack())) {
$cache[] = $pairing;
} else {
// Check if game already exists
if (!$this->GameExists($game, $round)) {
$this->AddGame($game, $round);
}
}
}
}
/**
* Checks if a game already is already registered
*
* @param Game $game
* @param int $round
* @return bool
*/
public function GameExists(Game $game, int $round = -1): bool
{
$search = [ $round ];
if ($round == -1) {
$search = [];
for ($i = 0; $i < $this->getNoOfRounds(); $i++) {
$search[] = $i;
}
}
foreach ($search as $round) {
if (!isset($this->getRounds()[$round])) {
return false;
}
$games = $this->getRounds()[$round]->getGames();
2019-03-20 12:46:46 +01:00
if (is_null($games)) {
return false;
}
foreach ($games as $roundgame) {
if ($roundgame->getWhite() == $game->getWhite() &&
$roundgame->getBlack() == $game->getBlack() &&
$roundgame->getResult() == $game->getResult()
) {
return true;
}
}
}
return false;
}
/**
2019-03-20 17:33:09 +01:00
* Adds a game to the tournament
*
* @param Game $game
* @param int $round
*/
public function addGame(Game $game, int $round)
{
if (!isset($this->getRounds()[$round])) {
$roundObj = new Round();
$roundObj->setRoundNo($round);
$this->addRound($roundObj);
}
$this->getRoundByNo($round)->addGame($game);
}
2019-02-06 17:24:10 +01:00
/**
2019-03-20 17:33:09 +01:00
* Gets the ranking of the tournament
*
2019-02-11 17:54:50 +01:00
* @return Player[]
2019-02-06 17:24:10 +01:00
*/
2019-05-28 16:26:03 +02:00
public function getRanking()
2019-02-06 17:24:10 +01:00
{
$players = $this->getPlayers();
2019-05-28 16:26:03 +02:00
usort($players, array($this, "SortTiebreak"));
2019-02-06 17:24:10 +01:00
2019-02-06 18:22:25 +01:00
return $players;
}
2019-02-06 20:10:52 +01:00
/**
2019-02-11 17:54:50 +01:00
* @param Player $a
* @param Player $b
* @return int
2019-02-06 20:10:52 +01:00
*/
2019-05-28 16:26:03 +02:00
private function sortTiebreak(Player $a, Player $b)
2019-02-06 18:22:25 +01:00
{
2019-05-28 18:07:43 +02:00
$result = 0;
foreach ($this->getTiebreaks() as $key=>$tiebreak) {
$result = $this->CalculateTiebreak($key, $b, $a) - $this->CalculateTiebreak($key, $a, $b);
if ($result != 0) {
return $result;
}
}
2019-02-06 17:24:10 +01:00
}
2019-02-06 20:10:52 +01:00
2019-05-28 16:26:03 +02:00
2019-02-06 20:10:52 +01:00
/**
2019-05-28 18:07:43 +02:00
* @return float
2019-05-28 16:26:03 +02:00
*/
2019-05-28 18:07:43 +02:00
private function calculateTiebreak(int $key, Player $player, Player $opponent): float
2019-05-28 16:26:03 +02:00
{
2019-05-28 18:07:43 +02:00
$tiebreak = $this->getTiebreaks()[$key];
switch ($tiebreak) {
case Tiebreak::Keizer:
return $this->calculateKeizer($key, $player);
break;
case Tiebreak::American:
return $this->calculateAmerican($key, $player);
break;
case Tiebreak::Points:
return $this->calculatePoints($key, $player);
break;
case Tiebreak::Baumbach:
return $this->calculateBaumbach($key, $player);
break;
case Tiebreak::BlackPlayed:
return $this->calculateBlackPlayed($key, $player);
break;
case Tiebreak::BlackWin:
return $this->calculateBlackWin($key, $player);
break;
2019-05-28 16:26:03 +02:00
}
}
2019-02-01 15:53:39 +01:00
}