Merge branch 'task/boardno' into develop

This commit is contained in:
Jeroen De Meerleer 2019-09-28 21:48:21 +02:00
commit 6c2aed46e8
Signed by: JeroenED
GPG Key ID: 28CCCB8F62BFADD6
12 changed files with 207 additions and 103 deletions

View File

@ -1,6 +1,8 @@
# CHANGELOG # CHANGELOG
## vx.y.z (Release: aa-bbb-cccc) ## vx.y.z (Release: aa-bbb-cccc)
* NEW FEATURE: `Game::getBoard()` for getting the board number of the game
* ENHANCEMENT: Some fields has been renamed to match coding guideline (Please see [1ab96fa](https://github.com/JeroenED/libpairtwo/commit/1ab96fa04782c1b0f2b6bb9d1bac8397a74ab38e) for more info)
## v1.2 (Release: 28-sep-2019) ## v1.2 (Release: 28-sep-2019)
* NEW READER: `Reader::swar-4` for reading out files created with SWAR version 4. * NEW READER: `Reader::swar-4` for reading out files created with SWAR version 4.

5
dist/template.php vendored
View File

@ -40,11 +40,12 @@ foreach ($reader->getTournament()->getRounds() as $round) {
echo '<table>' . PHP_EOL; echo '<table>' . PHP_EOL;
echo '<thead>' . PHP_EOL; echo '<thead>' . PHP_EOL;
echo '<tr><th>White</th><th>Black</th><th>Result</th></tr>' . PHP_EOL; echo '<tr><th></th><th>White</th><th>Black</th><th>Result</th></tr>' . PHP_EOL;
echo '</thead>' . PHP_EOL; echo '</thead>' . PHP_EOL;
echo '<tbody>' . PHP_EOL; echo '<tbody>' . PHP_EOL;
foreach ($round->getGames() as $game) { foreach ($round->getGamesByBoard() as $game) {
echo '<tr>' . PHP_EOL; echo '<tr>' . PHP_EOL;
echo '<td>' . ($game->getBoard() + 1) . '</td>' . PHP_EOL;
echo '<td>' . $game->getWhite()->getPlayer()->getName() . '</td>' . PHP_EOL; echo '<td>' . $game->getWhite()->getPlayer()->getName() . '</td>' . PHP_EOL;
echo '<td>' . $game->getBlack()->getPlayer()->getName() . '</td>' . PHP_EOL; echo '<td>' . $game->getBlack()->getPlayer()->getName() . '</td>' . PHP_EOL;
echo '<td>' . $game->getResult()->getValue() . '</td>' . PHP_EOL; echo '<td>' . $game->getResult()->getValue() . '</td>' . PHP_EOL;

View File

@ -27,11 +27,11 @@ use JeroenED\Libpairtwo\Enums\Result;
*/ */
class Constants class Constants
{ {
const Won = [ Result::won, Result::wonforfait, Result::wonbye, Result::wonadjourned ]; const Won = [ Result::Won, Result::WonForfait, Result::WonBye, Result::WonAdjourned ];
const Draw = [ Result::draw, Result::drawadjourned ]; const Draw = [ Result::Draw, Result::DrawAdjourned ];
const Lost = [ Result::absent, Result::bye, Result::lost, Result::adjourned ]; const Lost = [ Result::Absent, Result::Bye, Result::Lost, Result::Adjourned ];
const NotPlayed = [ Result::bye, Result::wonbye, Result::absent ]; const NotPlayed = [ Result::Bye, Result::WonBye, Result::Absent ];
const Played = [ Result::won, Result::wonforfait, Result::wonbye, Result::wonadjourned, Result::draw, Result::drawadjourned, Result::absent, Result::bye, Result::lost, Result::adjourned ]; const Played = [ Result::Won, Result::WonForfait, Result::WonBye, Result::WonAdjourned, Result::Draw, Result::DrawAdjourned, Result::Absent, Result::Bye, Result::Lost, Result::Adjourned ];
const Black = [ Color::black ]; const Black = [ Color::Black ];
const White = [ Color::white ]; const White = [ Color::White ];
} }

View File

@ -26,7 +26,7 @@ use MyCLabs\Enum\Enum;
*/ */
class Color extends Enum class Color extends Enum
{ {
const black = 'B'; const Black = 'B';
const white = 'W'; const White = 'W';
const none = '*'; const None = '*';
} }

View File

@ -26,15 +26,15 @@ use MyCLabs\Enum\Enum;
*/ */
class Result extends Enum class Result extends Enum
{ {
const none = '*'; const None = '*';
const lost = '0'; const Lost = '0';
const draw = '0.5'; const Draw = '0.5';
const won = '1'; const Won = '1';
const absent = '0 FF'; const Absent = '0 FF';
const wonforfait = '1 FF'; const WonForfait = '1 FF';
const adjourned = '0 A'; const Adjourned = '0 A';
const drawadjourned = '0.5 A'; const DrawAdjourned = '0.5 A';
const wonadjourned = '1 A'; const WonAdjourned = '1 A';
const bye = '0 Bye'; const Bye = '0 Bye';
const wonbye = '1 Bye'; const WonBye = '1 Bye';
} }

View File

@ -29,13 +29,16 @@ use DateTime;
class Game class Game
{ {
/** @var Pairing | null */ /** @var Pairing | null */
private $white; private $White;
/** @var Pairing | null */ /** @var Pairing | null */
private $black; private $Black;
/** @var GameResult | null */ /** @var GameResult | null */
private $result; private $Result;
/** @var int */
private $Board;
/** /**
* Returns the result for the game * Returns the result for the game
@ -44,8 +47,8 @@ class Game
*/ */
public function getResult(): Gameresult public function getResult(): Gameresult
{ {
if (!is_null($this->result)) { if (!is_null($this->Result)) {
return $this->result; return $this->Result;
} }
$whiteResult = $this->getWhite()->getResult(); $whiteResult = $this->getWhite()->getResult();
@ -80,18 +83,18 @@ class Game
*/ */
public function getWhite(): ?Pairing public function getWhite(): ?Pairing
{ {
return $this->white; return $this->White;
} }
/** /**
* Sets pairing for white player * Sets pairing for white player
* *
* @param Pairing | null $white * @param Pairing | null $White
* @return Game * @return Game
*/ */
public function setWhite(?Pairing $white): Game public function setWhite(?Pairing $White): Game
{ {
$this->white = $white; $this->White = $White;
return $this; return $this;
} }
@ -102,30 +105,50 @@ class Game
*/ */
public function getBlack(): ?Pairing public function getBlack(): ?Pairing
{ {
return $this->black; return $this->Black;
} }
/** /**
* Sets pairing for black player * Sets pairing for black player
* *
* @param Pairing | null $black * @param Pairing | null $Black
* @return Game * @return Game
*/ */
public function setBlack(?Pairing $black): Game public function setBlack(?Pairing $Black): Game
{ {
$this->black = $black; $this->Black = $Black;
return $this; return $this;
} }
/** /**
* Sets result for game * Sets result for game
* *
* @param Gameresult | null $result * @param Gameresult | null $Result
* @return Game * @return Game
*/ */
public function setResult(?Gameresult $result): Game public function setResult(?Gameresult $Result): Game
{ {
$this->result = $result; $this->Result = $Result;
return $this; return $this;
} }
/**
* Sets the board no of the game
*
* @return int
*/
public function getBoard(): int
{
return $this->Board;
}
/**
* Returns the board no of the game
*
* @param int $Board
*/
public function setBoard(int $Board): void
{
$this->Board = $Board;
}
} }

View File

@ -33,7 +33,7 @@ abstract class IOFactory
* *
* @var array * @var array
*/ */
private static $readers = [ private static $Readers = [
'Swar-4' => Readers\Swar4::class, 'Swar-4' => Readers\Swar4::class,
'Pairtwo-6' => Readers\Pairtwo6::class, 'Pairtwo-6' => Readers\Pairtwo6::class,
'Pairtwo-5' => Readers\Pairtwo6::class // File structure identical 'Pairtwo-5' => Readers\Pairtwo6::class // File structure identical
@ -51,12 +51,12 @@ abstract class IOFactory
*/ */
public static function createReader(string $type): ReaderInterface public static function createReader(string $type): ReaderInterface
{ {
if (!isset(self::$readers[$type])) { if (!isset(self::$Readers[$type])) {
throw new LibpairtwoException("Cannot read type $type"); throw new LibpairtwoException("Cannot read type $type");
} }
// create reader class // create reader class
$readerClass = self::$readers[$type]; $readerClass = self::$Readers[$type];
$reader = new $readerClass; $reader = new $readerClass;
return $reader; return $reader;

View File

@ -42,6 +42,9 @@ class Pairing
/** @var int */ /** @var int */
private $Round; private $Round;
/** @var int */
private $Board;
/** /**
* Returns the player of the pairing * Returns the player of the pairing
* *
@ -151,4 +154,24 @@ class Pairing
$this->Round = $Round; $this->Round = $Round;
return $this; return $this;
} }
/**
* Sets the board no of the pairing
*
* @return int
*/
public function getBoard(): int
{
return $this->Board;
}
/**
* Returns the board no of the pairing
*
* @param int $Board
*/
public function setBoard(int $Board): void
{
$this->Board = $Board;
}
} }

View File

@ -703,15 +703,15 @@ class Pairtwo6 implements ReaderInterface
switch ($this->readData('Int', substr($swscontents, $offset, $length))) { switch ($this->readData('Int', substr($swscontents, $offset, $length))) {
case 255: case 255:
case 253: case 253:
$color = Color::black; $color = Color::Black;
break; break;
case 1: case 1:
case 3: case 3:
$color = Color::white; $color = Color::White;
break; break;
case 0: case 0:
default: default:
$color = Color::none; $color = Color::None;
break; break;
} }
$pairing->setColor(new Color($color)); $pairing->setColor(new Color($color));
@ -720,38 +720,38 @@ class Pairtwo6 implements ReaderInterface
$length = 1; $length = 1;
switch ($this->readData('Int', substr($swscontents, $offset, $length))) { switch ($this->readData('Int', substr($swscontents, $offset, $length))) {
case 1: case 1:
$result = Result::lost; $result = Result::Lost;
break; break;
case 2: case 2:
$result = Result::absent; $result = Result::Absent;
break; break;
case 3: case 3:
$result = Result::adjourned; $result = Result::Adjourned;
break; break;
case 4: case 4:
$result = Result::bye; $result = Result::Bye;
break; break;
case 6: case 6:
$result = Result::draw; $result = Result::Draw;
break; break;
case 8: case 8:
$result = Result::drawadjourned; $result = Result::DrawAdjourned;
break; break;
case 11: case 11:
$result = Result::won; $result = Result::Won;
break; break;
case 12: case 12:
$result = Result::wonforfait; $result = Result::WonForfait;
break; break;
case 13: case 13:
$result = Result::wonadjourned; $result = Result::WonAdjourned;
break; break;
case 14: case 14:
$result = Result::wonbye; $result = Result::WonBye;
break; break;
case 0: case 0:
default: default:
$result = Result::none; $result = Result::None;
break; break;
} }
$pairing->setResult(new Result($result)); $pairing->setResult(new Result($result));
@ -760,6 +760,7 @@ class Pairtwo6 implements ReaderInterface
$pairing->setRound($x); $pairing->setRound($x);
$offset += 2; $offset += 2;
$pairing->setBoard(-1);
if ($x < $this->getBinaryData("CurrentRound")) { if ($x < $this->getBinaryData("CurrentRound")) {
$this->getTournament()->addPairing($pairing); $this->getTournament()->addPairing($pairing);
} }

View File

@ -37,10 +37,10 @@ class Swar4 implements ReaderInterface
private $tournament; private $tournament;
/** @var bool|int|DateTime|string[] */ /** @var bool|int|DateTime|string[] */
private $binaryData; private $BinaryData;
/** @var string */ /** @var string */
private $release; private $Release;
/** @var array */ /** @var array */
private const CompatibleVersions = ['v4.']; private const CompatibleVersions = ['v4.'];
@ -405,7 +405,7 @@ class Swar4 implements ReaderInterface
for ($j = 0; $j < $player->getBinaryData('AllocatedRounds'); $j++) { for ($j = 0; $j < $player->getBinaryData('AllocatedRounds'); $j++) {
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_player', $i); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_player', $i);
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_round', $this->readData('Int', $swshandle) - 1); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_round', $this->readData('Int', $swshandle) - 1);
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_table', $this->readData('Int', $swshandle)); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_table', $this->readData('Int', $swshandle) - 1);
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_opponent', $this->readData('Int', $swshandle)); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_opponent', $this->readData('Int', $swshandle));
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_result', $this->readData('Hex', $swshandle)); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_result', $this->readData('Hex', $swshandle));
$this->getTournament()->setBinaryData('Pairing_' . $pt . '_color', $this->readData('Int', $swshandle)); $this->getTournament()->setBinaryData('Pairing_' . $pt . '_color', $this->readData('Int', $swshandle));
@ -430,49 +430,51 @@ class Swar4 implements ReaderInterface
} }
switch ($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_result')) { switch ($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_result')) {
case '1000': case '1000':
$result = Result::lost; $result = Result::Lost;
break; break;
case '01': case '01':
$result = Result::absent; $result = Result::Absent;
break; break;
case '0010': case '0010':
$result = Result::bye; $result = Result::Bye;
break; break;
case '2000': case '2000':
$result = Result::draw; $result = Result::Draw;
break; break;
case '4000': case '4000':
$result = Result::won; $result = Result::Won;
break; break;
case '04': case '04':
$result = Result::wonforfait; $result = Result::WonForfait;
break; break;
case '40': case '40':
$result = Result::wonbye; $result = Result::WonBye;
break; break;
case '00': case '00':
default: default:
$result = Result::none; $result = Result::None;
break; break;
} }
if (array_search($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_table'), [ 16384, 8192 ]) !== false) { if (array_search($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_table'), [ 16384, 8192 ]) !== false) {
$result = Result::absent; $result = Result::Absent;
} }
$pairing->setResult(new Result($result)); $pairing->setResult(new Result($result));
switch ($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_color')) { switch ($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_color')) {
case 4294967295: case 4294967295:
$color = Color::black; $color = Color::Black;
break; break;
case 1: case 1:
$color = Color::white; $color = Color::White;
break; break;
case 0: case 0:
default: default:
$color = Color::none; $color = Color::None;
break; break;
} }
$pairing->setColor(new Color($color)); $pairing->setColor(new Color($color));
$pairing->setBoard($this->getTournament()->getBinaryData('Pairing_' . $ptn . '_table'));
$ptn++; $ptn++;
$this->getTournament()->addPairing($pairing); $this->getTournament()->addPairing($pairing);
} }
@ -571,15 +573,15 @@ class Swar4 implements ReaderInterface
*/ */
public function getRelease(): string public function getRelease(): string
{ {
return $this->release; return $this->Release;
} }
/** /**
* @param string $release * @param string $Release
*/ */
public function setRelease(string $release): void public function setRelease(string $Release): void
{ {
$this->release = $release; $this->Release = $Release;
} }
/** /**

View File

@ -32,28 +32,28 @@ class Round
* *
* @var DateTime * @var DateTime
*/ */
private $date; private $Date;
/** /**
* Array of all games * Array of all games
* *
* @var Game[] * @var Game[]
*/ */
private $games = []; private $Games = [];
/** /**
* Number of the round * Number of the round
* *
* @var int * @var int
*/ */
private $roundNo; private $RoundNo;
/** /**
* Array of all pairings for this round * Array of all pairings for this round
* *
* @var Pairing[] * @var Pairing[]
*/ */
private $pairings = []; private $Pairings = [];
/** /**
* Adds a game to the round * Adds a game to the round
@ -83,7 +83,6 @@ class Round
return $this; return $this;
} }
/** /**
* Returns an array of pairings where the player is bye * Returns an array of pairings where the player is bye
* *
@ -94,14 +93,13 @@ class Round
$allPairings = $this->getPairings(); $allPairings = $this->getPairings();
$byePairings = []; $byePairings = [];
foreach ($allPairings as $pairing) { foreach ($allPairings as $pairing) {
if ($pairing->getResult() == Result::wonbye) { if ($pairing->getResult() == Result::WonBye) {
$byePairings[] = $pairing; $byePairings[] = $pairing;
} }
} }
return $byePairings; return $byePairings;
} }
/** /**
* Returns an array of pairings where the player is absent * Returns an array of pairings where the player is absent
* *
@ -112,13 +110,40 @@ class Round
$allPairings = $this->getPairings(); $allPairings = $this->getPairings();
$absentPairings = []; $absentPairings = [];
foreach ($allPairings as $pairing) { foreach ($allPairings as $pairing) {
if ($pairing->getResult() == Result::absent) { if ($pairing->getResult() == Result::Absent) {
$absentPairings[] = $pairing; $absentPairings[] = $pairing;
} }
} }
return $absentPairings; return $absentPairings;
} }
/**
* Retuns an array with the games of this round sorted by board
*
* @return Game[]
*/
public function getGamesByBoard(): array
{
$allGames = $this->getGames();
usort($allGames, array($this, 'sortByBoard'));
return $allGames;
}
/**
* Sort by board
*
* @param Game $a
* @param Game $b
* @return int
*/
private function sortByBoard(Game $a, Game $b): int
{
if (($a->getBoard() == $b->getBoard()) || ($a->getBoard() === false) || ($b->getBoard() === false)) {
return 0;
}
return ($a->getBoard() > $b->getBoard()) ? +1 : -1;
}
/** /**
* Returns the date of the round * Returns the date of the round
* *
@ -126,19 +151,20 @@ class Round
*/ */
public function getDate(): DateTime public function getDate(): DateTime
{ {
return $this->date; return $this->Date;
} }
/** /**
* Sets the date of the round * Sets the date of the round
* *
* @param DateTime $date * @param DateTime $Date
* @return Round * @return Round
*/ */
public function setDate(DateTime $date): Round public function setDate(DateTime $Date): Round
{ {
$this->date = $date; $this->Date = $Date;
return $this; return $this;
} }
/** /**
* Returns an array of all games for the round * Returns an array of all games for the round
* *
@ -146,19 +172,21 @@ class Round
*/ */
public function getGames(): array public function getGames(): array
{ {
return $this->games; return $this->Games;
} }
/** /**
* Sets an array of all games for the round * Sets an array of all games for the round
* *
* @param Game[] $games * @param Game[] $Games
* @return Round * @return Round
*/ */
public function setGames(array $games): Round public function setGames(array $Games): Round
{ {
$this->games = $games; $this->Games = $Games;
return $this; return $this;
} }
/** /**
* Returns the round number of the round * Returns the round number of the round
* *
@ -166,19 +194,21 @@ class Round
*/ */
public function getRoundNo(): int public function getRoundNo(): int
{ {
return $this->roundNo; return $this->RoundNo;
} }
/** /**
* Sets the round number of the round * Sets the round number of the round
* *
* @param int $roundNo * @param int $RoundNo
* @return Round * @return Round
*/ */
public function setRoundNo(int $roundNo): Round public function setRoundNo(int $RoundNo): Round
{ {
$this->roundNo = $roundNo; $this->RoundNo = $RoundNo;
return $this; return $this;
} }
/** /**
* Returns an array of all pairings for the round * Returns an array of all pairings for the round
* *
@ -186,17 +216,18 @@ class Round
*/ */
public function getPairings(): array public function getPairings(): array
{ {
return $this->pairings; return $this->Pairings;
} }
/** /**
* Sets an array of all pairings for the round * Sets an array of all pairings for the round
* *
* @param Pairing[] $pairings * @param Pairing[] $Pairings
* @return Round * @return Round
*/ */
public function setPairings(array $pairings): Round public function setPairings(array $Pairings): Round
{ {
$this->pairings = $pairings; $this->Pairings = $Pairings;
return $this; return $this;
} }
} }

View File

@ -103,7 +103,7 @@ class Tournament
private $PriorityId = 'Nation'; private $PriorityId = 'Nation';
/** @var bool|DateTime|int|string[] */ /** @var bool|DateTime|int|string[] */
private $binaryData = []; private $BinaryData = [];
/** /**
* Gets a player by its ID * Gets a player by its ID
@ -226,6 +226,10 @@ class Tournament
/** @var Pairing[] */ /** @var Pairing[] */
$cache = array(); $cache = array();
/** @var int[] */
$lastboards;
/** @var Pairing $pairing */
foreach ($pairings as $pairing) { foreach ($pairings as $pairing) {
// Add pairing to player // Add pairing to player
$pairing->getPlayer()->addPairing($pairing); $pairing->getPlayer()->addPairing($pairing);
@ -234,6 +238,11 @@ class Tournament
$this->getRoundByNo($round)->addPairing($pairing); $this->getRoundByNo($round)->addPairing($pairing);
$opponent = null; $opponent = null;
/**
* @var int $key
* @var Pairing $cached
*/
foreach ($cache as $key=>$cached) { foreach ($cache as $key=>$cached) {
if (!is_null($cached)) { if (!is_null($cached)) {
if (($cached->getOpponent() == $pairing->getPlayer()) && ($cached->getRound() == $pairing->getRound())) { if (($cached->getOpponent() == $pairing->getPlayer()) && ($cached->getRound() == $pairing->getRound())) {
@ -244,10 +253,10 @@ class Tournament
} }
} }
$game = new Game(); $game = new Game();
if ($color->getValue() == Color::white) { if ($color->getValue() == Color::White) {
$game->setWhite($pairing); $game->setWhite($pairing);
$game->setBlack($opponent); $game->setBlack($opponent);
} elseif ($color->getValue() == Color::black) { } elseif ($color->getValue() == Color::Black) {
$game->setWhite($opponent); $game->setWhite($opponent);
$game->setBlack($pairing); $game->setBlack($pairing);
} }
@ -257,6 +266,18 @@ class Tournament
} else { } else {
// Check if game already exists // Check if game already exists
if (!$this->gameExists($game, $round)) { if (!$this->gameExists($game, $round)) {
$game->setBoard($game->getWhite()->getBoard());
// Add board if inexistent
if ($game->getBoard() == -1) {
if (isset($lastboards[$round])) {
$lastboards[$round] += 1;
} else {
$lastboards[$round] = 0;
}
$game->setBoard($lastboards[$round]);
$game->getWhite()->setBoard($lastboards[$round]);
$game->getBlack()->setBoard($lastboards[$round]);
}
$this->AddGame($game, $round); $this->AddGame($game, $round);
} }
} }
@ -344,7 +365,7 @@ class Tournament
$tosortplayers = $sortedplayers; $tosortplayers = $sortedplayers;
$sortedplayers = []; $sortedplayers = [];
foreach ($tosortplayers as $groupkey=>$sortedplayerselem) { foreach ($tosortplayers as $groupkey=>$sortedplayerselem) {
usort($tosortplayers[$groupkey], $this->SortTiebreak($tbkey)); usort($tosortplayers[$groupkey], $this->sortTiebreak($tbkey));
foreach ($tosortplayers[$groupkey] as $playerkey => $player) { foreach ($tosortplayers[$groupkey] as $playerkey => $player) {
if (!is_null($player->getTiebreaks()[$tbkey])) { if (!is_null($player->getTiebreaks()[$tbkey])) {
if ($playerkey != 0) { if ($playerkey != 0) {