Compare commits

...

10 Commits

5 changed files with 67 additions and 40 deletions

View File

@@ -11,16 +11,17 @@ class CHESS_JSON {
const MOVE_ACTIONS = 'actions'; const MOVE_ACTIONS = 'actions';
const MOVE_VARIATIONS = 'variations'; const MOVE_VARIATIONS = 'variations';
const MOVE_MOVES = 'moves'; const MOVE_MOVES = 'moves';
const MOVE_MOVES_STRING = 'movesStr';
const MOVE_CAPTURE = 'capture'; const MOVE_CAPTURE = 'capture';
const MOVE_PROMOTE_TO = 'promoteTo'; const MOVE_PROMOTE_TO = 'promoteTo';
const MOVE_CASTLE = 'castle'; const MOVE_CASTLE = 'castle';
const MOVE_PARSED = 'castle'; const MOVE_PARSED = 'parsed';
const GAME_METADATA = 'metadata'; const GAME_METADATA = 'metadata';
const GAME_EVENT = 'event'; const GAME_EVENT = 'event';
const GAME_WHITE = 'white'; const GAME_WHITE = 'white';
const GAME_BLACK = 'black'; const GAME_BLACK = 'black';
const GAME_ECO = 'black'; const GAME_ECO = 'eco';
const PGN_KEY_ACTION_ARROW = "ar"; const PGN_KEY_ACTION_ARROW = "ar";
const PGN_KEY_ACTION_HIGHLIGHT = "sq"; const PGN_KEY_ACTION_HIGHLIGHT = "sq";
@@ -29,10 +30,12 @@ class CHESS_JSON {
const PGN_KEY_ACTION_CLR_ARROW = "cal"; const PGN_KEY_ACTION_CLR_ARROW = "cal";
protected static $jsKeys = array('MOVE_FROM', 'MOVE_TO', 'MOVE_NOTATION', 'FEN','MOVE_COMMENT', protected static $jsKeys = array(
'MOVE_ACTION', 'MOVE_VARIATIONS', 'MOVE_MOVES','MOVE_CAPTURE','MOVE_PROMOTE_TO','MOVE_CASTLE', 'MOVE_FROM', 'MOVE_TO', 'MOVE_NOTATION', 'FEN',
'GAME_METADATA', 'GAME_EVENT', 'GAME_WHITE','GAME_BLACK', 'GAME_ECO', 'MOVE_COMMENT', 'MOVE_ACTION', 'MOVE_VARIATIONS', 'MOVE_MOVES',
'MOVE_MOVES_STRING', 'MOVE_CAPTURE', 'MOVE_PROMOTE_TO', 'MOVE_CASTLE',
'GAME_METADATA', 'GAME_EVENT', 'GAME_WHITE', 'GAME_BLACK',
'GAME_ECO',
); );
public static function toJavascript(){ public static function toJavascript(){
@@ -42,4 +45,4 @@ class CHESS_JSON {
} }
return 'ludo.CHESS_JSON_KEY = ' . json_encode($ret) .';'; return 'ludo.CHESS_JSON_KEY = ' . json_encode($ret) .';';
} }
} }

View File

@@ -188,7 +188,7 @@ class FenParser0x88
{ {
$this->setFen($fen); $this->setFen($fen);
if (!isset($move['from'])) { if (!isset($move['from'])) {
$fromAndTo = $this->getFromAndToByNotation($move[CHESS_JSON::MOVE_NOTATION]); $fromAndTo = $this->getFromAndToByNotation($move['m']);
$move['from'] = $fromAndTo['from']; $move['from'] = $fromAndTo['from'];
$move['to'] = $fromAndTo['to']; $move['to'] = $fromAndTo['to'];
@@ -556,7 +556,7 @@ class FenParser0x88
} }
} }
} }
break; break;
// Sliding pieces // Sliding pieces
case 0x05: case 0x05:
@@ -1206,9 +1206,9 @@ class FenParser0x88
$ret = array('promoteTo' => $this->getPromoteByNotation($notation)); $ret = array('promoteTo' => $this->getPromoteByNotation($notation));
$color = $this->getColor(); $color = $this->getColor();
$offset = 0; $offset = 0; /* a1 */
if ($color === 'black') { if ($color === 'black') {
$offset = 112; $offset = 112; /* a8 */
} }
$foundPieces = array(); $foundPieces = array();
@@ -1235,7 +1235,7 @@ class FenParser0x88
$ret['to'] = $this->getToSquareByNotation($notation); $ret['to'] = $this->getToSquareByNotation($notation);
switch ($pieceType) { switch ($pieceType) {
case 0x01: case 0x01: // pawn
case 0x09: case 0x09:
if ($color === 'black') { if ($color === 'black') {
$offsets = $capture ? array(15, 17) : array(16); $offsets = $capture ? array(15, 17) : array(16);
@@ -1256,23 +1256,21 @@ class FenParser0x88
} }
} }
break; break;
case 0x03: case 0x03: // king
case 0x0B: case 0x0B:
if (!strncmp($notation, 'O-O-O', 5)) {
if ($notation === 'O-O') {
$foundPieces[] = ($offset + 4);
$ret['to'] = $offset + 6;
} else if ($notation === 'O-O-O') {
$foundPieces[] = ($offset + 4); $foundPieces[] = ($offset + 4);
$ret['to'] = $offset + 2; $ret['to'] = $offset + 2;
} else if (!strncmp($notation, 'O-O', 3)) {
$foundPieces[] = ($offset + 4);
$ret['to'] = $offset + 6;
} else { } else {
$k = $this->getKing($color); $k = $this->getKing($color);
$foundPieces[] = $k['s']; $foundPieces[] = $k['s'];
} }
break; break;
case 0x02: case 0x02: // knight
case 0x0A: case 0x0A:
$pattern = Board0x88Config::$movePatterns[$pieceType]; $pattern = Board0x88Config::$movePatterns[$pieceType];
for ($i = 0, $len = count($pattern); $i < $len; $i++) { for ($i = 0, $len = count($pattern); $i < $len; $i++) {
$sq = $ret['to'] + $pattern[$i]; $sq = $ret['to'] + $pattern[$i];
@@ -1411,7 +1409,7 @@ class FenParser0x88
function getPieceTypeByNotation($notation, $color = null) function getPieceTypeByNotation($notation, $color = null)
{ {
if ($notation === 'O-O-O' || $notation === 'O-O') { if (!strncmp($notation, 'O-O', 3)) {
$pieceType = 'K'; $pieceType = 'K';
} else { } else {
$token = substr($notation, 0, 1); $token = substr($notation, 0, 1);
@@ -1812,4 +1810,4 @@ class FenParser0x88
class FenParser0x88Exception extends Exception{ class FenParser0x88Exception extends Exception{
} }

View File

@@ -75,4 +75,4 @@ class GameParser
{ {
return $this->game[CHESS_JSON::FEN]; return $this->game[CHESS_JSON::FEN];
} }
} }

View File

@@ -4,13 +4,16 @@
class PgnGameParser{ class PgnGameParser{
private $pgnGame; private $pgnGame;
private $moveBuilder;
private $defaultFen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1'; private $defaultFen = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';
private $gameData = array(); private $gameData = array();
private $specialMetadata = array( private $specialMetadata = array(
'event','site','white','black','result','plycount','eco','fen', 'event','site','white','black','result','plycount','eco','fen',
'timecontrol','round','date','annotator','termination' 'timecontrol','round','date','annotator','termination',
'whiteelo', 'blackelo', 'whiteteam', 'blackteam',
'opening', 'eventdate', 'seat'
); );
public function __construct($pgnGame = null){ public function __construct($pgnGame = null){
@@ -28,6 +31,7 @@ class PgnGameParser{
public function getParsedData(){ public function getParsedData(){
$this->gameData = $this->getMetadata(); $this->gameData = $this->getMetadata();
$this->gameData[CHESS_JSON::MOVE_MOVES_STRING] = $this->getMoveString();
$this->gameData[CHESS_JSON::MOVE_MOVES] = $this->getMoves(); $this->gameData[CHESS_JSON::MOVE_MOVES] = $this->getMoves();
return $this->gameData; return $this->gameData;
} }
@@ -140,4 +144,4 @@ class PgnGameParser{
$gameData = preg_replace("/(\s+)/", " ", $gameData); $gameData = preg_replace("/(\s+)/", " ", $gameData);
return trim($gameData); return trim($gameData);
} }
} }

View File

@@ -65,25 +65,47 @@ class PgnParser
{ {
$c = $this->pgnContent; $c = $this->pgnContent;
$c = preg_replace('/"\]\s{0,10}\[/s', "]\n[", $c); /* replace CR and TAB with space */
$c = preg_replace('/"\]\s{0,10}([\.0-9]|{)/s', "\"]\n\n$1", $c); $c = preg_replace("/[\t\r]/s", " ", $c);
$c = preg_replace("/{\s{0,6}\[%emt[^\}]*?\}/", "", $c); /* separate first comment of variation */
$c = preg_replace("/\\$[0-9]+/s", "", $c);
$c = str_replace("({", "( {", $c); $c = str_replace("({", "( {", $c);
$c = preg_replace("/{([^\[]*?)\[([^}]?)}/s", '{$1-SB-$2}', $c);
$c = preg_replace("/\r/s", "", $c); /* replace 0 in castle with O */
$c = preg_replace("/\t/s", "", $c);
$c = preg_replace("/\]\s+\[/s", "]\n[", $c);
$c = str_replace(" [", "[", $c);
$c = preg_replace("/([^\]])(\n+)\[/si", "$1\n\n[", $c);
$c = preg_replace("/\n{3,}/s", "\n\n", $c);
$c = str_replace("-SB-", "[", $c);
$c = str_replace("0-0-0", "O-O-O", $c); $c = str_replace("0-0-0", "O-O-O", $c);
$c = str_replace("0-0", "O-O", $c); $c = str_replace("0-0", "O-O", $c);
$c = preg_replace('/^([^\[])*?\[/', '[', $c); /* basic trimming:
* - remove initial blanks
* - keep only one space
* - trim lines
* - max 2 consecutive '\n'
*/
$c = preg_replace("/^\s+([^\s])/", "$1", $c);
$c = preg_replace("/ +/", " ", $c);
$c = preg_replace("/\s*\n\s*/", "\n", $c);
$c = preg_replace("/\n{3,}/s", "\n\n", $c);
/* replace '[' between '{' and '}' with '//--SB--//'
*/
$c = preg_replace('/(?:\G(?!\A)|\{)[^\}\[]*\K\[/', "//--SB--//", $c);
$c = preg_replace('/(?:\G(?!\A)|\{)[^\}\]]*\K\]/', "//--SE--//", $c);
/* set one '\n' between tags.
* This is possible because brackets within comments are protected above
*/
$c = preg_replace('/"\]\s*\[/s', "\"]\n[", $c);
/* set '\n\n' between tags and movetext section
* set '\n\n' between non tag line and tag line (between two games)
* This is possible because brackets within comments are protected above
*/
$c = preg_replace('/"\]\s*([\.0-9]|{)/s', "\"]\n\n$1", $c);
$c = preg_replace("/([^\]])\n+\[/", "$1\n\n[", $c);
/* revert brackets within movetext comments */
$c = str_replace("//--SB--//", "[", $c);
$c = str_replace("//--SE--//", "]", $c);
return $c; return $c;
} }
@@ -104,7 +126,7 @@ class PgnParser
$content = "\n\n" . $pgn; $content = "\n\n" . $pgn;
$games = preg_split("/\n\n\[/s", $content, -1, PREG_SPLIT_DELIM_CAPTURE); $games = preg_split("/\n\n\[/s", $content, -1, PREG_SPLIT_DELIM_CAPTURE);
file_put_contents("parsed.pgn", $content); //file_put_contents("/tmp/parsed.pgn", $content);
for ($i = 1, $count = count($games); $i < $count; $i++) { for ($i = 1, $count = count($games); $i < $count; $i++) {
$gameContent = trim("[" . $games[$i]); $gameContent = trim("[" . $games[$i]);