2019-02-01 15:53:39 +01:00
|
|
|
<?php
|
2020-08-02 21:51:59 +02:00
|
|
|
|
2019-02-01 15:53:39 +01:00
|
|
|
/**
|
2019-11-17 01:20:15 +01:00
|
|
|
* The file contains the Tournament class which takes care of almost every element in your tournament
|
2019-06-19 19:49:39 +02:00
|
|
|
*
|
2020-08-02 21:51:59 +02:00
|
|
|
* @author Jeroen De Meerleer <schaak@jeroened.be>
|
|
|
|
* @category Main
|
|
|
|
* @package Libpairtwo
|
|
|
|
* @copyright Copyright (c) 2018-2019 Jeroen De Meerleer <schaak@jeroened.be>
|
2019-02-01 15:53:39 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
namespace JeroenED\Libpairtwo;
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
use Closure;
|
|
|
|
use DateTime;
|
2019-02-11 22:41:44 +01:00
|
|
|
use JeroenED\Libpairtwo\Enums\Color;
|
2023-01-09 12:24:20 +01:00
|
|
|
use JeroenED\Libpairtwo\Enums\Result;
|
2019-09-28 10:33:59 +02:00
|
|
|
use JeroenED\Libpairtwo\Enums\Tiebreak;
|
2019-06-19 19:49:39 +02:00
|
|
|
use JeroenED\Libpairtwo\Enums\TournamentSystem;
|
2019-02-01 15:53:39 +01:00
|
|
|
|
2019-06-19 19:49:39 +02:00
|
|
|
/**
|
|
|
|
* Class Tournament
|
|
|
|
*
|
|
|
|
* Class for the tournament from the pairing file
|
|
|
|
*
|
2020-08-02 21:51:59 +02:00
|
|
|
* @author Jeroen De Meerleer <schaak@jeroened.be>
|
|
|
|
* @category Main
|
|
|
|
* @package Libpairtwo
|
|
|
|
* @copyright Copyright (c) 2018-2019 Jeroen De Meerleer <schaak@jeroened.be>
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
|
|
|
class Tournament
|
2019-02-01 15:53:39 +01:00
|
|
|
{
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* An Array of the assigned arbiters
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Arbiters;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Binary data that was read out of the pairing file
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var bool|DateTime|int|string[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private $BinaryData = [];
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Round objects of all rounds in the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var $Categories []
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Categories = [];
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* End date (Last round or Award Ceremony) of the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var DateTime
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $EndDate;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The federation for which this tournament is held
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Federation;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
|
|
|
* Whether or not the tournament is an official tournament and send to the world chess organisation
|
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
2019-11-15 17:16:38 +01:00
|
|
|
public $FideHomol;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The tempo for the first period of a game in the tournament
|
2020-08-02 21:51:59 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $FirstPeriod;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Name of the Tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Name;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Number of round the tournament has
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var int
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $NoOfRounds;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The elo a player gets if he does not have an official elo
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
|
|
|
* @var int
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $NonRatedElo;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Organiser of the tournament (eg. Donald J. Trump)
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Organiser;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2020-11-22 16:40:10 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Club name of the tournament organiser (eg. The White House Chess Club)
|
2020-11-22 16:40:10 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2020-11-22 16:40:10 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $OrganiserClub;
|
2020-11-22 16:40:10 +01:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Club ID of the tournament organiser (eg. 205001600)
|
2020-08-02 21:51:59 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @var string
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $OrganiserClubNo;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The country where the tournament is held
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $OrganiserCountry;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Place where the Tounament is held (eg. The Oval Office)
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $OrganiserPlace;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* All pairings of the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var Pairing[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Pairings = [];
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* All players of the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var Player[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Players = [];
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The elo that priority above all others
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $PriorityElo = 'Fide';
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The Id that has priority above all other
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $PriorityId = 'Nation';
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Round objects of all rounds in the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var Round[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Rounds = [];
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The tempo for the second period of a game in the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var string
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $SecondPeriod;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Start date (First round or Players meeting) of the tournament
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var DateTime
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $StartDate;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The system the tournament (eg. Swiss, Closed, American)
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var TournamentSystem
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $System;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The tempo of the tournament (eg. 90 min/40 moves + 30 sec. increment starting from move 1)
|
2019-11-17 01:20:15 +01:00
|
|
|
*
|
|
|
|
* @var string
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Tempo;
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2019-11-17 01:20:15 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The tiebreaks for the tournament
|
2019-12-22 17:58:40 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var Tiebreak[]
|
2019-11-17 01:20:15 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Tiebreaks = [];
|
2019-07-16 15:58:53 +02:00
|
|
|
|
2022-09-19 17:23:12 +02:00
|
|
|
/**
|
|
|
|
* Custom points for the tournament
|
|
|
|
*
|
|
|
|
* @var float[]
|
|
|
|
*/
|
|
|
|
public $CustomPoints = ['win' => 1, 'draw' => 0.5, 'loss' => 0, 'bye' => 1, 'absent' => 0];
|
|
|
|
|
2019-02-01 15:53:39 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The year or season the tournament is held or is count for
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @var int
|
2019-02-01 15:53:39 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public $Year;
|
2019-02-01 15:53:39 +01:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Get the ranking for a specific category
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param string $category
|
|
|
|
*
|
|
|
|
* @return array
|
2019-02-01 15:53:39 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function RankingForCategory(string $category): array
|
2019-02-01 15:53:39 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$globalRanking = $this->ranking();
|
|
|
|
|
|
|
|
$return = [];
|
|
|
|
foreach ($globalRanking as $player) {
|
|
|
|
if ($player->Category == $category) {
|
|
|
|
$return[] = $player;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $return;
|
2019-02-01 15:53:39 +01:00
|
|
|
}
|
2019-02-01 17:02:33 +01:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Magic method to read out several fields. If field was not found it is being searched in the binary data fields
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param string $key
|
|
|
|
*
|
|
|
|
* @return bool|DateTime|int|string|null
|
2019-02-01 17:02:33 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function __get(string $key)
|
2019-02-01 17:02:33 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
if ($key == 'Participants') {
|
|
|
|
return $this->participants();
|
|
|
|
} elseif ($key == 'AverageElo') {
|
|
|
|
return $this->averageElo();
|
|
|
|
} elseif ($key == 'Ranking') {
|
|
|
|
return $this->ranking();
|
|
|
|
} elseif (isset($this->BinaryData[ $key ])) {
|
|
|
|
return $this->BinaryData[ $key ];
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
2019-02-01 17:02:33 +01:00
|
|
|
}
|
2019-02-06 17:23:37 +01:00
|
|
|
|
2019-05-27 21:45:19 +02:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Sets binary data that is read out the pairing file but is not needed immediately
|
2019-05-27 21:45:19 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param string $key
|
|
|
|
* @param bool|int|DateTime|string $value
|
|
|
|
*
|
|
|
|
* @return void
|
2019-05-27 21:45:19 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function __set(string $key, $value): void
|
2019-05-27 21:45:19 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$this->BinaryData[ $key ] = $value;
|
2019-05-27 21:45:19 +02:00
|
|
|
}
|
|
|
|
|
2019-02-06 17:23:37 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Adds an arbiter to the tournament
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param string $Arbiter
|
2019-02-06 17:23:37 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function addArbiter(string $Arbiter): void
|
2019-02-06 17:23:37 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$newArray = $this->Arbiters;
|
|
|
|
$newArray[] = $Arbiter;
|
|
|
|
$this->Arbiters = $newArray;
|
2019-02-06 17:23:37 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 16:40:10 +01:00
|
|
|
/**
|
|
|
|
* Adds a category with given name object
|
|
|
|
*
|
|
|
|
* @param string $name
|
|
|
|
*/
|
|
|
|
public function addCategory(string $name): void
|
|
|
|
{
|
|
|
|
$newArray = $this->Categories;
|
|
|
|
$newArray[] = $name;
|
|
|
|
$this->Categories = $newArray;
|
|
|
|
}
|
|
|
|
|
2019-02-11 22:41:44 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Adds a game to the tournament
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Game $game
|
|
|
|
* @param int $round
|
2019-02-11 22:41:44 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function addGame(Game $game, int $round): void
|
2019-02-11 22:41:44 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
if (!isset($this->Rounds[ $round ])) {
|
|
|
|
$roundObj = new Round();
|
|
|
|
$roundObj->RoundNo = $round;
|
|
|
|
$this->addRound($roundObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->roundByNo($round)->addGame($game);
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
|
|
|
|
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
|
|
|
|
*/
|
2019-11-16 14:24:07 +01:00
|
|
|
public function addPairing(Pairing $pairing): void
|
2019-02-11 16:43:36 +01:00
|
|
|
{
|
2019-11-15 17:16:38 +01:00
|
|
|
$newArray = $this->Pairings;
|
2019-02-11 16:43:36 +01:00
|
|
|
$newArray[] = $pairing;
|
2019-11-15 17:16:38 +01:00
|
|
|
$this->Pairings = $newArray;
|
2019-02-11 16:43:36 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
/**
|
|
|
|
* Adds a player
|
|
|
|
*
|
|
|
|
* @param Player $Player
|
|
|
|
*/
|
|
|
|
public function addPlayer(Player $Player): void
|
|
|
|
{
|
|
|
|
$newArray = $this->Players;
|
|
|
|
$newArray[] = $Player;
|
|
|
|
$this->Players = $newArray;
|
|
|
|
}
|
2019-09-26 14:48:55 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Adds a round with given Round object
|
2019-09-27 16:29:29 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Round $round
|
2019-09-26 14:48:55 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function addRound(Round $round): void
|
2019-09-26 14:48:55 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$newArray = $this->Rounds;
|
|
|
|
$newArray[ $round->RoundNo ] = $round;
|
|
|
|
$this->Rounds = $newArray;
|
2019-09-26 14:48:55 +02:00
|
|
|
}
|
|
|
|
|
2019-02-11 22:41:44 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Adds a Tiebreak
|
|
|
|
*
|
|
|
|
* @param Tiebreak $tiebreak
|
2019-02-11 22:41:44 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function addTiebreak(Tiebreak $tiebreak): void
|
2019-02-11 22:41:44 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$newArray = $this->Tiebreaks;
|
|
|
|
$newArray[] = $tiebreak;
|
|
|
|
$this->Tiebreaks = $newArray;
|
|
|
|
}
|
2019-02-11 22:41:44 +01:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Return the average rating for tournament
|
2019-02-11 22:41:44 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @return int
|
2019-02-11 22:41:44 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function averageElo(): int
|
2019-02-11 22:41:44 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$totalrating = 0;
|
|
|
|
$players = 0;
|
|
|
|
foreach ($this->Players as $player) {
|
|
|
|
$toadd = $player->getElo($this->PriorityElo);
|
|
|
|
if ($toadd == 0) {
|
|
|
|
$toadd = $this->NonRatedElo;
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
$totalrating += $toadd;
|
|
|
|
$players++;
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return intdiv($totalrating, $players);
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The average performance of the opponents
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Player $player
|
|
|
|
* @param string $type
|
|
|
|
* @param int $cut
|
|
|
|
*
|
|
|
|
* @return float
|
2019-02-11 22:41:44 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateAveragePerformance(Player $player, string $type, int $cut = 0): float
|
2019-02-11 22:41:44 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$pairings = $player->Pairings;
|
|
|
|
$allratings = [];
|
|
|
|
foreach ($pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Result, Constants::NOTPLAYED) === false) {
|
|
|
|
$toadd = $pairing->Opponent->Performance($type, $this->NonRatedElo);
|
|
|
|
if ($toadd != 0) {
|
|
|
|
$allratings[] = $toadd;
|
|
|
|
}
|
|
|
|
}
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
sort($allratings);
|
|
|
|
$allratings = array_slice($allratings, $cut);
|
2019-02-11 22:41:44 +01:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return round(array_sum($allratings) / count($allratings));
|
2019-02-11 22:41:44 +01:00
|
|
|
}
|
|
|
|
|
2020-11-22 16:40:10 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The average rating of the opponents
|
2020-11-22 16:40:10 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Player $player
|
|
|
|
* @param string $type
|
|
|
|
* @param int $cut
|
2020-11-22 16:40:10 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @return float
|
2020-11-22 16:40:10 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateAverageRating(Player $player, string $type, int $cut = 0): float
|
2020-11-22 16:40:10 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$pairings = $player->Pairings;
|
|
|
|
$allratings = [];
|
|
|
|
foreach ($pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Result, Constants::NOTPLAYED) === false) {
|
|
|
|
$toadd = $pairing->Opponent->getElo($type);
|
|
|
|
if ($toadd != 0) {
|
|
|
|
$allratings[] = $toadd;
|
|
|
|
}
|
2020-11-22 16:40:10 +01:00
|
|
|
}
|
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
sort($allratings);
|
|
|
|
$allratings = array_slice($allratings, $cut);
|
|
|
|
$tiebreak = 0;
|
|
|
|
if (count($allratings) > 0) {
|
|
|
|
$tiebreak = round(array_sum($allratings) / count($allratings));
|
|
|
|
}
|
|
|
|
|
|
|
|
return $tiebreak;
|
2020-11-22 16:40:10 +01:00
|
|
|
}
|
|
|
|
|
2019-02-06 17:24:10 +01:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Number of won games
|
2019-03-20 17:33:09 +01:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Player $player
|
|
|
|
*
|
|
|
|
* @return float
|
2019-02-06 17:24:10 +01:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateBaumbach(Player $player): float
|
2019-02-06 17:24:10 +01:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->Pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Result, Constants::NOTPLAYED) === false) {
|
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$totalwins++;
|
2019-05-29 15:48:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-06 18:22:25 +01:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return $totalwins;
|
2019-02-06 17:24:10 +01:00
|
|
|
}
|
2019-02-06 20:10:52 +01:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Number of played games with black
|
|
|
|
*
|
|
|
|
* @param Player $player
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-05-28 16:26:03 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateBlackPlayed(Player $player): float
|
2019-05-28 16:26:03 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->Pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Color, Constants::BLACK) !== false) {
|
|
|
|
$totalwins++;
|
|
|
|
}
|
2019-05-28 16:26:03 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
|
|
|
|
return $totalwins;
|
2019-05-28 16:26:03 +02:00
|
|
|
}
|
2019-05-29 17:57:42 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Number of won games with black
|
2019-05-29 17:57:42 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Player $player
|
|
|
|
*
|
|
|
|
* @return float
|
2019-05-29 17:57:42 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateBlackWin(Player $player): float
|
2019-05-29 17:57:42 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$totalwins = 0;
|
|
|
|
foreach ($player->Pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Color, Constants::BLACK) !== false &&
|
|
|
|
array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$totalwins++;
|
2019-05-29 17:57:42 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-18 15:57:42 +02:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return $totalwins;
|
2019-06-18 15:57:42 +02:00
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The combined points of the opponents
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $cutlowest
|
|
|
|
* @param int $cuthighest
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateBuchholz(Player $player, int $cutlowest = 0, int $cuthighest = 0): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak = 0;
|
|
|
|
$intpairingsWithBye = $player->Pairings;
|
|
|
|
|
|
|
|
$intpairings = [];
|
|
|
|
$curpoints = 0;
|
|
|
|
$curround = 1;
|
|
|
|
foreach ($intpairingsWithBye as $key => $pairing) {
|
|
|
|
$roundstoplay = (count($intpairingsWithBye)) - $curround;
|
|
|
|
if (is_null($pairing->Opponent)) {
|
|
|
|
$intpairings[] = $player->calculatePointsForVirtualPlayer($key);
|
|
|
|
} else {
|
|
|
|
$intpairings[] = $pairing->Opponent->calculatePointsForTiebreaks();
|
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$curpoints += 1;
|
|
|
|
} elseif (array_search($pairing->Result, Constants::DRAW) !== false) {
|
|
|
|
$curpoints += 0.5;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$curround++;
|
|
|
|
}
|
|
|
|
|
|
|
|
usort(
|
|
|
|
$intpairings,
|
|
|
|
function ($a, $b) {
|
|
|
|
if ($b == $a) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ($a > $b) ? 1 : -1;
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
$intpairings = array_slice($intpairings, $cutlowest);
|
|
|
|
$intpairings = array_slice($intpairings, 0 - $cuthighest);
|
|
|
|
|
|
|
|
return array_sum($intpairings);
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Combined score of $player after each round
|
|
|
|
*
|
|
|
|
* @param Player $player
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateCumulative(Player $player): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak = 0;
|
|
|
|
$score = [];
|
|
|
|
foreach ($player->Pairings as $pairing) {
|
|
|
|
$toadd = 0;
|
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$toadd = 1;
|
|
|
|
} elseif (array_search($pairing->Result, Constants::DRAW) !== false) {
|
|
|
|
$toadd = 0.5;
|
|
|
|
}
|
|
|
|
$tiebreak += $toadd;
|
|
|
|
$score[] = $tiebreak;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return array_sum($score);
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* $points["Won"] points for each win, $points["Draw"] for each draw and $points["Lost"] point for losing.
|
|
|
|
* $points["NotPlayed"] points for not played games
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
* @param int[] $points
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateKashdan(Player $player, array $points): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak = 0;
|
2019-11-15 17:16:38 +01:00
|
|
|
foreach ($player->Pairings as $pairing) {
|
2020-11-22 17:13:13 +01:00
|
|
|
$toadd = 0;
|
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$toadd = $points[ "Won" ];
|
|
|
|
} elseif (array_search($pairing->Result, Constants::DRAW) !== false) {
|
|
|
|
$toadd = $points[ "Draw" ];
|
|
|
|
} elseif (array_search($pairing->Result, Constants::LOST) !== false) {
|
|
|
|
$toadd = $points[ "Lost" ];
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
|
|
|
|
if (array_search($pairing->Result, Constants::NOTPLAYED) !== false) {
|
|
|
|
$toadd = $points[ "NotPlayed" ];
|
|
|
|
}
|
|
|
|
$tiebreak += $toadd;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return $tiebreak; // - $player->NoOfWins;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Points following keizer system
|
|
|
|
*
|
|
|
|
* @param Player $player
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateKeizer(Player $player): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
return $player->ScoreAmerican;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Points against players who have more than $cut % points
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $cut
|
2019-06-20 15:29:02 +02:00
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateKoya(Player $player, int $cut = 50): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak = 0;
|
|
|
|
foreach ($player->Pairings as $plkey => $plpairing) {
|
|
|
|
if (($plpairing->Opponent->calculatePoints() / count($plpairing->Opponent->Pairings) * 100) >= $cut) {
|
|
|
|
if (array_search($plpairing->Result, Constants::WON) !== false) {
|
|
|
|
$tiebreak += 1;
|
|
|
|
} elseif (array_search($plpairing->Result, Constants::DRAW) !== false) {
|
|
|
|
$tiebreak += 0.5;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return $tiebreak;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2019-06-20 14:53:26 +02:00
|
|
|
* Result between the tied players
|
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Player $player
|
|
|
|
* @param array $opponents
|
|
|
|
* @param int $key
|
|
|
|
*
|
2019-11-17 01:20:15 +01:00
|
|
|
* @return float
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2019-11-17 01:20:15 +01:00
|
|
|
private function calculateMutualResult(Player $player, array $opponents, int $key): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
|
|
|
$interestingplayers = $opponents;
|
|
|
|
if ($key != 0) {
|
|
|
|
$interestingplayers = [];
|
2019-11-15 17:16:38 +01:00
|
|
|
$playerstiebreaks = $player->Tiebreaks;
|
2019-06-19 19:49:39 +02:00
|
|
|
array_splice($playerstiebreaks, $key);
|
|
|
|
foreach ($opponents as $opponent) {
|
2019-11-15 17:16:38 +01:00
|
|
|
$opponenttiebreaks = $opponent->Tiebreaks;
|
2019-06-19 19:49:39 +02:00
|
|
|
array_splice($opponenttiebreaks, $key);
|
|
|
|
if (($playerstiebreaks == $opponenttiebreaks) && ($player != $opponent)) {
|
|
|
|
$interestingplayers[] = $opponent;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-12-26 20:33:53 +01:00
|
|
|
if ($interestingplayers) {
|
2019-12-25 13:43:36 +01:00
|
|
|
$allintplayers = $interestingplayers;
|
|
|
|
$allintplayers[] = $player;
|
2019-12-26 20:33:53 +01:00
|
|
|
foreach ($allintplayers as $player) {
|
2019-12-25 13:43:36 +01:00
|
|
|
if (!$player->hasPlayedAllPlayersOfArray($allintplayers)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
$points = 0;
|
|
|
|
$totalmatches = 0;
|
2019-11-15 17:16:38 +01:00
|
|
|
foreach ($player->Pairings as $pairing) {
|
|
|
|
if (array_search($pairing->Opponent, $interestingplayers) !== false) {
|
2020-08-02 21:51:59 +02:00
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
2019-06-19 19:49:39 +02:00
|
|
|
$points = $points + 1;
|
2020-08-02 21:51:59 +02:00
|
|
|
} elseif (array_search($pairing->Result, Constants::DRAW) !== false) {
|
2019-06-19 19:49:39 +02:00
|
|
|
$points = $points + 0.5;
|
|
|
|
}
|
|
|
|
$totalmatches++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($totalmatches != count($interestingplayers)) {
|
2019-09-27 17:29:51 +02:00
|
|
|
$points = 0;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
|
2019-06-19 19:49:39 +02:00
|
|
|
return $points;
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
/**
|
|
|
|
* Number of points
|
|
|
|
*
|
|
|
|
* @param Player $player
|
|
|
|
*
|
|
|
|
* @return float
|
|
|
|
*/
|
|
|
|
private function calculatePoints(Player $player): float
|
|
|
|
{
|
2022-09-19 17:23:12 +02:00
|
|
|
return $player->calculatePoints(-1, $this->CustomPoints);
|
2020-11-22 17:13:13 +01:00
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* The points of $player's opponents who $player won against, plus half of the points of $player's opponents who
|
|
|
|
* $player drew against
|
|
|
|
*
|
|
|
|
* @param Player $player
|
2019-06-20 14:53:26 +02:00
|
|
|
*
|
2019-06-19 19:49:39 +02:00
|
|
|
* @return float
|
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function calculateSonneborn(Player $player): float
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak = 0;
|
|
|
|
foreach ($player->Pairings as $key => $pairing) {
|
|
|
|
if ($pairing->Opponent) {
|
|
|
|
if (array_search($pairing->Result, Constants::WON) !== false) {
|
|
|
|
$tiebreak += $pairing->Opponent->calculatePointsForTiebreaks();
|
|
|
|
} elseif (array_search($pairing->Result, Constants::DRAW) !== false) {
|
|
|
|
$tiebreak += $pairing->Opponent->calculatePointsForTiebreaks() / 2;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
}
|
2023-01-09 12:51:23 +01:00
|
|
|
if ($pairing->Result == Result::WON_BYE) {
|
2020-11-22 17:13:13 +01:00
|
|
|
$tiebreak += $player->calculatePointsForVirtualPlayer($key);
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
|
|
|
|
return $tiebreak;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculates a specific tiebreak for $player
|
|
|
|
*
|
|
|
|
* @param Tiebreak $tiebreak
|
|
|
|
* @param Player $player
|
|
|
|
* @param int $tbkey
|
|
|
|
*
|
|
|
|
* @return float
|
|
|
|
*/
|
|
|
|
private function calculateTiebreak(Tiebreak $tiebreak, Player $player, int $tbkey = 0): float
|
|
|
|
{
|
|
|
|
switch ($tiebreak) {
|
|
|
|
case Tiebreak::KEIZER:
|
|
|
|
return $this->calculateKeizer($player);
|
|
|
|
case Tiebreak::POINTS:
|
|
|
|
return $this->calculatePoints($player);
|
|
|
|
case Tiebreak::BAUMBACH:
|
|
|
|
return $this->calculateBaumbach($player);
|
|
|
|
case Tiebreak::BLACK_PLAYED:
|
|
|
|
return $this->calculateBlackPlayed($player);
|
|
|
|
case Tiebreak::BLACK_WIN:
|
|
|
|
return $this->calculateBlackWin($player);
|
|
|
|
case Tiebreak::BETWEEN:
|
|
|
|
return $this->calculateMutualResult($player, $this->Players, $tbkey);
|
|
|
|
case Tiebreak::ARO:
|
|
|
|
return $this->calculateAverageRating($player, $this->PriorityElo);
|
|
|
|
case Tiebreak::AROCUT:
|
|
|
|
return $this->calculateAverageRating($player, $this->PriorityElo, 1);
|
|
|
|
case Tiebreak::KOYA:
|
|
|
|
return $this->calculateKoya($player);
|
|
|
|
case Tiebreak::BUCHHOLZ:
|
|
|
|
return $this->calculateBuchholz($player);
|
|
|
|
case Tiebreak::BUCHHOLZ_CUT:
|
|
|
|
return $this->calculateBuchholz($player, 1);
|
|
|
|
case Tiebreak::BUCHHOLZ_MED:
|
|
|
|
return $this->calculateBuchholz($player, 1, 1);
|
|
|
|
case Tiebreak::BUCHHOLZ_CUT_2:
|
|
|
|
return $this->calculateBuchholz($player, 2);
|
|
|
|
case Tiebreak::BUCHHOLZ_MED_2:
|
|
|
|
return $this->calculateBuchholz($player, 2, 2);
|
|
|
|
case Tiebreak::SONNEBORN:
|
|
|
|
return $this->calculateSonneborn($player);
|
|
|
|
case Tiebreak::KASHDAN:
|
|
|
|
return $this->calculateKashdan($player, ["Won" => 4, "Draw" => 2, "Lost" => 1, "NotPlayed" => 0]);
|
|
|
|
case Tiebreak::SOCCER_KASHDAN:
|
|
|
|
return $this->calculateKashdan($player, ["Won" => 3, "Draw" => 1, "Lost" => 0, "NotPlayed" => -1]);
|
|
|
|
case Tiebreak::CUMULATIVE:
|
|
|
|
return $this->calculateCumulative($player);
|
|
|
|
case Tiebreak::AVERAGE_PERFORMANCE:
|
|
|
|
return $this->calculateAveragePerformance($player, $this->PriorityElo);
|
|
|
|
case Tiebreak::PERFORMANCE:
|
|
|
|
return $player->Performance($this->PriorityElo, $this->NonRatedElo);
|
|
|
|
default:
|
|
|
|
return 0;
|
2019-09-27 18:00:28 +02:00
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Checks if a game already is already registered
|
2019-06-20 14:53:26 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param Game $game
|
|
|
|
* @param int $round
|
|
|
|
*
|
|
|
|
* @return bool
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function gameExists(Game $game, int $round = -1): bool
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$search = [$round];
|
|
|
|
if ($round == -1) {
|
|
|
|
$search = [];
|
|
|
|
for ($i = 0; $i < $this->NoOfRounds; $i++) {
|
|
|
|
$search[] = $i;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
foreach ($search as $round) {
|
|
|
|
if (!isset($this->Rounds[ $round ])) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$games = $this->Rounds[ $round ]->Games;
|
|
|
|
if (is_null($games)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
foreach ($games as $roundgame) {
|
|
|
|
if ($game->equals($roundgame)) {
|
|
|
|
return true;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
return false;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Converts pairings into games with a black and white player
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function pairingsToRounds(): void
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$pairings = $this->Pairings;
|
2019-09-27 16:29:29 +02:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
/**
|
|
|
|
* @var Pairing[]
|
|
|
|
*/
|
|
|
|
$cache = [];
|
|
|
|
|
|
|
|
foreach ($pairings as $pairing) {
|
|
|
|
// Add pairing to player
|
|
|
|
$pairing->Player->addPairing($pairing);
|
|
|
|
$round = $pairing->Round;
|
|
|
|
$color = $pairing->Color;
|
|
|
|
|
|
|
|
$this->roundByNo($round)->addPairing($pairing);
|
|
|
|
$opponent = null;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var int $key
|
|
|
|
* @var Pairing $cached
|
|
|
|
*/
|
|
|
|
foreach ($cache as $key => $cached) {
|
|
|
|
if (!is_null($cached)) {
|
|
|
|
if (($cached->Opponent == $pairing->Player) && ($cached->Round == $pairing->Round)) {
|
|
|
|
$opponent = $cached;
|
|
|
|
$cache[ $key ] = null;
|
|
|
|
break;
|
|
|
|
}
|
2019-09-27 16:29:29 +02:00
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
$game = new Game();
|
|
|
|
if ($color->getValue() == Color::WHITE) {
|
|
|
|
$game->White = $pairing;
|
|
|
|
$game->Black = $opponent;
|
|
|
|
} elseif ($color->getValue() == Color::BLACK) {
|
|
|
|
$game->White = $opponent;
|
|
|
|
$game->Black = $pairing;
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
if (is_null($game->White) || is_null($game->Black)) {
|
|
|
|
$cache[] = $pairing;
|
|
|
|
} elseif (!$this->gameExists($game, $round)) { // Check if game already exists
|
|
|
|
$game->Board = $game->White->Board;
|
|
|
|
// Add board if inexistent
|
|
|
|
if ($game->Board == -1) {
|
|
|
|
if (isset($lastboards[ $round ])) {
|
|
|
|
$lastboards[ $round ] += 1;
|
|
|
|
} else {
|
|
|
|
$lastboards[ $round ] = 0;
|
|
|
|
}
|
|
|
|
$game->Board = $lastboards[ $round ];
|
|
|
|
$game->White->Board = $lastboards[ $round ];
|
|
|
|
$game->Black->Board = $lastboards[ $round ];
|
2020-08-02 21:51:59 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
$this->AddGame($game, $round);
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Returns the number of participants
|
2019-06-20 14:53:26 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @return int
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function participants(): int
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
return count($this->Players);
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
2020-11-22 17:13:13 +01:00
|
|
|
/**
|
|
|
|
* Gets a player by its ID
|
|
|
|
*
|
|
|
|
* @param int $id
|
|
|
|
*
|
|
|
|
* @return Player
|
|
|
|
*/
|
|
|
|
public function playerById(int $id): Player
|
|
|
|
{
|
|
|
|
return $this->Players[ $id ];
|
|
|
|
}
|
2019-06-19 19:49:39 +02:00
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Gets the ranking of the tournament
|
2019-06-20 14:53:26 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @return Player[]
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function ranking(): array
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$players = $this->Players;
|
|
|
|
foreach ($this->Tiebreaks as $tbkey => $tiebreak) {
|
|
|
|
foreach ($players as $pkey => $player) {
|
|
|
|
$break = $this->calculateTiebreak($tiebreak, $player, $tbkey);
|
|
|
|
$tiebreaks = $player->Tiebreaks;
|
|
|
|
$tiebreaks[ $tbkey ] = $break;
|
|
|
|
$player->Tiebreaks = $tiebreaks;
|
|
|
|
$this->updatePlayer($pkey, $player);
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
}
|
|
|
|
$sortedplayers[ 0 ] = $players;
|
|
|
|
foreach ($this->Tiebreaks 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->Tiebreaks[ $tbkey ])) {
|
|
|
|
if ($playerkey != 0) {
|
|
|
|
$newgroupkey++;
|
|
|
|
if ($player->Tiebreaks[ $tbkey ] ==
|
|
|
|
$tosortplayers[ $groupkey ][ $playerkey - 1 ]->Tiebreaks[ $tbkey ]) {
|
|
|
|
$newgroupkey--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$sortedplayers[ $newgroupkey ][] = $player;
|
|
|
|
}
|
|
|
|
$newgroupkey++;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
}
|
2020-11-22 17:13:13 +01:00
|
|
|
$finalarray = [];
|
|
|
|
foreach ($sortedplayers as $sort1) {
|
|
|
|
foreach ($sort1 as $player) {
|
|
|
|
$finalarray[] = $player;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $finalarray;
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Gets a round by its number.
|
2019-06-20 14:53:26 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param int $roundNo
|
|
|
|
*
|
|
|
|
* @return Round
|
2019-06-19 19:49:39 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function roundByNo(int $roundNo): Round
|
2019-06-19 19:49:39 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
return $this->Rounds[ $roundNo ];
|
2019-06-19 19:49:39 +02:00
|
|
|
}
|
|
|
|
|
2019-07-16 15:58:53 +02:00
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Sort by tiebreak
|
2019-07-16 15:58:53 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param int $key
|
|
|
|
*
|
|
|
|
* @return Closure
|
2019-07-16 15:58:53 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
private function sortTiebreak(int $key): Closure
|
2019-07-16 15:58:53 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
return function (Player $a, Player $b) use ($key) {
|
|
|
|
if (($b->Tiebreaks[ $key ] == $a->Tiebreaks[ $key ]) ||
|
|
|
|
($a->Tiebreaks[ $key ] === false) ||
|
|
|
|
($b->Tiebreaks[ $key ] === false)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ($b->Tiebreaks[ $key ] > $a->Tiebreaks[ $key ]) ? +1 : -1;
|
|
|
|
};
|
2019-07-16 15:58:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-11-22 17:13:13 +01:00
|
|
|
* Updates player on id to the given Player object
|
2019-07-16 15:58:53 +02:00
|
|
|
*
|
2020-11-22 17:13:13 +01:00
|
|
|
* @param int $id
|
|
|
|
* @param Player $player
|
2019-07-16 15:58:53 +02:00
|
|
|
*/
|
2020-11-22 17:13:13 +01:00
|
|
|
public function updatePlayer(int $id, Player $player): void
|
2019-07-16 15:58:53 +02:00
|
|
|
{
|
2020-11-22 17:13:13 +01:00
|
|
|
$newArray = $this->Players;
|
|
|
|
$newArray[ $id ] = $player;
|
|
|
|
$this->Players = $newArray;
|
2019-07-16 15:58:53 +02:00
|
|
|
}
|
2019-02-01 15:53:39 +01:00
|
|
|
}
|