Added PGNDatabase and PGNGame classes with support for PGN parsing
This commit is contained in:
parent
84b3e1503f
commit
713c95338e
29
src/dev/kske/chess/pgn/PGNDatabase.java
Normal file
29
src/dev/kske/chess/pgn/PGNDatabase.java
Normal file
@ -0,0 +1,29 @@
|
||||
package dev.kske.chess.pgn;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
import dev.kske.chess.exception.ChessException;
|
||||
|
||||
/**
|
||||
* Project: <strong>Chess</strong><br>
|
||||
* File: <strong>PGNDatabase.java</strong><br>
|
||||
* Created: <strong>4 Oct 2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public class PGNDatabase {
|
||||
|
||||
private final List<PGNGame> games = new ArrayList<>();
|
||||
|
||||
public void load(File pgnFile) {
|
||||
try (Scanner sc = new Scanner(pgnFile)) {
|
||||
while (sc.hasNext())
|
||||
games.add(PGNGame.parse(sc));
|
||||
} catch (FileNotFoundException | ChessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
77
src/dev/kske/chess/pgn/PGNGame.java
Normal file
77
src/dev/kske/chess/pgn/PGNGame.java
Normal file
@ -0,0 +1,77 @@
|
||||
package dev.kske.chess.pgn;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.MatchResult;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import dev.kske.chess.board.Board;
|
||||
import dev.kske.chess.exception.ChessException;
|
||||
|
||||
/**
|
||||
* Project: <strong>Chess</strong><br>
|
||||
* File: <strong>PGNGame.java</strong><br>
|
||||
* Created: <strong>22 Sep 2019</strong><br>
|
||||
* Author: <strong>Kai S. K. Engelbart</strong>
|
||||
*/
|
||||
public class PGNGame {
|
||||
|
||||
private final Map<String, String> tagPairs = new HashMap<>(7);
|
||||
private final Board board = new Board();
|
||||
|
||||
public static PGNGame parse(Scanner sc) throws ChessException {
|
||||
PGNGame game = new PGNGame();
|
||||
|
||||
MatchResult matchResult;
|
||||
Pattern tagPairPattern = Pattern.compile("\\[(\\w+) \"(.*)\"]"),
|
||||
movePattern = Pattern.compile("\\d+\\. (\\S+)\\s(\\S+)"),
|
||||
nagPattern = Pattern.compile("(\\$\\d{1,3})*"),
|
||||
terminationMarkerPattern = Pattern.compile("1-0|0-1|1\\/2-1\\/2|\\*");
|
||||
|
||||
// Parse tag pairs
|
||||
while (true) {
|
||||
if (sc.findInLine(tagPairPattern) != null) {
|
||||
matchResult = sc.match();
|
||||
if (matchResult.groupCount() == 2) game.setTag(matchResult.group(0), matchResult.group(1));
|
||||
else break;
|
||||
} else break;
|
||||
sc.nextLine();
|
||||
}
|
||||
|
||||
// Parse movetext
|
||||
while (true) {
|
||||
// Skip NAG (Numeric Annotation Glyph)
|
||||
sc.skip(nagPattern);
|
||||
|
||||
// TODO: Parse RAV (Recursive Annotation Variation)
|
||||
|
||||
sc.findWithinHorizon(movePattern, 20);
|
||||
matchResult = sc.match();
|
||||
if (matchResult.groupCount() > 0) for (int i = 1; i < matchResult.groupCount() + 1; i++) {
|
||||
game.board.move(matchResult.group(i));
|
||||
System.out.println(game.board.toFEN());
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
||||
// Parse game termination marker
|
||||
if (sc.hasNext(terminationMarkerPattern)) {
|
||||
sc.next(terminationMarkerPattern);
|
||||
} else throw new ChessException("Game termination marker expected");
|
||||
|
||||
return game;
|
||||
}
|
||||
|
||||
public String getTag(String tagName) {
|
||||
return tagPairs.get(tagName);
|
||||
}
|
||||
|
||||
public boolean hasTag(String tagName) {
|
||||
return tagPairs.containsKey(tagName);
|
||||
}
|
||||
|
||||
public void setTag(String tagName, String tagValue) {
|
||||
tagPairs.put(tagName, tagValue);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user