Refined IO functionality, fixed FEN string serialization and deserialization #7
@ -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