223 lines
7.0 KiB
PHP
223 lines
7.0 KiB
PHP
<?php
|
|
|
|
namespace Blackbirdchess\Service\Import\Readers;
|
|
|
|
use Blackbirdchess\Service\Import\Exceptions\InvalidFileException;
|
|
use Blackbirdchess\Service\Import\Interfaces\ReaderInterface;
|
|
use Blackbirdchess\Service\Results\Enums\Color;
|
|
use Blackbirdchess\Service\Results\Enums\Gender;
|
|
use Blackbirdchess\Service\Results\Enums\Result;
|
|
use Blackbirdchess\Service\Results\Enums\Title;
|
|
use Blackbirdchess\Service\Results\Pairing;
|
|
use Blackbirdchess\Service\Results\Player;
|
|
use Blackbirdchess\Service\Results\Round;
|
|
use Blackbirdchess\Service\Results\Tournament;
|
|
use DateTime;
|
|
|
|
class Trf16 implements ReaderInterface
|
|
{
|
|
|
|
/**
|
|
* The tournament
|
|
*
|
|
* @var Tournament
|
|
*/
|
|
public $Tournament;
|
|
|
|
private $playerIndexes;
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function read(string $filename): void
|
|
{
|
|
$file = explode("\n", str_replace("\r", "", file_get_contents($filename)));
|
|
$this->Tournament = new Tournament();
|
|
$this->playerIndexes['0000'] = NULL;
|
|
$this->playerIndexes[' '] = NULL;
|
|
$linecount = count($file);
|
|
for ($lineno = 0; $lineno < count($file); $lineno++) {
|
|
$line = $file[$lineno];
|
|
$datatype = substr($line, 0, 3);
|
|
|
|
switch($datatype) {
|
|
case '012':
|
|
$this->Tournament->Name = substr($line, 4);
|
|
break;
|
|
case '022':
|
|
$this->Tournament->OrganiserPlace = substr($line, 4);
|
|
break;
|
|
case '032':
|
|
$this->Tournament->OrganiserCountry = substr($line, 4);
|
|
break;
|
|
case '042':
|
|
$this->Tournament->StartDate = \DateTime::createFromFormat("Y/m/d", substr($line, 4));
|
|
break;
|
|
case '052':
|
|
$this->Tournament->EndDate = \DateTime::createFromFormat("Y/m/d", substr($line, 4));
|
|
break;
|
|
case '102':
|
|
case '112':
|
|
$this->Tournament->addArbiter(substr($line, 4));
|
|
break;
|
|
case '132':
|
|
$this->readRoundData($line);
|
|
break;
|
|
case '001':
|
|
if(!empty($this->Tournament->Rounds)) {
|
|
$this->readPlayerData($line);
|
|
} elseif($lineno < $linecount) {
|
|
$file[] = $line;
|
|
} else {
|
|
throw new InvalidFileException();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
$this->setOpponentIndexToPlayerObj();
|
|
$this->Tournament->pairingsToRounds();
|
|
}
|
|
|
|
private function readPlayerData(string $line): void
|
|
{
|
|
$player = new Player();
|
|
$player->InitialRank = substr($line, 4, 4);
|
|
switch (substr($line, 9, 1))
|
|
{
|
|
case 'm':
|
|
$player->Gender = Gender::MALE;
|
|
break;
|
|
case 'w':
|
|
$player->Gender = Gender::FEMALE;
|
|
break;
|
|
default:
|
|
$player->Gender = NULL;
|
|
break;
|
|
}
|
|
|
|
switch (trim(substr($line, 10, 3)))
|
|
{
|
|
case 'GM':
|
|
$player->Title = Title::GM;
|
|
break;
|
|
case 'IM':
|
|
$player->Title = Title::IM;
|
|
break;
|
|
case 'WGM':
|
|
$player->Title = Title::WGM;
|
|
break;
|
|
case 'FM':
|
|
$player->Title = Title::FM;
|
|
break;
|
|
case 'WIM':
|
|
$player->Title = Title::WIM;
|
|
break;
|
|
case 'CM':
|
|
$player->Title = Title::CM;
|
|
break;
|
|
case 'WFM':
|
|
$player->Title = Title::WFM;
|
|
break;
|
|
case 'WCM':
|
|
$player->Title = Title::WCM;
|
|
break;
|
|
default:
|
|
$player->Title = NULL;
|
|
break;
|
|
}
|
|
|
|
$player->Name = trim(substr($line, 14, 32));
|
|
$player->setElo('Fide', (int)trim(substr($line, 48, 4)));
|
|
$player->Nation = trim(substr($line, 53, 3));
|
|
$player->setId('Fide', (int)trim(substr($line, 57, 10)));
|
|
$player->DateOfBirth = \DateTime::createFromFormat("Y/m/d", substr($line, 69, 10));
|
|
$player->Points = (float)trim(substr($line, 80, 4));
|
|
$player->Rank = (int)trim(substr($line, 85, 4));
|
|
|
|
|
|
//read pairing round 1
|
|
$position = 91;
|
|
$length = strlen($line);
|
|
$roundnum = 1;
|
|
do {
|
|
$pairing = new Pairing();
|
|
$pairing->Round = $roundnum;
|
|
$pairing->Player = $player;
|
|
$pairing->OpponentIndex = substr($line, $position, 4);
|
|
|
|
switch (trim(substr($line, $position + 6, 1)))
|
|
{
|
|
case 'w':
|
|
$pairing->Color = Color::WHITE;
|
|
break;
|
|
case 'b':
|
|
$pairing->Color = Color::BLACK;
|
|
break;
|
|
case '-':
|
|
default:
|
|
$pairing->Color = Color::NONE;
|
|
break;
|
|
}
|
|
|
|
switch (strtoupper(trim(substr($line, $position + 8, 1))))
|
|
{
|
|
case '-':
|
|
case 'Z':
|
|
$pairing->Result = Result::ABSENT;
|
|
break;
|
|
case '+':
|
|
$pairing->Result = Result::WON_FORFAIT;
|
|
break;
|
|
case 'W':
|
|
case '1':
|
|
$pairing->Result = Result::WON;
|
|
break;
|
|
case 'D':
|
|
case '=':
|
|
$pairing->Result = Result::DRAW;
|
|
break;
|
|
case 'L':
|
|
case '0':
|
|
$pairing->Result = Result::LOST;
|
|
break;
|
|
case 'H':
|
|
case 'F':
|
|
case 'U':
|
|
$pairing->Result = Result::WON_BYE;
|
|
break;
|
|
default:
|
|
$pairing->Color = Result::NONE;
|
|
break;
|
|
}
|
|
$position += 10;
|
|
$roundnum ++;
|
|
$this->Tournament->addPairing($pairing);
|
|
} while ($length > $position);
|
|
$this->playerIndexes[$player->InitialRank] = $player;
|
|
$this->Tournament->addPlayer($player);
|
|
}
|
|
|
|
private function setOpponentIndexToPlayerObj()
|
|
{
|
|
foreach($this->Tournament->Pairings as &$pairing) {
|
|
$pairing->Opponent = $this->playerIndexes[$pairing->OpponentIndex];
|
|
}
|
|
}
|
|
|
|
private function readRoundData(string $line)
|
|
{
|
|
$position = 91;
|
|
$length = strlen($line);
|
|
$roundnum = 1;
|
|
do {
|
|
$round = new Round();
|
|
$round->Date = DateTime::createFromFormat('y/m/d', substr($line, $position, 8));
|
|
$round->RoundNo = $roundnum;
|
|
$this->Tournament->addRound($round);
|
|
$position += 10;
|
|
$roundnum ++;
|
|
} while ($length > $position);
|
|
}
|
|
}
|