MAJOR UPDATE: Generalization + Tiebreaks

This commit is contained in:
Jeroen De Meerleer 2019-06-01 16:39:58 +02:00
parent 3b5b42b46d
commit 89e4e6c121
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
18 changed files with 1047 additions and 372 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 ];
}

31
src/Enums/Tiebreak.php Normal file
View File

@ -0,0 +1,31 @@
<?php
namespace JeroenED\Libpairtwo\Enums;
use MyCLabs\Enum\Enum;
class Tiebreak extends Enum
{
const None = "";
const Keizer = "Keizer";
const Points = "Points";
const American = "American";
const Buchholz = "Buchholz";
const BuchholzMed = "Buchholz Median";
const BuchholzCut = "Buchholz Cut";
const Sonneborn = "Sonneborn-Berger";
const Kashdan = "Kashdan";
const Cumulative = "Cumulative";
const Between = "Mutual Result";
const Koya = "Koya";
const Baumbach = "Most wins"; // Ref: https://en.wikipedia.org/wiki/Tie-breaking_in_Swiss-system_tournaments#Most_wins_(Baumbach) Please tell me why?
const AveragePerformance = "Average performance";
const Performance = "Performance";
const Aro = "Average Rating";
const AroCut = "Average Rating Cut";
const BlackPlayed = "Black played";
const BlackWin = "Black Winned";
const Testmatch = "Testmatch";
const Drawing = "Drawing of lot";
}

View File

@ -15,5 +15,5 @@ class TournamentSystem extends Enum
const Swiss = 'Swiss'; const Swiss = 'Swiss';
const Closed = 'Closed'; const Closed = 'Closed';
const American = 'American'; const American = 'American';
const Imperial = 'Imperial'; const Keizer = 'Keizer';
} }

View File

@ -3,8 +3,6 @@
namespace JeroenED\Libpairtwo\Exceptions; namespace JeroenED\Libpairtwo\Exceptions;
class IncompatibleReaderException extends LibpairtwoException
class IncompatibleReaderException Extends LibpairtwoException
{ {
} }

View File

@ -3,8 +3,6 @@
namespace JeroenED\LibPairtwo\Exceptions; namespace JeroenED\LibPairtwo\Exceptions;
class LibpairtwoException extends \Exception class LibpairtwoException extends \Exception
{ {
} }

View File

@ -3,7 +3,10 @@
namespace JeroenED\Libpairtwo\Interfaces; namespace JeroenED\Libpairtwo\Interfaces;
use JeroenED\Libpairtwo\Tournament;
interface ReaderInterface interface ReaderInterface
{ {
public function read($filename); public function read($filename): ReaderInterface;
public function getTournament(): Tournament;
} }

View File

@ -13,60 +13,66 @@ use JeroenED\Libpairtwo\Pairing;
abstract class Game abstract class Game
{ {
/** @var Pairing */ /** @var Pairing|null */
private $white; private $white;
/** @var Pairing */ /** @var Pairing|null */
private $black; private $black;
/** @var GameResult */ /** @var GameResult|null */
private $result; private $result;
/** /**
* @return Pairing * @return Pairing|null
*/ */
public function getWhite() public function getWhite(): ?Pairing
{ {
return $this->white; return $this->white;
} }
/** /**
* @param Pairing $white * @param Pairing|null $white
* @return Game
*/ */
public function setWhite($white): void public function setWhite(?Pairing $white): Game
{ {
$this->white = $white; $this->white = $white;
return $this;
} }
/** /**
* @return Pairing * @return Pairing|null
*/ */
public function getBlack() public function getBlack(): ?Pairing
{ {
return $this->black; return $this->black;
} }
/** /**
* @param Pairing $black * @param Pairing|null $black
* @return Game
*/ */
public function setBlack($black): void public function setBlack(?Pairing $black): Game
{ {
$this->black = $black; $this->black = $black;
return $this;
} }
/** /**
* @return GameResult * @return Gameresult|null
*/ */
public function getResult() public function getResult(): ?Gameresult
{ {
return $this->result; return $this->result;
} }
/** /**
* @param GameResult $result * @param Gameresult|null $result
* @return Game
*/ */
public function setResult(GameResult $result): void public function setResult(?Gameresult $result): Game
{ {
$this->result = $result; $this->result = $result;
return $this;
} }
} }

View File

@ -14,10 +14,10 @@ use JeroenED\Libpairtwo\Player;
abstract class Pairing abstract class Pairing
{ {
/** @var Player */ /** @var Player|null */
private $Player; private $Player;
/** @var Player */ /** @var Player|null */
private $Opponent; private $Opponent;
/** @var Color */ /** @var Color */
@ -30,35 +30,39 @@ abstract class Pairing
private $Round; private $Round;
/** /**
* @return Player * @return Player|null
*/ */
public function getPlayer() public function getPlayer(): ?Player
{ {
return $this->Player; return $this->Player;
} }
/** /**
* @param Player $Player * @param Player|null $Player
* @return Pairing
*/ */
public function setPlayer(Player $Player): void public function setPlayer(?Player $Player): Pairing
{ {
$this->Player = $Player; $this->Player = $Player;
return $this;
} }
/** /**
* @return Player * @return Player|null
*/ */
public function getOpponent() public function getOpponent(): ?Player
{ {
return $this->Opponent; return $this->Opponent;
} }
/** /**
* @param Player $Opponent * @param Player|null $Opponent
* @return Pairing
*/ */
public function setOpponent(Player $Opponent): void public function setOpponent(?Player $Opponent): Pairing
{ {
$this->Opponent = $Opponent; $this->Opponent = $Opponent;
return $this;
} }
/** /**
@ -71,10 +75,12 @@ abstract class Pairing
/** /**
* @param Color $Color * @param Color $Color
* @return Pairing
*/ */
public function setColor(Color $Color): void public function setColor(Color $Color): Pairing
{ {
$this->Color = $Color; $this->Color = $Color;
return $this;
} }
/** /**
@ -87,10 +93,12 @@ abstract class Pairing
/** /**
* @param Result $Result * @param Result $Result
* @return Pairing
*/ */
public function setResult(Result $Result): void public function setResult(Result $Result): Pairing
{ {
$this->Result = $Result; $this->Result = $Result;
return $this;
} }
/** /**
@ -103,9 +111,11 @@ abstract class Pairing
/** /**
* @param int $Round * @param int $Round
* @return Pairing
*/ */
public function setRound(int $Round): void public function setRound(int $Round): Pairing
{ {
$this->Round = $Round; $this->Round = $Round;
return $this;
} }
} }

View File

@ -18,42 +18,22 @@ abstract class Player
/** @var string */ /** @var string */
private $Name; private $Name;
/** @var int */ /** @var int[] */
private $Rank; private $Ids;
/** @var int */ /** @var int[] */
private $FideId; private $Elos;
/** @var int */
private $ExtraPts;
/** @var int */
private $KbsbElo;
/** @var DateTime */ /** @var DateTime */
private $dateofbirth; private $DateOfBirth;
/** @var int */ /** @var float[] */
private $KbsbID; private $Tiebreaks = [];
/** @var float */
private $Points;
/** @var int */
private $ClubNr;
/** @var float */
private $ScoreBucholtz;
/** @var float */
private $ScoreAmerican;
/** @var int */
private $FideElo;
/** @var string */ /** @var string */
private $Nation; private $Nation;
// TODO: Implement categories
/** @var string */ /** @var string */
private $Category; private $Category;
@ -63,15 +43,12 @@ abstract class Player
/** @var Gender */ /** @var Gender */
private $Gender; private $Gender;
/** @var int */
private $NumberOfTies;
/** @var bool */
private $Absent;
/** @var Pairing[] */ /** @var Pairing[] */
private $Pairings = []; private $Pairings = [];
/** @var bool|DateTime|int|string[] */
private $BinaryData;
/** /**
* @return string * @return string
*/ */
@ -82,186 +59,84 @@ abstract class Player
/** /**
* @param string $Name * @param string $Name
* @return Player
*/ */
public function setName($Name): void public function setName(string $Name): Player
{ {
$this->Name = $Name; $this->Name = $Name;
return $this;
} }
/** /**
* @return int * @return string[]
*/ */
public function getRank(): int public function getIds(): ?array
{ {
return $this->Rank; return $this->Ids;
} }
/** /**
* @param int $Rank * @param string[] $Ids
* @return Player
*/ */
public function setRank(int $Rank): void public function setIds(array $Ids): Player
{ {
$this->Rank = $Rank; $this->Ids = $Ids;
return $this;
} }
/** /**
* @return int * @return int[]
*/ */
public function getFideId(): int public function getElos(): ?array
{ {
return $this->FideId; return $this->Elos;
} }
/** /**
* @param int $FideId * @param int[] $Elos
* @return Player
*/ */
public function setFideId(int $FideId): void public function setElos(array $Elos): Player
{ {
$this->FideId = $FideId; $this->Elos = $Elos;
return $this;
} }
/** /**
* @return int * @return \DateTime
*/ */
public function getExtraPts(): int public function getDateOfBirth(): \DateTime
{ {
return $this->ExtraPts; return $this->DateOfBirth;
} }
/** /**
* @param int $ExtraPts * @param \DateTime $DateOfBirth
* @return Player
*/ */
public function setExtraPts(int $ExtraPts): void public function setDateOfBirth(\DateTime $DateOfBirth): Player
{ {
$this->ExtraPts = $ExtraPts; $this->DateOfBirth = $DateOfBirth;
return $this;
} }
/** /**
* @return int * @return float[]
*/ */
public function getKbsbElo(): int public function getTiebreaks(): array
{ {
return $this->KbsbElo; return $this->Tiebreaks;
} }
/** /**
* @param int $KbsbElo * @param float[] $Tiebreaks
* @return Player
*/ */
public function setKbsbElo(int $KbsbElo): void public function setTiebreaks(array $Tiebreaks): Player
{ {
$this->KbsbElo = $KbsbElo; $this->Tiebreaks = $Tiebreaks;
} return $this;
/**
* @return DateTime
*/
public function getDateofbirth(): DateTime
{
return $this->dateofbirth;
}
/**
* @param DateTime $dateofbirth
*/
public function setDateofbirth(DateTime $dateofbirth): void
{
$this->dateofbirth = $dateofbirth;
}
/**
* @return int
*/
public function getKbsbID(): int
{
return $this->KbsbID;
}
/**
* @param int $KbsbID
*/
public function setKbsbID(int $KbsbID): void
{
$this->KbsbID = $KbsbID;
}
/**
* @return float
*/
public function getPoints(): float
{
return $this->Points;
}
/**
* @param float $Points
*/
public function setPoints(float $Points): void
{
$this->Points = $Points;
}
/**
* @return int
*/
public function getClubNr(): int
{
return $this->ClubNr;
}
/**
* @param int $ClubNr
*/
public function setClubNr(int $ClubNr): void
{
$this->ClubNr = $ClubNr;
}
/**
* @return float
*/
public function getScoreBucholtz(): float
{
return $this->ScoreBucholtz;
}
/**
* @param float $ScoreBucholtz
*/
public function setScoreBucholtz(float $ScoreBucholtz): void
{
$this->ScoreBucholtz = $ScoreBucholtz;
}
/**
* @return int
*/
public function getScoreAmerican(): int
{
return $this->ScoreAmerican;
}
/**
* @param int $ScoreAmerican
*/
public function setScoreAmerican(int $ScoreAmerican): void
{
$this->ScoreAmerican = $ScoreAmerican;
}
/**
* @return int
*/
public function getFideElo(): int
{
return $this->FideElo;
}
/**
* @param int $FideElo
*/
public function setFideElo(int $FideElo): void
{
$this->FideElo = $FideElo;
} }
/** /**
@ -278,10 +153,12 @@ abstract class Player
* example value: BEL * example value: BEL
* *
* @param string $Nation * @param string $Nation
* @return Player
*/ */
public function setNation(string $Nation): void public function setNation(string $Nation): Player
{ {
$this->Nation = $Nation; $this->Nation = $Nation;
return $this;
} }
/** /**
@ -294,10 +171,12 @@ abstract class Player
/** /**
* @param string $Category * @param string $Category
* @return Player
*/ */
public function setCategory(string $Category): void public function setCategory(string $Category): Player
{ {
$this->Category = $Category; $this->Category = $Category;
return $this;
} }
/** /**
@ -310,10 +189,12 @@ abstract class Player
/** /**
* @param Title $Title * @param Title $Title
* @return Player
*/ */
public function setTitle(Title $Title): void public function setTitle(Title $Title): Player
{ {
$this->Title = $Title; $this->Title = $Title;
return $this;
} }
/** /**
@ -326,42 +207,12 @@ abstract class Player
/** /**
* @param Gender $Gender * @param Gender $Gender
* @return Player
*/ */
public function setGender(Gender $Gender): void public function setGender(Gender $Gender): Player
{ {
$this->Gender = $Gender; $this->Gender = $Gender;
} return $this;
/**
* @return int
*/
public function getNumberOfTies(): int
{
return $this->NumberOfTies;
}
/**
* @param int $NumberOfTies
*/
public function setNumberOfTies(int $NumberOfTies): void
{
$this->NumberOfTies = $NumberOfTies;
}
/**
* @return bool
*/
public function getAbsent(): bool
{
return $this->Absent;
}
/**
* @param bool $Absent
*/
public function setAbsent(bool $Absent): void
{
$this->Absent = $Absent;
} }
/** /**
@ -374,9 +225,31 @@ abstract class Player
/** /**
* @param Pairing[] $Pairings * @param Pairing[] $Pairings
* @return Player
*/ */
public function setPairings(array $Pairings): void public function setPairings(array $Pairings): Player
{ {
$this->Pairings = $Pairings; $this->Pairings = $Pairings;
return $this;
}
/**
* @param string $Key
* @return bool|DateTime|int|string
*/
public function getBinaryData(string $Key)
{
return $this->BinaryData[$Key];
}
/**
* @param string $Key
* @param bool|int|DateTime|string $Value
* @return Player
*/
public function setBinaryData(string $Key, $Value): Player
{
$this->BinaryData[$Key] = $Value;
return $this;
} }
} }

View File

@ -28,35 +28,38 @@ abstract class Round
/** /**
* @return DateTime * @return DateTime
*
*/ */
public function getDate() public function getDate(): DateTime
{ {
return $this->date; return $this->date;
} }
/** /**
* @param DateTime $date * @param DateTime $date
* @return Round
*/ */
public function setDate($date): void public function setDate(DateTime $date): Round
{ {
$this->date = $date; $this->date = $date;
return $this;
} }
/** /**
* @return Game[] * @return Game[]
*/ */
public function getGames() public function getGames(): array
{ {
return $this->games; return $this->games;
} }
/** /**
* @param Game[] $games * @param Game[] $games
* @return Round
*/ */
public function setGames($games): void public function setGames(array $games): Round
{ {
$this->games = $games; $this->games = $games;
return $this;
} }
/** /**
@ -69,10 +72,12 @@ abstract class Round
/** /**
* @param int $roundNo * @param int $roundNo
* @return Round
*/ */
public function setRoundNo(int $roundNo): void public function setRoundNo(int $roundNo): Round
{ {
$this->roundNo = $roundNo; $this->roundNo = $roundNo;
return $this;
} }
/** /**
@ -85,9 +90,11 @@ abstract class Round
/** /**
* @param Pairing[] $pairings * @param Pairing[] $pairings
* @return Round
*/ */
public function setPairings(array $pairings): void public function setPairings(array $pairings): Round
{ {
$this->pairings = $pairings; $this->pairings = $pairings;
return $this;
} }
} }

View File

@ -26,6 +26,7 @@
namespace JeroenED\Libpairtwo\Models; namespace JeroenED\Libpairtwo\Models;
use JeroenED\Libpairtwo\Enums\Tiebreak;
use JeroenED\Libpairtwo\Enums\TournamentSystem; use JeroenED\Libpairtwo\Enums\TournamentSystem;
use JeroenED\Libpairtwo\Player; use JeroenED\Libpairtwo\Player;
use DateTime; use DateTime;
@ -71,7 +72,7 @@ abstract class Tournament
private $NoOfRounds; private $NoOfRounds;
/** @var Round[] */ /** @var Round[] */
private $Rounds; private $Rounds = [];
/** @var int */ /** @var int */
private $Participants; private $Participants;
@ -95,13 +96,22 @@ abstract class Tournament
private $Federation; private $Federation;
/** @var Player[] */ /** @var Player[] */
private $Players; private $Players = [];
/** @var int */ /** @var int */
private $Year; private $Year;
/** @var Pairing[] */ /** @var Pairing[] */
private $Pairings; private $Pairings = [];
/** @var Tiebreak[] */
private $Tiebreaks = [];
/** @var string */
private $PriorityElo = 'Fide';
/** @var string */
private $PriorityId = 'Nation';
/** /**
* @return string * @return string
@ -113,10 +123,12 @@ abstract class Tournament
/** /**
* @param string $Name * @param string $Name
* @return Tournament
*/ */
public function setName(string $Name): void public function setName(string $Name): Tournament
{ {
$this->Name = $Name; $this->Name = $Name;
return $this;
} }
/** /**
@ -129,26 +141,12 @@ abstract class Tournament
/** /**
* @param string $Organiser * @param string $Organiser
* @return Tournament
*/ */
public function setOrganiser(string $Organiser): void public function setOrganiser(string $Organiser): Tournament
{ {
$this->Organiser = $Organiser; $this->Organiser = $Organiser;
} return $this;
/**
* @return string
*/
public function getOrganiserClub(): string
{
return $this->OrganiserClub;
}
/**
* @param string $OrganiserClub
*/
public function setOrganiserClub(string $OrganiserClub): void
{
$this->OrganiserClub = $OrganiserClub;
} }
/** /**
@ -161,10 +159,30 @@ abstract class Tournament
/** /**
* @param int $OrganiserClubNo * @param int $OrganiserClubNo
* @return Tournament
*/ */
public function setOrganiserClubNo(int $OrganiserClubNo): void public function setOrganiserClubNo(int $OrganiserClubNo): Tournament
{ {
$this->OrganiserClubNo = $OrganiserClubNo; $this->OrganiserClubNo = $OrganiserClubNo;
return $this;
}
/**
* @return string
*/
public function getOrganiserClub(): string
{
return $this->OrganiserClub;
}
/**
* @param string $OrganiserClub
* @return Tournament
*/
public function setOrganiserClub(string $OrganiserClub): Tournament
{
$this->OrganiserClub = $OrganiserClub;
return $this;
} }
/** /**
@ -177,10 +195,12 @@ abstract class Tournament
/** /**
* @param string $OrganiserPlace * @param string $OrganiserPlace
* @return Tournament
*/ */
public function setOrganiserPlace(string $OrganiserPlace): void public function setOrganiserPlace(string $OrganiserPlace): Tournament
{ {
$this->OrganiserPlace = $OrganiserPlace; $this->OrganiserPlace = $OrganiserPlace;
return $this;
} }
/** /**
@ -193,10 +213,12 @@ abstract class Tournament
/** /**
* @param string $OrganiserCountry * @param string $OrganiserCountry
* @return Tournament
*/ */
public function setOrganiserCountry(string $OrganiserCountry): void public function setOrganiserCountry(string $OrganiserCountry): Tournament
{ {
$this->OrganiserCountry = $OrganiserCountry; $this->OrganiserCountry = $OrganiserCountry;
return $this;
} }
/** /**
@ -209,10 +231,12 @@ abstract class Tournament
/** /**
* @param int $FideHomol * @param int $FideHomol
* @return Tournament
*/ */
public function setFideHomol(int $FideHomol): void public function setFideHomol(int $FideHomol): Tournament
{ {
$this->FideHomol = $FideHomol; $this->FideHomol = $FideHomol;
return $this;
} }
/** /**
@ -225,10 +249,12 @@ abstract class Tournament
/** /**
* @param DateTime $StartDate * @param DateTime $StartDate
* @return Tournament
*/ */
public function setStartDate(DateTime $StartDate): void public function setStartDate(DateTime $StartDate): Tournament
{ {
$this->StartDate = $StartDate; $this->StartDate = $StartDate;
return $this;
} }
/** /**
@ -241,10 +267,12 @@ abstract class Tournament
/** /**
* @param DateTime $EndDate * @param DateTime $EndDate
* @return Tournament
*/ */
public function setEndDate(DateTime $EndDate): void public function setEndDate(DateTime $EndDate): Tournament
{ {
$this->EndDate = $EndDate; $this->EndDate = $EndDate;
return $this;
} }
/** /**
@ -257,10 +285,12 @@ abstract class Tournament
/** /**
* @param string $Arbiter * @param string $Arbiter
* @return Tournament
*/ */
public function setArbiter(string $Arbiter): void public function setArbiter(string $Arbiter): Tournament
{ {
$this->Arbiter = $Arbiter; $this->Arbiter = $Arbiter;
return $this;
} }
/** /**
@ -273,26 +303,30 @@ abstract class Tournament
/** /**
* @param int $NoOfRounds * @param int $NoOfRounds
* @return Tournament
*/ */
public function setNoOfRounds(int $NoOfRounds): void public function setNoOfRounds(int $NoOfRounds): Tournament
{ {
$this->NoOfRounds = $NoOfRounds; $this->NoOfRounds = $NoOfRounds;
return $this;
} }
/** /**
* @return Round[] * @return Round[]
*/ */
public function getRounds() public function getRounds(): array
{ {
return $this->Rounds; return $this->Rounds;
} }
/** /**
* @param Round[] $Rounds * @param Round[] $Rounds
* @return Tournament
*/ */
public function setRounds(array $Rounds): void public function setRounds(array $Rounds): Tournament
{ {
$this->Rounds = $Rounds; $this->Rounds = $Rounds;
return $this;
} }
/** /**
@ -305,10 +339,12 @@ abstract class Tournament
/** /**
* @param int $Participants * @param int $Participants
* @return Tournament
*/ */
public function setParticipants(int $Participants): void public function setParticipants(int $Participants): Tournament
{ {
$this->Participants = $Participants; $this->Participants = $Participants;
return $this;
} }
/** /**
@ -321,10 +357,12 @@ abstract class Tournament
/** /**
* @param string $Tempo * @param string $Tempo
* @return Tournament
*/ */
public function setTempo(string $Tempo): void public function setTempo(string $Tempo): Tournament
{ {
$this->Tempo = $Tempo; $this->Tempo = $Tempo;
return $this;
} }
/** /**
@ -337,10 +375,12 @@ abstract class Tournament
/** /**
* @param int $NonRatedElo * @param int $NonRatedElo
* @return Tournament
*/ */
public function setNonRatedElo(int $NonRatedElo): void public function setNonRatedElo(int $NonRatedElo): Tournament
{ {
$this->NonRatedElo = $NonRatedElo; $this->NonRatedElo = $NonRatedElo;
return $this;
} }
/** /**
@ -353,10 +393,12 @@ abstract class Tournament
/** /**
* @param TournamentSystem $System * @param TournamentSystem $System
* @return Tournament
*/ */
public function setSystem(TournamentSystem $System): void public function setSystem(TournamentSystem $System): Tournament
{ {
$this->System = $System; $this->System = $System;
return $this;
} }
/** /**
@ -369,10 +411,12 @@ abstract class Tournament
/** /**
* @param string $FirstPeriod * @param string $FirstPeriod
* @return Tournament
*/ */
public function setFirstPeriod(string $FirstPeriod): void public function setFirstPeriod(string $FirstPeriod): Tournament
{ {
$this->FirstPeriod = $FirstPeriod; $this->FirstPeriod = $FirstPeriod;
return $this;
} }
/** /**
@ -385,10 +429,12 @@ abstract class Tournament
/** /**
* @param string $SecondPeriod * @param string $SecondPeriod
* @return Tournament
*/ */
public function setSecondPeriod(string $SecondPeriod): void public function setSecondPeriod(string $SecondPeriod): Tournament
{ {
$this->SecondPeriod = $SecondPeriod; $this->SecondPeriod = $SecondPeriod;
return $this;
} }
/** /**
@ -401,26 +447,30 @@ abstract class Tournament
/** /**
* @param string $Federation * @param string $Federation
* @return Tournament
*/ */
public function setFederation(string $Federation): void public function setFederation(string $Federation): Tournament
{ {
$this->Federation = $Federation; $this->Federation = $Federation;
return $this;
} }
/** /**
* @return Player[] * @return Player[]
*/ */
public function getPlayers() public function getPlayers(): array
{ {
return $this->Players; return $this->Players;
} }
/** /**
* @param Player[] $Players * @param Player[] $Players
* @return Tournament
*/ */
public function setPlayers($Players): void public function setPlayers(array $Players): Tournament
{ {
$this->Players = $Players; $this->Players = $Players;
return $this;
} }
/** /**
@ -433,25 +483,82 @@ abstract class Tournament
/** /**
* @param int $Year * @param int $Year
* @return Tournament
*/ */
public function setYear(int $Year): void public function setYear(int $Year): Tournament
{ {
$this->Year = $Year; $this->Year = $Year;
return $this;
} }
/** /**
* @return Pairing[] * @return Pairing[]
*/ */
public function getPairings() public function getPairings(): array
{ {
return $this->Pairings; return $this->Pairings;
} }
/** /**
* @param Pairing[] $Pairings * @param Pairing[] $Pairings
* @return Tournament
*/ */
public function setPairings($Pairings): void public function setPairings(array $Pairings): Tournament
{ {
$this->Pairings = $Pairings; $this->Pairings = $Pairings;
return $this;
}
/**
* @return Tiebreak[]
*/
public function getTiebreaks(): array
{
return $this->Tiebreaks;
}
/**
* @param Tiebreak[] $Tiebreaks
* @return Tournament
*/
public function setTiebreaks(array $Tiebreaks): Tournament
{
$this->Tiebreaks = $Tiebreaks;
return $this;
}
/**
* @return string
*/
public function getPriorityElo(): string
{
return $this->PriorityElo;
}
/**
* @param string $PriorityElo
* @return Tournament
*/
public function setPriorityElo(string $PriorityElo): Tournament
{
$this->PriorityElo = $PriorityElo;
return $this;
}
/**
* @return string
*/
public function getPriorityId(): string
{
return $this->PriorityId;
}
/**
* @param string $PriorityId
* @return Tournament
*/
public function setPriorityId(string $PriorityId): Tournament
{
$this->PriorityId = $PriorityId;
return $this;
} }
} }

View File

@ -52,4 +52,103 @@ class Player extends PlayerModel
return $return; return $return;
} }
/**
* @param string $type
* @return int
*/
public function getElo(string $type): int
{
return $this->getElos()[$type];
}
/**
* @param string $type
* @param int $value
* @return Player
*/
public function setElo(string $type, int $value): Player
{
$currentElos = $this->getElos();
$currentElos[$type] = $value;
$this->setElos($currentElos);
return $this;
}
/**
* @param string $type
* @return string
*/
public function getId(string $type): string
{
return $this->getElos()[$type];
}
/**
* @param string $type
* @param string $value
* @return Player
*/
public function setId(string $type, string $value): Player
{
$currentIds = $this->getIds();
$currentIds[$type] = $value;
$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(string $type, int $unratedElo) : float
{
$total = 0;
$opponents = 0;
foreach ($this->getPairings() as $pairing) {
if (array_search($pairing->getResult(), Constants::NotPlayed) === false) {
$opponentElo = $pairing->getOpponent()->getElo($type);
$opponentElo = $opponentElo != 0 ? $opponentElo : $unratedElo;
if (array_search($pairing->getResult(), Constants::Won) !== false) {
$total += $opponentElo + 400;
} elseif (array_search($pairing->getResult(), Constants::Lost) !== false) {
$total += $opponentElo - 400;
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
$total += $opponentElo;
}
$opponents++;
}
}
return round($total / $opponents);
}
} }

View File

@ -16,7 +16,7 @@ abstract class Pairtwo6
private $BinaryData; private $BinaryData;
/** /**
* @return String * @return string
*/ */
public function getRelease(): string public function getRelease(): string
{ {
@ -24,11 +24,13 @@ abstract class Pairtwo6
} }
/** /**
* @param String $Release * @param string $Release
* @return Pairtwo6
*/ */
public function setRelease(string $Release): void public function setRelease(string $Release): Pairtwo6
{ {
$this->Release = $Release; $this->Release = $Release;
return $this;
} }
/** /**
@ -41,31 +43,33 @@ abstract class Pairtwo6
/** /**
* @param Tournament $Tournament * @param Tournament $Tournament
* @return Pairtwo6
*/ */
public function setTournament(Tournament $Tournament): void public function setTournament(Tournament $Tournament): Pairtwo6
{ {
$this->Tournament = $Tournament; $this->Tournament = $Tournament;
return $this;
} }
/**
* Returns binary data from the sws-file
*
* @param string
* @return string
*/
public function getBinaryData(string $key)
{
return $this->BinaryData[$key];
}
/** /**
* Sets binary data * @param string $Key
* * @return bool|DateTime|int|string
* @param string
* @param mixed
*/ */
public function setBinaryData(string $key, $data): void public function getBinaryData(string $Key)
{ {
$this->BinaryData[$key] = $data; return $this->BinaryData[$Key];
}
/**
* @param string $Key
* @param bool|int|DateTime|string $Value
* @return Pairtwo6
*/
public function setBinaryData(string $Key, $Value): Pairtwo6
{
$this->BinaryData[$Key] = $Value;
return $this;
} }
} }

View File

@ -26,6 +26,7 @@
namespace JeroenED\Libpairtwo\Readers; namespace JeroenED\Libpairtwo\Readers;
use JeroenED\Libpairtwo\Enums\Tiebreak;
use JeroenED\Libpairtwo\Enums\Title; use JeroenED\Libpairtwo\Enums\Title;
use JeroenED\Libpairtwo\Enums\Gender; use JeroenED\Libpairtwo\Enums\Gender;
use JeroenED\Libpairtwo\Enums\Color; use JeroenED\Libpairtwo\Enums\Color;
@ -59,7 +60,7 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
* @param string $filename * @param string $filename
* @return Pairtwo6 * @return Pairtwo6
*/ */
public function read($filename) public function read($filename): ReaderInterface
{ {
$swshandle = fopen($filename, 'rb'); $swshandle = fopen($filename, 'rb');
$swscontents = fread($swshandle, filesize($filename)); $swscontents = fread($swshandle, filesize($filename));
@ -77,7 +78,8 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
} }
$this->setTournament(new Tournament()); $this->setTournament(new Tournament());
$this->getTournament()->setPriorityElo('Nation');
$this->getTournament()->setPriorityId('Nation');
// UserCountry // UserCountry
$length = 4; $length = 4;
$this->setBinaryData("UserCountry", $this->readData('Int', substr($swscontents, $offset, $length))); $this->setBinaryData("UserCountry", $this->readData('Int', substr($swscontents, $offset, $length)));
@ -219,9 +221,62 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
$offset += $length; $offset += $length;
// TieOrder // TieOrder
$length = 4 * 5; for ($i = 0; $i < 5; $i++) {
$this->setBinaryData("TieOrder", $this->readData('Int', substr($swscontents, $offset, $length))); $length = 4;
switch ($this->readData('Int', substr($swscontents, $offset, $length))) {
case 1:
$tiebreak = Tiebreak::Buchholz;
break;
case 2:
$tiebreak = Tiebreak::BuchholzMed;
break;
case 3:
$tiebreak = Tiebreak::BuchholzCut;
break;
case 4:
$tiebreak = Tiebreak::Sonneborn;
break;
case 5:
$tiebreak = Tiebreak::Kashdan;
break;
case 6:
$tiebreak = Tiebreak::Cumulative;
break;
case 7:
$tiebreak = Tiebreak::Between;
break;
case 8:
$tiebreak = Tiebreak::Koya;
break;
case 9:
$tiebreak = Tiebreak::Baumbach;
break;
case 10:
$tiebreak = Tiebreak::Performance;
break;
case 11:
$tiebreak = Tiebreak::Aro;
break;
case 12:
$tiebreak = Tiebreak::AroCut;
break;
case 13:
$tiebreak = Tiebreak::BlackPlayed;
break;
case 14:
$tiebreak = Tiebreak::Testmatch;
break;
case 15:
$tiebreak = Tiebreak::Drawing;
break;
case 0:
default:
$tiebreak = Tiebreak::None;
break;
}
$this->getTournament()->addTieBreak(new Tiebreak($tiebreak));
$offset += $length; $offset += $length;
}
// Categorie // Categorie
$length = 4 * 10; $length = 4 * 10;
@ -242,24 +297,25 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
for ($i = 0; $i < $this->getBinaryData("NewPlayer"); $i++) { for ($i = 0; $i < $this->getBinaryData("NewPlayer"); $i++) {
$player = new Player(); $player = new Player();
// Rank (Unused value)
$length = 4; $length = 4;
$player->SetRank($this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("Rank", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$this->setBinaryData("Players($i)_NamePos", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("NamePos", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->SetFideId($this->readData('Int', substr($swscontents, $offset, $length))); $player->setId('Fide', $this->readData('Int', substr($swscontents, $offset, $length) . ""));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->SetExtraPts($this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("ExtraPts", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->SetKbsbElo($this->readData('Int', substr($swscontents, $offset, $length))); $player->setElo('Nation', $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
@ -267,35 +323,35 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setKbsbID($this->readData('Int', substr($swscontents, $offset, $length))); $player->setId('Nation', $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setPoints($this->readData('Int', substr($swscontents, $offset, $length)) / 2); $player->setBinaryData("Points", $this->readData('Int', substr($swscontents, $offset, $length)) / 2);
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setClubNr($this->readData('Int', substr($swscontents, $offset, $length))); $player->setId('Club', $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setScoreBucholtz($this->readData('Int', substr($swscontents, $offset, $length)) / 2); $player->setBinaryData("ScoreBuchholz", $this->readData('Int', substr($swscontents, $offset, $length)) / 2);
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setScoreAmerican($this->readData('Int', substr($swscontents, $offset, $length)) / 2); $player->setBinaryData("ScoreAmerican", $this->readData('Int', substr($swscontents, $offset, $length)) / 2);
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$this->setBinaryData("Players($i)_HelpValue", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("HelpValue", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 4; $length = 4;
$player->setFideElo($this->readData('Int', substr($swscontents, $offset, $length))); $player->setElo('Fide', $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_NameLength", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("NameLength", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 3; $length = 3;
@ -368,39 +424,39 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$player->setNumberOfTies($this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData('NumberOfTies', $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$player->setAbsent($this->readData('Bool', substr($swscontents, $offset, $length))); $player->setBinaryData('Absent', $this->readData('Bool', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_ColorDiff", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("ColorDiff", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_ColorPref", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("ColorPref", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_Paired", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("Paired", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_Float", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("Float", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_FloatPrev", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("FloatPrev", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_FloatBefore", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("FloatBefore", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$length = 1; $length = 1;
$this->setBinaryData("Players($i)_TieMatch", $this->readData('Int', substr($swscontents, $offset, $length))); $player->setBinaryData("TieMatch", $this->readData('Int', substr($swscontents, $offset, $length)));
$offset += $length; $offset += $length;
$this->getTournament()->addPlayer($player); $this->getTournament()->addPlayer($player);
@ -411,9 +467,9 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
$offset += $length; $offset += $length;
for ($i = 0; $i < $this->getBinaryData("NewPlayer"); $i++) { for ($i = 0; $i < $this->getBinaryData("NewPlayer"); $i++) {
$namelength = $this->getBinaryData("Players($i)_NameLength");
$nameoffset = $this->getBinaryData("Players($i)_NamePos");
$player = $this->getTournament()->getPlayerById($i); $player = $this->getTournament()->getPlayerById($i);
$namelength = $player->getBinaryData("NameLength");
$nameoffset = $player->getBinaryData("NamePos");
$player->setName($this->readData("String", substr($this->getBinaryData("PlayerNames"), $nameoffset, $namelength))); $player->setName($this->readData("String", substr($this->getBinaryData("PlayerNames"), $nameoffset, $namelength)));
$this->getTournament()->updatePlayer($i, $player); $this->getTournament()->updatePlayer($i, $player);
@ -499,7 +555,7 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
$system = TournamentSystem::American; $system = TournamentSystem::American;
break; break;
case 6: case 6:
$system = TournamentSystem::Imperial; $system = TournamentSystem::Keizer;
break; break;
case 0: case 0:
default: default:
@ -637,6 +693,8 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
} }
} }
$this->addTiebreaks();
$this->getTournament()->pairingsToRounds(); $this->getTournament()->pairingsToRounds();
return $this; return $this;
} }
@ -742,4 +800,27 @@ class Pairtwo6 extends Pairtwo6Model implements ReaderInterface
return DateTime::createFromFormat($format, $concat); return DateTime::createFromFormat($format, $concat);
} }
/**
* @return $this
*/
private function addTiebreaks(): Pairtwo6
{
switch ($this->getTournament()->getSystem()) {
case TournamentSystem::Keizer:
$firstElement = new Tiebreak(Tiebreak::Keizer);
break;
case TournamentSystem::American:
$firstElement = new Tiebreak(Tiebreak::American);
break;
case TournamentSystem::Closed:
case TournamentSystem::Swiss:
$firstElement = new Tiebreak(Tiebreak::Points);
}
$tiebreaks = $this->getTournament()->getTiebreaks();
array_unshift($tiebreaks, $firstElement);
$this->getTournament()->setTiebreaks($tiebreaks);
return $this;
}
} }

View File

@ -26,7 +26,7 @@
namespace JeroenED\Libpairtwo; namespace JeroenED\Libpairtwo;
use JeroenED\LibPairtwo\Exceptions\LibpairtwoException;
/** /**
* This class reads a SWS file * This class reads a SWS file
@ -41,13 +41,13 @@ class Sws
* Reads out $swsfile and returns a Pairtwo6 class object * Reads out $swsfile and returns a Pairtwo6 class object
* *
* @param string $swsfile * @param string $swsfile
* @throws LibpairtwoException
* @deprecated * @deprecated
*/ */
public static function ReadSws(string $swsfile) public static function ReadSws(string $swsfile)
{ {
trigger_error ( "This function is deprecated. Please convert your code to use the new pattern. More info to be found on Github (https://github.com/JeroenED/libpairtwo/wiki/Converting-your-code-to-the-generalized-format).", E_USER_DEPRECATED); trigger_error("This function is deprecated. Please convert your code to use the new pattern. More info to be found on Github (https://github.com/JeroenED/libpairtwo/wiki/Converting-your-code-to-the-generalized-format).", E_USER_DEPRECATED);
$reader = IOFactory::createReader("Pairtwo-6"); $reader = IOFactory::createReader("Pairtwo-6");
return $reader->read($swsfile); return $reader->read($swsfile);
} }
} }

295
src/Tiebreaks.php Normal file
View File

@ -0,0 +1,295 @@
<?php
namespace JeroenED\Libpairtwo;
use JeroenED\Libpairtwo\Enums\Color;
use JeroenED\Libpairtwo\Models\Tournament;
use JeroenED\Libpairtwo\Enums\Result;
abstract class Tiebreaks extends Tournament
{
/**
* @param Player $player
* @return float|null
*/
protected function calculateKeizer(Player $player): ?float
{
return $player->getBinaryData('ScoreAmerican');
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateAmerican(Player $player): ?float
{
return $player->getBinaryData('ScoreAmerican');
}
/**
* @param Player $player
* @return float|null
*/
protected function calculatePoints(Player $player): ?float
{
return $player->getPoints();
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateBaumbach(Player $player): ?float
{
$totalwins = 0;
foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getResult(), Constants::Won) !== false) {
$totalwins++;
}
}
return $totalwins;
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateBlackPlayed(Player $player): ?float
{
$totalwins = 0;
foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getColor(), Constants::Black) !== false) {
$totalwins++;
}
}
return $totalwins;
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateBlackWin(Player $player): ?float
{
$totalwins = 0;
foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getColor(), Constants::Black) !== false && array_search($pairing->getResult(), Constants::Won) !== false) {
$totalwins++;
}
}
return $totalwins;
}
/**
* @param Player $player
* @param array $opponents
* @param int $key
* @return float|null
*/
protected function calculateMutualResult(Player $player, array $opponents, int $key): ?float
{
$interestingplayers = $opponents;
if ($key != 0) {
$interestingplayers = [];
foreach ($opponents as $opponent) {
if (($opponent->getTiebreaks()[$key - 1] == $player->getTiebreaks()[$key - 1]) && ($player != $opponent)) {
$interestingplayers[] = $opponent;
}
}
}
$points = 0;
$totalmatches = 0;
foreach ($player->getPairings() as $pairing) {
if (array_search($pairing->getOpponent(), $interestingplayers) !== false) {
if (array_search($pairing->getResult(), Constants::Won) !== false) {
$points = $points + 1;
} elseif (array_search($pairing->getResult(), Constants::Draw) !== false) {
$points = $points + 0.5;
}
$totalmatches++;
}
}
if ($totalmatches != count($interestingplayers)) {
$points = null;
}
return $points;
}
/**
* @param Player $player
* @param int $cut
* @return float
*/
protected function calculateAverageRating(Player $player, string $type, int $cut = 0): ?float
{
$pairings = $player->getPairings();
$allratings = [];
foreach ($pairings as $pairing) {
if (array_search($pairing->getResult(), Constants::NotPlayed) === false) {
$toadd = $pairing->getOpponent()->getElo($type);
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 calculateAveragePerformance(Player $player, string $type, int $cut = 0): ?float
{
$pairings = $player->getPairings();
$allratings = [];
foreach ($pairings as $pairing) {
if (array_search($pairing->getResult(), Constants::NotPlayed) === false) {
$toadd = $pairing->getOpponent()->getPerformance($type, $this->getNonRatedElo());
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()->getPoints() / count($plpairing->getOpponent()->getPairings()) * 100) >= $cut) {
if (array_search($plpairing->getResult(), Constants::Won) !== false) {
$tiebreak += 1;
} elseif (array_search($plpairing->getResult(), Constants::Draw) !== false) {
$tiebreak += 0.5;
}
}
}
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 (is_null($a->getOpponent())) {
return -1;
}
if (is_null($b->getOpponent())) {
return 1;
}
if ($b->getOpponent()->getPoints() == $a->getOpponent()->getPoints()) {
return 0;
}
return ($a->getOpponent()->getPoints() > $b->getOpponent()->getPoints()) ? 1 : -1;
});
$intpairings = array_slice($intpairings, $cutlowest);
$intpairings = array_slice($intpairings, 0, 0 - $cuthighest);
foreach ($intpairings as $intkey => $intpairing) {
if (!is_null($intpairing->getOpponent())) {
$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 ($pairing->getOpponent()) {
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 = 1;
} elseif (array_search($pairing->getResult(), Constants::Lost) !== false) {
$toadd = 0;
}
if (array_search($pairing->getResult(), Constants::NotPlayed) !== false) {
$toadd = -1;
}
$tiebreak += $toadd;
}
return $tiebreak; // - $player->getNoOfWins();
}
/**
* @param Player $player
* @return float|null
*/
protected function calculateCumulative(Player $player): ?float
{
$tiebreak = 0;
$score = [];
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 += $toadd;
$score[] = $tiebreak;
}
return array_sum($score);
}
}

View File

@ -8,10 +8,10 @@
namespace JeroenED\Libpairtwo; namespace JeroenED\Libpairtwo;
use JeroenED\Libpairtwo\Models\Tournament as TournamentModel; use JeroenED\Libpairtwo\Enums\Tiebreak;
use JeroenED\Libpairtwo\Enums\Color; use JeroenED\Libpairtwo\Enums\Color;
class Tournament extends TournamentModel class Tournament extends Tiebreaks
{ {
/** /**
* Gets a player by its ID * Gets a player by its ID
@ -49,6 +49,18 @@ class Tournament extends TournamentModel
$this->setPlayers($newArray); $this->setPlayers($newArray);
} }
/**
* Adds a Tiebreak
*
* @param Tiebreak $tiebreak
*/
public function addTiebreak(Tiebreak $tiebreak)
{
$newArray = $this->getTiebreaks();
$newArray[] = $tiebreak;
$this->setTiebreaks($newArray);
}
/** /**
* Adds a round with given Round object * Adds a round with given Round object
* *
@ -190,35 +202,150 @@ class Tournament extends TournamentModel
/** /**
* Gets the ranking of the tournament * Gets the ranking of the tournament
* *
* @param bool $americansort
* @return Player[] * @return Player[]
*/ */
public function getRanking(bool $americansort = false) public function getRanking()
{ {
$players = $this->getPlayers(); $players = $this->getPlayers();
foreach ($this->getTiebreaks() as $tbkey=>$tiebreak) {
$americansort ? usort($players, array($this, "SortAmerican")) : usort($players, array($this, "SortNormal")); foreach ($players as $pkey => $player) {
$break = $this->calculateTiebreak($tiebreak, $player, $tbkey);
return $players; $tiebreaks = $player->getTiebreaks();
$tiebreaks[$tbkey] = $break;
$player->setTiebreaks($tiebreaks);
$this->updatePlayer($pkey, $player);
}
}
$sortedplayers[0] = $players;
foreach ($this->getTiebreaks() 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->getTiebreaks()[$tbkey])) {
if ($playerkey != 0) {
$newgroupkey++;
if ($player->getTiebreaks()[$tbkey] == $tosortplayers[$groupkey][$playerkey - 1]->getTiebreaks()[$tbkey]) {
$newgroupkey--;
}
}
}
$sortedplayers[$newgroupkey][] = $player;
}
$newgroupkey++;
}
}
$finalarray = [];
foreach ($sortedplayers as $sort1) {
foreach ($sort1 as $player) {
$finalarray[] = $player;
}
}
return $finalarray;
} }
/** /**
* @param Player $a * @param Player $a
* @param Player $b * @param Player $b
* @return int * @return \Closure
*/ */
private function sortNormal(Player $a, Player $b)
private function sortTiebreak(int $key)
{ {
return $b->getPoints() - $a->getPoints(); return function (Player $a, Player $b) use ($key) {
if (($b->getTiebreaks()[$key] == $a->getTiebreaks()[$key]) || ($a->getTiebreaks()[$key] === false) || ($b->getTiebreaks()[$key] === false)) {
return 0;
}
return ($b->getTiebreaks()[$key] > $a->getTiebreaks()[$key]) ? +1 : -1;
};
}
/**
* @return float|null
*/
private function calculateTiebreak(Tiebreak $tiebreak, Player $player, int $tbkey = 0): ?float
{
switch ($tiebreak) {
case Tiebreak::Keizer:
return $this->calculateKeizer($player);
break;
case Tiebreak::American:
return $this->calculateAmerican($player);
break;
case Tiebreak::Points:
return $this->calculatePoints($player);
break;
case Tiebreak::Baumbach:
return $this->calculateBaumbach($player);
break;
case Tiebreak::BlackPlayed:
return $this->calculateBlackPlayed($player);
break;
case Tiebreak::BlackWin:
return $this->calculateBlackWin($player);
break;
case Tiebreak::Between:
return $this->calculateMutualResult($player, $this->getPlayers(), $tbkey);
break;
case Tiebreak::Aro:
return $this->calculateAverageRating($player, $this->getPriorityElo());
break;
case Tiebreak::AroCut:
return $this->calculateAverageRating($player, $this->getPriorityElo(), 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::AveragePerformance:
return $this->calculateAveragePerformance($player, $this->getPriorityElo());
break;
case Tiebreak::Performance:
return $player->getPerformance($this->getPriorityElo(), $this->getNonRatedElo());
break;
default:
return null;
}
} }
/** /**
* @param Player $a * Return the average rating for tournament
* @param Player $b *
* @return int * @return int
*/ */
private function sortAmerican(Player $a, Player $b) public function getAverageElo(): int
{ {
return $b->getScoreAmerican() - $a->getScoreAmerican(); $totalrating = 0;
$players = 0;
foreach ($this->getPlayers() as $player) {
$toadd = $player->getElo($this->getPriorityElo());
if ($toadd == 0) {
$toadd = $this->getNonRatedElo();
}
$totalrating += $toadd;
$players++;
}
return intdiv($totalrating, $players);
} }
} }

View File

@ -46,21 +46,21 @@ echo "Place: " . $sws->getTournament()->getOrganiserPlace() . PHP_EOL;
echo "Unrated-Elo: " . $sws->getTournament()->getNonRatedElo() . PHP_EOL; echo "Unrated-Elo: " . $sws->getTournament()->getNonRatedElo() . PHP_EOL;
echo "Federation: " . $sws->getTournament()->getFederation() . PHP_EOL; echo "Federation: " . $sws->getTournament()->getFederation() . PHP_EOL;
echo "Organiser: " . $sws->getTournament()->getOrganiserClubNo() . PHP_EOL; echo "Organiser: " . $sws->getTournament()->getOrganiserClubNo() . PHP_EOL;
echo "Fide Elo P1: " . $sws->getTournament()->getPlayerById(0)->getFideElo() . PHP_EOL; echo "Fide Elo P1: " . $sws->getTournament()->getPlayerById(0)->getElo('Fide') . PHP_EOL;
echo "Fide Elo P2: " . $sws->getTournament()->getPlayerById(1)->getFideElo() . PHP_EOL; echo "Fide Elo P2: " . $sws->getTournament()->getPlayerById(1)->getElo('Fide') . PHP_EOL;
echo "Fide Elo P3: " . $sws->getTournament()->getPlayerById(2)->getFideElo() . PHP_EOL; echo "Fide Elo P3: " . $sws->getTournament()->getPlayerById(2)->getElo('Fide') . PHP_EOL;
echo "KBSB Elo P1: " . $sws->getTournament()->getPlayerById(0)->getKbsbElo() . PHP_EOL; echo "KBSB Elo P1: " . $sws->getTournament()->getPlayerById(0)->getElo('Nation') . PHP_EOL;
echo "KBSB Elo P2: " . $sws->getTournament()->getPlayerById(1)->getKbsbElo() . PHP_EOL; echo "KBSB Elo P2: " . $sws->getTournament()->getPlayerById(1)->getElo('Nation') . PHP_EOL;
echo "KBSB Elo P3: " . $sws->getTournament()->getPlayerById(2)->getKbsbElo() . PHP_EOL; echo "KBSB Elo P3: " . $sws->getTournament()->getPlayerById(2)->getElo('Nation') . PHP_EOL;
echo "Name P1: " . $sws->getTournament()->getPlayerById(0)->getName() . PHP_EOL; echo "Name P1: " . $sws->getTournament()->getPlayerById(0)->getName() . PHP_EOL;
echo "Name P2: " . $sws->getTournament()->getPlayerById(1)->getName() . PHP_EOL; echo "Name P2: " . $sws->getTournament()->getPlayerById(1)->getName() . PHP_EOL;
echo "Name P3: " . $sws->getTournament()->getPlayerById(2)->getName() . PHP_EOL; echo "Name P3: " . $sws->getTournament()->getPlayerById(2)->getName() . PHP_EOL;
echo "Gender P1: " . $sws->getTournament()->getPlayerById(0)->getGender()->getKey() . PHP_EOL; echo "Gender P1: " . $sws->getTournament()->getPlayerById(0)->getGender()->getKey() . PHP_EOL;
echo "Gender P2: " . $sws->getTournament()->getPlayerById(1)->getGender()->getKey() . PHP_EOL; echo "Gender P2: " . $sws->getTournament()->getPlayerById(1)->getGender()->getKey() . PHP_EOL;
echo "Gender P3: " . $sws->getTournament()->getPlayerById(2)->getGender()->getKey() . PHP_EOL; echo "Gender P3: " . $sws->getTournament()->getPlayerById(2)->getGender()->getKey() . PHP_EOL;
echo "Absent P1: " . $sws->getTournament()->getPlayerById(0)->getAbsent() . PHP_EOL; echo "Absent P1: " . $sws->getTournament()->getPlayerById(0)->getBinaryData("Absent") . PHP_EOL;
echo "Absent P2: " . $sws->getTournament()->getPlayerById(1)->getAbsent() . PHP_EOL; echo "Absent P2: " . $sws->getTournament()->getPlayerById(1)->getBinaryData("Absent") . PHP_EOL;
echo "Absent P3: " . $sws->getTournament()->getPlayerById(2)->getAbsent() . PHP_EOL; echo "Absent P3: " . $sws->getTournament()->getPlayerById(2)->getBinaryData("Absent") . PHP_EOL;
echo "Date Round 1: " . $sws->getTournament()->getRoundByNo(0)->getDate()->format('d/m/Y') . PHP_EOL; echo "Date Round 1: " . $sws->getTournament()->getRoundByNo(0)->getDate()->format('d/m/Y') . PHP_EOL;
echo "Date Round 2: " . $sws->getTournament()->getRoundByNo(1)->getDate()->format('d/m/Y') . PHP_EOL; echo "Date Round 2: " . $sws->getTournament()->getRoundByNo(1)->getDate()->format('d/m/Y') . PHP_EOL;
echo "Date Round 3: " . $sws->getTournament()->getRoundByNo(2)->getDate()->format('d/m/Y') . PHP_EOL; echo "Date Round 3: " . $sws->getTournament()->getRoundByNo(2)->getDate()->format('d/m/Y') . PHP_EOL;
@ -70,3 +70,22 @@ echo "Color Pairing 3: " . $sws->getTournament()->getPairings()[3]->getColor()->
echo "Player Pairing 1: " . $sws->getTournament()->getPairings()[0]->getPlayer()->getName() . PHP_EOL; echo "Player Pairing 1: " . $sws->getTournament()->getPairings()[0]->getPlayer()->getName() . PHP_EOL;
echo "Player Pairing 2: " . $sws->getTournament()->getPairings()[1]->getPlayer()->getName() . PHP_EOL; echo "Player Pairing 2: " . $sws->getTournament()->getPairings()[1]->getPlayer()->getName() . PHP_EOL;
echo "Player Pairing 3: " . $sws->getTournament()->getPairings()[2]->getPlayer()->getName() . PHP_EOL; echo "Player Pairing 3: " . $sws->getTournament()->getPairings()[2]->getPlayer()->getName() . PHP_EOL;
echo "Tiebreak 1: " . $sws->getTournament()->getTiebreaks()[0]->getValue() . PHP_EOL;
echo "Tiebreak 2: " . $sws->getTournament()->getTiebreaks()[1]->getValue() . PHP_EOL;
echo "Tiebreak 3: " . $sws->getTournament()->getTiebreaks()[2]->getValue() . PHP_EOL;
echo "Tiebreak 4: " . $sws->getTournament()->getTiebreaks()[3]->getValue() . PHP_EOL;
echo "Tiebreak 5: " . $sws->getTournament()->getTiebreaks()[4]->getValue() . PHP_EOL;
echo "Tiebreak 6: " . $sws->getTournament()->getTiebreaks()[5]->getValue() . PHP_EOL;
echo "Average Elo: " . $sws->getTournament()->getAverageElo() . PHP_EOL;
foreach ($sws->getTournament()->getRanking() as $player) {
echo str_pad($player->getName() . '(' . $player->getElo($sws->getTournament()->getPriorityElo()) . ') ', 35) . implode_pad(' ', $player->getTiebreaks(), 5, ' ') . PHP_EOL;
}
function implode_pad($glue, $collection, $padlength, $padstring): string
{
$newarray = [];
foreach ($collection as $elem) {
$newarray[] = str_pad($elem, $padlength, $padstring);
}
return implode($glue, $newarray);
}