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<>();
|
||||
castlingRights = new HashMap<>();
|
||||
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.
|
||||
*/
|
||||
public void initializeDefaultPositions() {
|
||||
public void initDefaultPositions() {
|
||||
// Initialize pawns
|
||||
for (int i = 0; i < 8; i++) {
|
||||
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
|
||||
* {@code kingPos} and {code boardArr}
|
||||
* Initialized the board with a position specified in a FEN-encoded string.
|
||||
*
|
||||
* @param fen The FEN-encoded string representing target state of the board
|
||||
*/
|
||||
@Override
|
||||
public Object clone() {
|
||||
Board board = null;
|
||||
try {
|
||||
board = (Board) super.clone();
|
||||
} catch (CloneNotSupportedException ex) {
|
||||
ex.printStackTrace();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
// Active color
|
||||
log.setActiveColor(Color.fromFirstChar(parts[1].charAt(0)));
|
||||
|
||||
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() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
@ -458,6 +487,7 @@ public class Board implements Cloneable {
|
||||
// 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');
|
||||
@ -469,7 +499,7 @@ public class Board implements Cloneable {
|
||||
|
||||
final LoggedMove lastMove = log.getLast();
|
||||
|
||||
// En passant availabillity
|
||||
// En passant availability
|
||||
sb.append(" " + (lastMove == null || lastMove.enPassant == null ? "-" : lastMove.enPassant.toSAN()));
|
||||
|
||||
// Halfmove clock
|
||||
@ -481,6 +511,33 @@ public class Board implements Cloneable {
|
||||
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) {
|
||||
return boardArr[pos.x][pos.y];
|
||||
}
|
||||
|
@ -69,6 +69,8 @@ public class Log implements Cloneable {
|
||||
|
||||
public Color getActiveColor() { return activeColor; }
|
||||
|
||||
public void setActiveColor(Color activeColor) { this.activeColor = activeColor; }
|
||||
|
||||
public List<LoggedMove> getLoggedMoves() { return moves; }
|
||||
|
||||
public static class LoggedMove {
|
||||
|
@ -91,12 +91,16 @@ public abstract class Piece implements Cloneable {
|
||||
public static enum Color {
|
||||
WHITE, BLACK;
|
||||
|
||||
public Color opposite() {
|
||||
return this == WHITE ? BLACK : WHITE;
|
||||
public static Color fromFirstChar(char c) {
|
||||
return Character.toLowerCase(c) == 'w' ? WHITE : BLACK;
|
||||
}
|
||||
|
||||
public char firstChar() {
|
||||
return this == WHITE ? 'w' : 'b';
|
||||
}
|
||||
|
||||
public Color opposite() {
|
||||
return this == WHITE ? BLACK : WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public class Game {
|
||||
|
||||
public void reset() {
|
||||
players.values().forEach(Player::cancelMove);
|
||||
board.initializeDefaultPositions();
|
||||
board.initDefaultPositions();
|
||||
boardComponent.repaint();
|
||||
overlayComponent.clearDots();
|
||||
overlayComponent.clearArrow();
|
||||
|
@ -82,6 +82,18 @@ public class MenuBar extends JMenuBar {
|
||||
.setContents(new StringSelection(mainWindow.getGame().getBoard().toFEN()), null));
|
||||
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);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user