-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
* Added Chess\PgnParser\FileLine * Added Chess\PgnParser\AbstractParser * Implemented Chess\Parser * Refactored play_games() * Renamed play_games() as classical_customized()
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
<?php | ||
|
||
namespace Chess\Parser; | ||
|
||
use Chess\Variant\Classical\PGN\Termination; | ||
|
||
class PgnLine | ||
{ | ||
public function isOneLinerMovetext(string $line): bool | ||
{ | ||
return $this->startsMovetext($line) && $this->endsMovetext($line); | ||
} | ||
|
||
public function startsMovetext(string $line): bool | ||
{ | ||
return $this->startsWith($line, '1.'); | ||
} | ||
|
||
public function endsMovetext(string $line): bool | ||
{ | ||
return $this->endsWith($line, Termination::WHITE_WINS) || | ||
$this->endsWith($line, Termination::BLACK_WINS) || | ||
$this->endsWith($line, Termination::DRAW) || | ||
$this->endsWith($line, Termination::UNKNOWN); | ||
} | ||
|
||
public function startsWith(string $haystack, string $needle): bool | ||
{ | ||
return strncmp($haystack, $needle, strlen($needle)) === 0; | ||
} | ||
|
||
public function endsWith(string $haystack, string $needle): bool | ||
{ | ||
return substr($haystack, -strlen($needle)) === $needle; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
namespace Chess\Parser; | ||
|
||
use Chess\Exception\UnknownNotationException; | ||
use Chess\Movetext\SanMovetext; | ||
use Chess\Parser\PgnLine; | ||
use Chess\Variant\Classical\PGN\Tag; | ||
use Chess\Variant\Classical\PGN\Move; | ||
|
||
class PgnParser | ||
{ | ||
protected string $filepath; | ||
|
||
protected PgnLine $line; | ||
|
||
protected object $result; | ||
|
||
protected \Closure $callback; | ||
|
||
public function __construct(string $filepath) | ||
{ | ||
$this->filepath = $filepath; | ||
$this->line = new PgnLine(); | ||
$this->result = (object) [ | ||
'total' => 0, | ||
'valid' => 0, | ||
]; | ||
} | ||
|
||
public function getResult(): array | ||
{ | ||
return $this->result; | ||
} | ||
|
||
public function parse(): void | ||
{ | ||
$tags = []; | ||
$movetext = ''; | ||
$file = new \SplFileObject($this->filepath); | ||
$tag = new Tag(); | ||
$move = new Move(); | ||
while (!$file->eof()) { | ||
$line = rtrim($file->fgets()); | ||
try { | ||
$valid = $tag->validate($line); | ||
$tags[$valid['name']] = $valid['value']; | ||
} catch (UnknownNotationException $e) { | ||
if ($this->line->isOneLinerMovetext($line)) { | ||
if (!array_diff($tag->mandatory(), array_keys($tags)) && | ||
$validMovetext = (new SanMovetext($move, $line))->validate() | ||
) { | ||
if ($this->handle($tags, $validMovetext)) { | ||
$this->result->valid++; | ||
} | ||
} | ||
$tags = []; | ||
$movetext = ''; | ||
$this->result->total++; | ||
} elseif ($this->line->startsMovetext($line)) { | ||
if (!array_diff($tag->mandatory(), array_keys($tags))) { | ||
$movetext .= ' ' . $line; | ||
} | ||
} elseif ($this->line->endsMovetext($line)) { | ||
$movetext .= ' ' . $line; | ||
if ($validMovetext = (new SanMovetext($move, $movetext))->validate()) { | ||
if ($this->handle($tags, $validMovetext)) { | ||
$this->result->valid++; | ||
} | ||
} | ||
$tags = []; | ||
$movetext = ''; | ||
$this->result->total++; | ||
} else { | ||
$movetext .= ' ' . $line; | ||
} | ||
} | ||
} | ||
} | ||
|
||
public function onValidate($callback): void | ||
{ | ||
$this->callback = $callback; | ||
} | ||
|
||
protected function handle(array $tags, string $movetext): void | ||
{ | ||
call_user_func($this->callback, $tags, $movetext); | ||
} | ||
} |
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.