Removed old FEN string methods, fixed FEN regex
This commit is contained in:
		@@ -63,13 +63,6 @@ public class Board {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public Board() { initDefaultPositions(); }
 | 
						public Board() { initDefaultPositions(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Initializes the board with data from a FEN-string.
 | 
					 | 
				
			||||||
	 * 
 | 
					 | 
				
			||||||
	 * @param fen The FEN-string to initialize the board from
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public Board(String fen) { initFromFEN(fen); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Creates a copy of another {@link Board} instance.<br>
 | 
						 * Creates a copy of another {@link Board} instance.<br>
 | 
				
			||||||
	 * The created object is a deep copy, but does not contain any move history
 | 
						 * The created object is a deep copy, but does not contain any move history
 | 
				
			||||||
@@ -416,138 +409,6 @@ public class Board {
 | 
				
			|||||||
		log.reset();
 | 
							log.reset();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Initialized the board with a position specified in a FEN-encoded string.
 | 
					 | 
				
			||||||
	 * 
 | 
					 | 
				
			||||||
	 * @param fen The FEN-encoded string representing target state of the board
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public void initFromFEN(String fen) {
 | 
					 | 
				
			||||||
		String[] parts = fen.split(" ");
 | 
					 | 
				
			||||||
		log.reset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Piece placement (from white's perspective)
 | 
					 | 
				
			||||||
		String[] rows = parts[0].split("/");
 | 
					 | 
				
			||||||
		for (int i = 0; i < 8; i++) {
 | 
					 | 
				
			||||||
			char[] places = rows[i].toCharArray();
 | 
					 | 
				
			||||||
			for (int j = 0, k = 0; k < places.length; j++, k++) {
 | 
					 | 
				
			||||||
				if (Character.isDigit(places[k])) {
 | 
					 | 
				
			||||||
					for (int l = j; l < Character.digit(places[k], 10); l++, j++)
 | 
					 | 
				
			||||||
						boardArr[j][i] = null;
 | 
					 | 
				
			||||||
					--j;
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					Color color = Character.isUpperCase(places[k]) ? Color.WHITE : Color.BLACK;
 | 
					 | 
				
			||||||
					switch (Character.toLowerCase(places[k])) {
 | 
					 | 
				
			||||||
						case 'k':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new King(color, this);
 | 
					 | 
				
			||||||
							kingPos.put(color, new Position(j, i));
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case 'q':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new Queen(color, this);
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case 'r':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new Rook(color, this);
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case 'n':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new Knight(color, this);
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case 'b':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new Bishop(color, this);
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						case 'p':
 | 
					 | 
				
			||||||
							boardArr[j][i] = new Pawn(color, this);
 | 
					 | 
				
			||||||
							break;
 | 
					 | 
				
			||||||
						default:
 | 
					 | 
				
			||||||
							System.err.printf("Unknown character '%c' in board declaration of FEN string '%s'%n", places[k], fen);
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Active color
 | 
					 | 
				
			||||||
		log.setActiveColor(Color.fromFirstChar(parts[1].charAt(0)));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Castling rights
 | 
					 | 
				
			||||||
		Map<Type, Boolean> whiteCastling = new HashMap<>(), blackCastling = new HashMap<>();
 | 
					 | 
				
			||||||
		for (char c : parts[2].toCharArray())
 | 
					 | 
				
			||||||
			switch (c) {
 | 
					 | 
				
			||||||
				case 'K':
 | 
					 | 
				
			||||||
					whiteCastling.put(Type.KING, true);
 | 
					 | 
				
			||||||
				case 'Q':
 | 
					 | 
				
			||||||
					whiteCastling.put(Type.QUEEN, true);
 | 
					 | 
				
			||||||
				case 'k':
 | 
					 | 
				
			||||||
					blackCastling.put(Type.KING, true);
 | 
					 | 
				
			||||||
				case 'q':
 | 
					 | 
				
			||||||
					blackCastling.put(Type.QUEEN, true);
 | 
					 | 
				
			||||||
				case '-':
 | 
					 | 
				
			||||||
					break;
 | 
					 | 
				
			||||||
				default:
 | 
					 | 
				
			||||||
					System.err.printf("Unknown character '%c' in castling rights declaration of FEN string '%s'", c, fen);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		// castlingRights.put(Color.WHITE, whiteCastling);
 | 
					 | 
				
			||||||
		// castlingRights.put(Color.BLACK, blackCastling);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// En passant availability
 | 
					 | 
				
			||||||
		if (!parts[3].equals("-")) log.setEnPassant(Position.fromLAN(parts[3]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Halfmove clock
 | 
					 | 
				
			||||||
		log.setHalfmoveClock(Integer.parseInt(parts[4]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Fullmove counter
 | 
					 | 
				
			||||||
		log.setFullmoveNumber(Integer.parseInt(parts[5]));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * @return a FEN-encoded string representing the board
 | 
					 | 
				
			||||||
	 */
 | 
					 | 
				
			||||||
	public String toFEN() {
 | 
					 | 
				
			||||||
		StringBuilder sb = new StringBuilder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Piece placement (from white's perspective)
 | 
					 | 
				
			||||||
		for (int i = 0; i < 8; i++) {
 | 
					 | 
				
			||||||
			int emptyCount = 0;
 | 
					 | 
				
			||||||
			for (int j = 0; j < 8; j++) {
 | 
					 | 
				
			||||||
				final Piece piece = boardArr[j][i];
 | 
					 | 
				
			||||||
				if (piece == null) ++emptyCount;
 | 
					 | 
				
			||||||
				else {
 | 
					 | 
				
			||||||
					if (emptyCount != 0) {
 | 
					 | 
				
			||||||
						sb.append(emptyCount);
 | 
					 | 
				
			||||||
						emptyCount = 0;
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					char p = boardArr[j][i].getType().firstChar();
 | 
					 | 
				
			||||||
					sb.append(piece.getColor() == Color.WHITE ? Character.toUpperCase(p) : p);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (emptyCount != 0) sb.append(emptyCount);
 | 
					 | 
				
			||||||
			if (i < 7) sb.append('/');
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Active color
 | 
					 | 
				
			||||||
		sb.append(" " + log.getActiveColor().firstChar());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Castling Rights
 | 
					 | 
				
			||||||
		sb.append(' ');
 | 
					 | 
				
			||||||
		StringBuilder castlingSb = new StringBuilder();
 | 
					 | 
				
			||||||
		// if (castlingRights.get(Color.WHITE).get(Type.KING)) castlingSb.append('K');
 | 
					 | 
				
			||||||
		// if (castlingRights.get(Color.WHITE).get(Type.QUEEN)) castlingSb.append('Q');
 | 
					 | 
				
			||||||
		// if (castlingRights.get(Color.BLACK).get(Type.KING)) castlingSb.append('k');
 | 
					 | 
				
			||||||
		// if (castlingRights.get(Color.BLACK).get(Type.QUEEN)) castlingSb.append('q');
 | 
					 | 
				
			||||||
		if (castlingSb.length() == 0) sb.append("-");
 | 
					 | 
				
			||||||
		sb.append(castlingSb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		final MoveNode lastMove = log.getLast();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// En passant availability
 | 
					 | 
				
			||||||
		sb.append(" " + (lastMove == null || lastMove.enPassant == null ? "-" : lastMove.enPassant.toLAN()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Halfmove clock
 | 
					 | 
				
			||||||
		sb.append(" " + String.valueOf(lastMove == null ? 0 : lastMove.halfmoveClock));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Fullmove counter
 | 
					 | 
				
			||||||
		sb.append(" " + String.valueOf(lastMove == null ? 1 : lastMove.fullmoveCounter));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return sb.toString();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public int hashCode() {
 | 
						public int hashCode() {
 | 
				
			||||||
		final int	prime	= 31;
 | 
							final int	prime	= 31;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,7 @@ public class FENString {
 | 
				
			|||||||
	public FENString(String fen) throws ChessException {
 | 
						public FENString(String fen) throws ChessException {
 | 
				
			||||||
		// Check fen string against regex
 | 
							// Check fen string against regex
 | 
				
			||||||
		Pattern	fenPattern	= Pattern.compile(
 | 
							Pattern	fenPattern	= Pattern.compile(
 | 
				
			||||||
				"^(?<piecePlacement>(?:[1-8nbrqkpNBRQKP]{1,8}\\/){7}[1-8nbrqkpNBRQKP]{1,8}) (?<activeColor>[wb]) (?<castlingAvailability>-|[KQkq]{1,4}) (?<enPassantTargetSquare>-|[a-h][1-8]) (?<halfmoveClock>\\d) (?<fullmoveNumber>\\d)$");
 | 
									"^(?<piecePlacement>(?:[1-8nbrqkpNBRQKP]{1,8}\\/){7}[1-8nbrqkpNBRQKP]{1,8}) (?<activeColor>[wb]) (?<castlingAvailability>-|[KQkq]{1,4}) (?<enPassantTargetSquare>-|[a-h][1-8]) (?<halfmoveClock>\\d+) (?<fullmoveNumber>\\d+)$");
 | 
				
			||||||
		Matcher	matcher		= fenPattern.matcher(fen);
 | 
							Matcher	matcher		= fenPattern.matcher(fen);
 | 
				
			||||||
		if (!matcher.find()) throw new ChessException("FEN string does not match pattern " + fenPattern.pattern());
 | 
							if (!matcher.find()) throw new ChessException("FEN string does not match pattern " + fenPattern.pattern());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,8 +55,7 @@ public class FENString {
 | 
				
			|||||||
		piecePlacement			= matcher.group("piecePlacement");
 | 
							piecePlacement			= matcher.group("piecePlacement");
 | 
				
			||||||
		activeColor				= Color.fromFirstChar(matcher.group("activeColor").charAt(0));
 | 
							activeColor				= Color.fromFirstChar(matcher.group("activeColor").charAt(0));
 | 
				
			||||||
		castlingAvailability	= matcher.group("castlingAvailability");
 | 
							castlingAvailability	= matcher.group("castlingAvailability");
 | 
				
			||||||
		if (!matcher.group("enPassantTargetSquare").equals("-"))
 | 
							if (!matcher.group("enPassantTargetSquare").equals("-")) enPassantTargetSquare = Position.fromLAN(matcher.group("enPassantTargetSquare"));
 | 
				
			||||||
			enPassantTargetSquare = Position.fromLAN(matcher.group("enPassantTargetSquare"));
 | 
					 | 
				
			||||||
		halfmoveClock	= Integer.parseInt(matcher.group("halfmoveClock"));
 | 
							halfmoveClock	= Integer.parseInt(matcher.group("halfmoveClock"));
 | 
				
			||||||
		fullmoveNumber	= Integer.parseInt(matcher.group("fullmoveNumber"));
 | 
							fullmoveNumber	= Integer.parseInt(matcher.group("fullmoveNumber"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package dev.kske.chess.game;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.chess.board.FENString;
 | 
				
			||||||
import dev.kske.chess.board.Move;
 | 
					import dev.kske.chess.board.Move;
 | 
				
			||||||
import dev.kske.chess.board.Piece.Color;
 | 
					import dev.kske.chess.board.Piece.Color;
 | 
				
			||||||
import dev.kske.chess.uci.UCIHandle;
 | 
					import dev.kske.chess.uci.UCIHandle;
 | 
				
			||||||
@@ -30,7 +31,7 @@ public class UCIPlayer extends Player implements UCIListener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void requestMove() {
 | 
						public void requestMove() {
 | 
				
			||||||
		handle.positionFEN(board.toFEN());
 | 
							handle.positionFEN(new FENString(board).toString());
 | 
				
			||||||
		handle.go();
 | 
							handle.go();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ import java.util.regex.MatchResult;
 | 
				
			|||||||
import java.util.regex.Pattern;
 | 
					import java.util.regex.Pattern;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import dev.kske.chess.board.Board;
 | 
					import dev.kske.chess.board.Board;
 | 
				
			||||||
 | 
					import dev.kske.chess.board.FENString;
 | 
				
			||||||
import dev.kske.chess.exception.ChessException;
 | 
					import dev.kske.chess.exception.ChessException;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -26,8 +27,7 @@ public class PGNGame {
 | 
				
			|||||||
		MatchResult	matchResult;
 | 
							MatchResult	matchResult;
 | 
				
			||||||
		Pattern		tagPairPattern	= Pattern.compile("\\[(\\w+) \"(.*)\"]"),
 | 
							Pattern		tagPairPattern	= Pattern.compile("\\[(\\w+) \"(.*)\"]"),
 | 
				
			||||||
				movePattern = Pattern.compile("\\d+\\.\\s+(?:(?:(\\S+)\\s+(\\S+))|(?:O-O-O)|(?:O-O))(?:\\+{0,2}|\\#)"),
 | 
									movePattern = Pattern.compile("\\d+\\.\\s+(?:(?:(\\S+)\\s+(\\S+))|(?:O-O-O)|(?:O-O))(?:\\+{0,2}|\\#)"),
 | 
				
			||||||
				nagPattern = Pattern.compile("(\\$\\d{1,3})*"),
 | 
									nagPattern = Pattern.compile("(\\$\\d{1,3})*"), terminationMarkerPattern = Pattern.compile("1-0|0-1|1\\/2-1\\/2|\\*");
 | 
				
			||||||
				terminationMarkerPattern = Pattern.compile("1-0|0-1|1\\/2-1\\/2|\\*");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Parse tag pairs
 | 
							// Parse tag pairs
 | 
				
			||||||
		while (sc.findInLine(tagPairPattern) != null) {
 | 
							while (sc.findInLine(tagPairPattern) != null) {
 | 
				
			||||||
@@ -48,30 +48,23 @@ public class PGNGame {
 | 
				
			|||||||
				matchResult = sc.match();
 | 
									matchResult = sc.match();
 | 
				
			||||||
				if (matchResult.groupCount() > 0) for (int i = 1; i < matchResult.groupCount() + 1; i++) {
 | 
									if (matchResult.groupCount() > 0) for (int i = 1; i < matchResult.groupCount() + 1; i++) {
 | 
				
			||||||
					game.board.move(matchResult.group(i));
 | 
										game.board.move(matchResult.group(i));
 | 
				
			||||||
					System.out.println(game.getBoard().getLog().getLast().move.toLAN() + ": " + game.board.toFEN());
 | 
										System.out.println(game.getBoard().getLog().getLast().move.toLAN() + ": " + new FENString(game.board).toString());
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else break;
 | 
									else break;
 | 
				
			||||||
			} else break;
 | 
								} else break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Parse game termination marker
 | 
							// Parse game termination marker
 | 
				
			||||||
		if (sc.findWithinHorizon(terminationMarkerPattern, 20) == null)
 | 
							if (sc.findWithinHorizon(terminationMarkerPattern, 20) == null) System.err.println("Termination marker expected");
 | 
				
			||||||
			System.err.println("Termination marker expected");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return game;
 | 
							return game;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public String getTag(String tagName) {
 | 
						public String getTag(String tagName) { return tagPairs.get(tagName); }
 | 
				
			||||||
		return tagPairs.get(tagName);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public boolean hasTag(String tagName) {
 | 
						public boolean hasTag(String tagName) { return tagPairs.containsKey(tagName); }
 | 
				
			||||||
		return tagPairs.containsKey(tagName);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public void setTag(String tagName, String tagValue) {
 | 
						public void setTag(String tagName, String tagValue) { tagPairs.put(tagName, tagValue); }
 | 
				
			||||||
		tagPairs.put(tagName, tagValue);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Board getBoard() { return board; }
 | 
						public Board getBoard() { return board; }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,10 @@ import java.io.FileReader;
 | 
				
			|||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import dev.kske.chess.board.Board;
 | 
					import javax.swing.JOptionPane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import dev.kske.chess.board.FENString;
 | 
				
			||||||
 | 
					import dev.kske.chess.exception.ChessException;
 | 
				
			||||||
import dev.kske.chess.game.Game;
 | 
					import dev.kske.chess.game.Game;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -24,9 +27,7 @@ public class FENDropTarget extends DropTargetAdapter {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	private MainWindow mainWindow;
 | 
						private MainWindow mainWindow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public FENDropTarget(MainWindow mainWindow) {
 | 
						public FENDropTarget(MainWindow mainWindow) { this.mainWindow = mainWindow; }
 | 
				
			||||||
		this.mainWindow = mainWindow;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@SuppressWarnings("unchecked")
 | 
						@SuppressWarnings("unchecked")
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
@@ -38,9 +39,18 @@ public class FENDropTarget extends DropTargetAdapter {
 | 
				
			|||||||
					final GamePane	gamePane	= mainWindow.addGamePane();
 | 
										final GamePane	gamePane	= mainWindow.addGamePane();
 | 
				
			||||||
					final String	fen			= br.readLine();
 | 
										final String	fen			= br.readLine();
 | 
				
			||||||
					DialogUtil.showGameConfigurationDialog(null, (whiteName, blackName) -> {
 | 
										DialogUtil.showGameConfigurationDialog(null, (whiteName, blackName) -> {
 | 
				
			||||||
						final Game game = new Game(gamePane.getBoardPane(), whiteName, blackName, new Board(fen));
 | 
											Game game;
 | 
				
			||||||
 | 
											try {
 | 
				
			||||||
 | 
												game = new Game(gamePane.getBoardPane(), whiteName, blackName, new FENString(fen).getBoard());
 | 
				
			||||||
							gamePane.setGame(game);
 | 
												gamePane.setGame(game);
 | 
				
			||||||
							game.start();
 | 
												game.start();
 | 
				
			||||||
 | 
											} catch (ChessException e) {
 | 
				
			||||||
 | 
												e.printStackTrace();
 | 
				
			||||||
 | 
												JOptionPane.showMessageDialog(mainWindow,
 | 
				
			||||||
 | 
														"Failed to load FEN string: " + e.toString(),
 | 
				
			||||||
 | 
														"FEN loading error",
 | 
				
			||||||
 | 
														JOptionPane.ERROR_MESSAGE);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
					evt.dropComplete(true);
 | 
										evt.dropComplete(true);
 | 
				
			||||||
				} catch (IOException e) {
 | 
									} catch (IOException e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,8 @@ import javax.swing.JMenuBar;
 | 
				
			|||||||
import javax.swing.JMenuItem;
 | 
					import javax.swing.JMenuItem;
 | 
				
			||||||
import javax.swing.JOptionPane;
 | 
					import javax.swing.JOptionPane;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import dev.kske.chess.board.Board;
 | 
					import dev.kske.chess.board.FENString;
 | 
				
			||||||
 | 
					import dev.kske.chess.exception.ChessException;
 | 
				
			||||||
import dev.kske.chess.game.Game;
 | 
					import dev.kske.chess.game.Game;
 | 
				
			||||||
import dev.kske.chess.io.EngineUtil;
 | 
					import dev.kske.chess.io.EngineUtil;
 | 
				
			||||||
import dev.kske.chess.pgn.PGNDatabase;
 | 
					import dev.kske.chess.pgn.PGNDatabase;
 | 
				
			||||||
@@ -42,8 +43,7 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
		JMenu gameMenu = new JMenu("Game");
 | 
							JMenu gameMenu = new JMenu("Game");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		JMenuItem newGameMenuItem = new JMenuItem("New Game");
 | 
							JMenuItem newGameMenuItem = new JMenuItem("New Game");
 | 
				
			||||||
		newGameMenuItem
 | 
							newGameMenuItem.addActionListener((evt) -> DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
				
			||||||
			.addActionListener((evt) -> DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
					 | 
				
			||||||
			GamePane	gamePane	= mainWindow.addGamePane();
 | 
								GamePane	gamePane	= mainWindow.addGamePane();
 | 
				
			||||||
			Game		game		= new Game(gamePane.getBoardPane(), whiteName, blackName);
 | 
								Game		game		= new Game(gamePane.getBoardPane(), whiteName, blackName);
 | 
				
			||||||
			gamePane.setGame(game);
 | 
								gamePane.setGame(game);
 | 
				
			||||||
@@ -64,10 +64,8 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
 | 
							JMenuItem addEngineMenuItem = new JMenuItem("Add engine");
 | 
				
			||||||
		addEngineMenuItem.addActionListener((evt) -> {
 | 
							addEngineMenuItem.addActionListener((evt) -> {
 | 
				
			||||||
			String enginePath = JOptionPane.showInputDialog(getParent(),
 | 
								String enginePath = JOptionPane
 | 
				
			||||||
					"Enter the path to a UCI-compatible chess engine:",
 | 
									.showInputDialog(getParent(), "Enter the path to a UCI-compatible chess engine:", "Engine selection", JOptionPane.QUESTION_MESSAGE);
 | 
				
			||||||
					"Engine selection",
 | 
					 | 
				
			||||||
					JOptionPane.QUESTION_MESSAGE);
 | 
					 | 
				
			||||||
			if (enginePath != null) EngineUtil.addEngine(enginePath);
 | 
								if (enginePath != null) EngineUtil.addEngine(enginePath);
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -83,7 +81,7 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		JMenuItem exportFENMenuItem = new JMenuItem("Export board to FEN");
 | 
							JMenuItem exportFENMenuItem = new JMenuItem("Export board to FEN");
 | 
				
			||||||
		exportFENMenuItem.addActionListener((evt) -> {
 | 
							exportFENMenuItem.addActionListener((evt) -> {
 | 
				
			||||||
			final String fen = mainWindow.getSelectedGamePane().getGame().getBoard().toFEN();
 | 
								final String fen = new FENString(mainWindow.getSelectedGamePane().getGame().getBoard()).toString();
 | 
				
			||||||
			Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(fen), null);
 | 
								Toolkit.getDefaultToolkit().getSystemClipboard().setContents(new StringSelection(fen), null);
 | 
				
			||||||
			JOptionPane.showMessageDialog(mainWindow, String.format("FEN-string copied to clipboard!%n%s", fen));
 | 
								JOptionPane.showMessageDialog(mainWindow, String.format("FEN-string copied to clipboard!%n%s", fen));
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
@@ -94,9 +92,16 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
			final GamePane	gamePane	= mainWindow.addGamePane();
 | 
								final GamePane	gamePane	= mainWindow.addGamePane();
 | 
				
			||||||
			final String	fen			= JOptionPane.showInputDialog("Enter a FEN string: ");
 | 
								final String	fen			= JOptionPane.showInputDialog("Enter a FEN string: ");
 | 
				
			||||||
			DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
								DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
				
			||||||
				final Game game = new Game(gamePane.getBoardPane(), whiteName, blackName, new Board(fen));
 | 
									Game game;
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										game = new Game(gamePane.getBoardPane(), whiteName, blackName, new FENString(fen).getBoard());
 | 
				
			||||||
					gamePane.setGame(game);
 | 
										gamePane.setGame(game);
 | 
				
			||||||
					game.start();
 | 
										game.start();
 | 
				
			||||||
 | 
									} catch (ChessException e) {
 | 
				
			||||||
 | 
										e.printStackTrace();
 | 
				
			||||||
 | 
										JOptionPane
 | 
				
			||||||
 | 
											.showMessageDialog(mainWindow, "Failed to load FEN string: " + e.toString(), "FEN loading error", JOptionPane.ERROR_MESSAGE);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		toolsMenu.add(loadFromFENMenuItem);
 | 
							toolsMenu.add(loadFromFENMenuItem);
 | 
				
			||||||
@@ -113,9 +118,18 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
					final GamePane	gamePane	= mainWindow.addGamePane(name);
 | 
										final GamePane	gamePane	= mainWindow.addGamePane(name);
 | 
				
			||||||
					final String	fen			= new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
 | 
										final String	fen			= new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
 | 
				
			||||||
					DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
										DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
				
			||||||
						final Game game = new Game(gamePane.getBoardPane(), whiteName, blackName, new Board(fen));
 | 
											Game game;
 | 
				
			||||||
 | 
											try {
 | 
				
			||||||
 | 
												game = new Game(gamePane.getBoardPane(), whiteName, blackName, new FENString(fen).getBoard());
 | 
				
			||||||
							gamePane.setGame(game);
 | 
												gamePane.setGame(game);
 | 
				
			||||||
							game.start();
 | 
												game.start();
 | 
				
			||||||
 | 
											} catch (ChessException e) {
 | 
				
			||||||
 | 
												e.printStackTrace();
 | 
				
			||||||
 | 
												JOptionPane.showMessageDialog(mainWindow,
 | 
				
			||||||
 | 
														"Failed to load FEN string: " + e.toString(),
 | 
				
			||||||
 | 
														"FEN loading error",
 | 
				
			||||||
 | 
														JOptionPane.ERROR_MESSAGE);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
					});
 | 
										});
 | 
				
			||||||
				} catch (Exception e) {
 | 
									} catch (Exception e) {
 | 
				
			||||||
					e.printStackTrace();
 | 
										e.printStackTrace();
 | 
				
			||||||
@@ -134,14 +148,10 @@ public class MenuBar extends JMenuBar {
 | 
				
			|||||||
						String[] gameNames = new String[pgnDB.getGames().size()];
 | 
											String[] gameNames = new String[pgnDB.getGames().size()];
 | 
				
			||||||
						for (int i = 0; i < gameNames.length; i++) {
 | 
											for (int i = 0; i < gameNames.length; i++) {
 | 
				
			||||||
							final PGNGame game = pgnDB.getGames().get(i);
 | 
												final PGNGame game = pgnDB.getGames().get(i);
 | 
				
			||||||
							gameNames[i] = String.format("%s vs %s: %s",
 | 
												gameNames[i] = String.format("%s vs %s: %s", game.getTag("White"), game.getTag("Black"), game.getTag("Result"));
 | 
				
			||||||
									game.getTag("White"),
 | 
					 | 
				
			||||||
									game.getTag("Black"),
 | 
					 | 
				
			||||||
									game.getTag("Result"));
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						JComboBox<String> comboBox = new JComboBox<>(gameNames);
 | 
											JComboBox<String> comboBox = new JComboBox<>(gameNames);
 | 
				
			||||||
						JOptionPane
 | 
											JOptionPane.showInputDialog(mainWindow, comboBox, "Select a game", JOptionPane.QUESTION_MESSAGE);
 | 
				
			||||||
							.showInputDialog(mainWindow, comboBox, "Select a game", JOptionPane.QUESTION_MESSAGE);
 | 
					 | 
				
			||||||
						DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
											DialogUtil.showGameConfigurationDialog(mainWindow, (whiteName, blackName) -> {
 | 
				
			||||||
							final Game game = new Game(gamePane.getBoardPane(), whiteName, blackName,
 | 
												final Game game = new Game(gamePane.getBoardPane(), whiteName, blackName,
 | 
				
			||||||
									pgnDB.getGames().get(comboBox.getSelectedIndex()).getBoard());
 | 
														pgnDB.getGames().get(comboBox.getSelectedIndex()).getBoard());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ class FENStringTest {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	@BeforeEach
 | 
						@BeforeEach
 | 
				
			||||||
	void setUp() throws Exception {
 | 
						void setUp() throws Exception {
 | 
				
			||||||
		fenStrings.addAll(Arrays.asList("rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b - - 1 2"));
 | 
							fenStrings.addAll(Arrays.asList("rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2"));
 | 
				
			||||||
		Board board = new Board();
 | 
							Board board = new Board();
 | 
				
			||||||
		board.set(Position.fromLAN("c7"), null);
 | 
							board.set(Position.fromLAN("c7"), null);
 | 
				
			||||||
		board.set(Position.fromLAN("c5"), new Pawn(Color.BLACK, board));
 | 
							board.set(Position.fromLAN("c5"), new Pawn(Color.BLACK, board));
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user