Added PGNDatabase and PGNGame classes with support for PGN parsing
This commit is contained in:
		
							
								
								
									
										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