Working on board loading from FEN-encoded string
This commit is contained in:
parent
e7af9f40c2
commit
90c100e0e1
@ -64,7 +64,7 @@ public class Board implements Cloneable {
|
|||||||
kingPos = new HashMap<>();
|
kingPos = new HashMap<>();
|
||||||
castlingRights = new HashMap<>();
|
castlingRights = new HashMap<>();
|
||||||
log = new Log();
|
log = new Log();
|
||||||
initializeDefaultPositions();
|
initDefaultPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,7 +327,7 @@ public class Board implements Cloneable {
|
|||||||
/**
|
/**
|
||||||
* Initialized the board array with the default chess pieces and positions.
|
* Initialized the board array with the default chess pieces and positions.
|
||||||
*/
|
*/
|
||||||
public void initializeDefaultPositions() {
|
public void initDefaultPositions() {
|
||||||
// Initialize pawns
|
// Initialize pawns
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
boardArr[i][1] = new Pawn(Color.BLACK, this);
|
boardArr[i][1] = new Pawn(Color.BLACK, this);
|
||||||
@ -383,34 +383,63 @@ public class Board implements Cloneable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A new instance of this class with a shallow copy of both
|
* Initialized the board with a position specified in a FEN-encoded string.
|
||||||
* {@code kingPos} and {code boardArr}
|
*
|
||||||
|
* @param fen The FEN-encoded string representing target state of the board
|
||||||
*/
|
*/
|
||||||
@Override
|
public void initFromFEN(String fen) {
|
||||||
public Object clone() {
|
String[] parts = fen.split(" ");
|
||||||
Board board = null;
|
log.reset();
|
||||||
try {
|
|
||||||
board = (Board) super.clone();
|
// Piece placement (from white's perspective)
|
||||||
} catch (CloneNotSupportedException ex) {
|
String[] rows = parts[0].split("/");
|
||||||
ex.printStackTrace();
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
board.boardArr = new Piece[8][8];
|
|
||||||
for (int i = 0; i < 8; i++)
|
|
||||||
for (int j = 0; j < 8; j++) {
|
|
||||||
if (boardArr[i][j] == null) continue;
|
|
||||||
board.boardArr[i][j] = (Piece) boardArr[i][j].clone();
|
|
||||||
board.boardArr[i][j].board = board;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
board.kingPos = new HashMap<>();
|
// Active color
|
||||||
board.kingPos.putAll(kingPos);
|
log.setActiveColor(Color.fromFirstChar(parts[1].charAt(0)));
|
||||||
board.log = (Log) log.clone();
|
|
||||||
|
|
||||||
return board;
|
// TODO: other fields, synchronize with log and game
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A FEN string representing the board
|
* @return A FEN-encoded string representing the board
|
||||||
*/
|
*/
|
||||||
public String toFEN() {
|
public String toFEN() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
@ -458,6 +487,7 @@ public class Board implements Cloneable {
|
|||||||
// Active color
|
// Active color
|
||||||
sb.append(" " + log.getActiveColor().firstChar());
|
sb.append(" " + log.getActiveColor().firstChar());
|
||||||
|
|
||||||
|
// Castling Rights
|
||||||
sb.append(' ');
|
sb.append(' ');
|
||||||
StringBuilder castlingSb = new StringBuilder();
|
StringBuilder castlingSb = new StringBuilder();
|
||||||
if (castlingRights.get(Color.WHITE).get(Type.KING)) castlingSb.append('K');
|
if (castlingRights.get(Color.WHITE).get(Type.KING)) castlingSb.append('K');
|
||||||
@ -469,7 +499,7 @@ public class Board implements Cloneable {
|
|||||||
|
|
||||||
final LoggedMove lastMove = log.getLast();
|
final LoggedMove lastMove = log.getLast();
|
||||||
|
|
||||||
// En passant availabillity
|
// En passant availability
|
||||||
sb.append(" " + (lastMove == null || lastMove.enPassant == null ? "-" : lastMove.enPassant.toSAN()));
|
sb.append(" " + (lastMove == null || lastMove.enPassant == null ? "-" : lastMove.enPassant.toSAN()));
|
||||||
|
|
||||||
// Halfmove clock
|
// Halfmove clock
|
||||||
@ -481,6 +511,33 @@ public class Board implements Cloneable {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A new instance of this class with a shallow copy of both
|
||||||
|
* {@code kingPos} and {code boardArr}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object clone() {
|
||||||
|
Board board = null;
|
||||||
|
try {
|
||||||
|
board = (Board) super.clone();
|
||||||
|
} catch (CloneNotSupportedException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
board.boardArr = new Piece[8][8];
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
for (int j = 0; j < 8; j++) {
|
||||||
|
if (boardArr[i][j] == null) continue;
|
||||||
|
board.boardArr[i][j] = (Piece) boardArr[i][j].clone();
|
||||||
|
board.boardArr[i][j].board = board;
|
||||||
|
}
|
||||||
|
|
||||||
|
board.kingPos = new HashMap<>();
|
||||||
|
board.kingPos.putAll(kingPos);
|
||||||
|
board.log = (Log) log.clone();
|
||||||
|
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
public Piece get(Position pos) {
|
public Piece get(Position pos) {
|
||||||
return boardArr[pos.x][pos.y];
|
return boardArr[pos.x][pos.y];
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,8 @@ public class Log implements Cloneable {
|
|||||||
|
|
||||||
public Color getActiveColor() { return activeColor; }
|
public Color getActiveColor() { return activeColor; }
|
||||||
|
|
||||||
|
public void setActiveColor(Color activeColor) { this.activeColor = activeColor; }
|
||||||
|
|
||||||
public List<LoggedMove> getLoggedMoves() { return moves; }
|
public List<LoggedMove> getLoggedMoves() { return moves; }
|
||||||
|
|
||||||
public static class LoggedMove {
|
public static class LoggedMove {
|
||||||
|
@ -91,12 +91,16 @@ public abstract class Piece implements Cloneable {
|
|||||||
public static enum Color {
|
public static enum Color {
|
||||||
WHITE, BLACK;
|
WHITE, BLACK;
|
||||||
|
|
||||||
public Color opposite() {
|
public static Color fromFirstChar(char c) {
|
||||||
return this == WHITE ? BLACK : WHITE;
|
return Character.toLowerCase(c) == 'w' ? WHITE : BLACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
public char firstChar() {
|
public char firstChar() {
|
||||||
return this == WHITE ? 'w' : 'b';
|
return this == WHITE ? 'w' : 'b';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Color opposite() {
|
||||||
|
return this == WHITE ? BLACK : WHITE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ public class Game {
|
|||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
players.values().forEach(Player::cancelMove);
|
players.values().forEach(Player::cancelMove);
|
||||||
board.initializeDefaultPositions();
|
board.initDefaultPositions();
|
||||||
boardComponent.repaint();
|
boardComponent.repaint();
|
||||||
overlayComponent.clearDots();
|
overlayComponent.clearDots();
|
||||||
overlayComponent.clearArrow();
|
overlayComponent.clearArrow();
|
||||||
|
@ -82,6 +82,18 @@ public class MenuBar extends JMenuBar {
|
|||||||
.setContents(new StringSelection(mainWindow.getGame().getBoard().toFEN()), null));
|
.setContents(new StringSelection(mainWindow.getGame().getBoard().toFEN()), null));
|
||||||
toolsMenu.add(exportFENMenuItem);
|
toolsMenu.add(exportFENMenuItem);
|
||||||
|
|
||||||
|
// TODO: Synchronize with game
|
||||||
|
JMenuItem loadFromFENMenuItem = new JMenuItem("Load board from FEN");
|
||||||
|
loadFromFENMenuItem.addActionListener((evt) -> {
|
||||||
|
mainWindow.getGame().reset();
|
||||||
|
mainWindow.getGame()
|
||||||
|
.getBoard()
|
||||||
|
.initFromFEN(JOptionPane.showInputDialog("Enter a FEN string: "));
|
||||||
|
mainWindow.getBoardPane().getBoardComponent().repaint();
|
||||||
|
|
||||||
|
});
|
||||||
|
toolsMenu.add(loadFromFENMenuItem);
|
||||||
|
|
||||||
add(toolsMenu);
|
add(toolsMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user