Implemented game serialization to the PGN format #16
@ -34,9 +34,9 @@ public class Board {
|
|||||||
* apart from the current {@link MoveNode}.
|
* apart from the current {@link MoveNode}.
|
||||||
*
|
*
|
||||||
* @param other The {@link Board} instance to copy
|
* @param other The {@link Board} instance to copy
|
||||||
|
* @param copyVariations TODO
|
||||||
*/
|
*/
|
||||||
public Board(Board other) {
|
public Board(Board other, boolean copyVariations) {
|
||||||
boardArr = new Piece[8][8];
|
|
||||||
for (int i = 0; i < 8; i++)
|
for (int i = 0; i < 8; i++)
|
||||||
for (int j = 0; j < 8; j++) {
|
for (int j = 0; j < 8; j++) {
|
||||||
if (other.boardArr[i][j] == null) continue;
|
if (other.boardArr[i][j] == null) continue;
|
||||||
@ -45,7 +45,11 @@ public class Board {
|
|||||||
}
|
}
|
||||||
|
|
||||||
kingPos.putAll(other.kingPos);
|
kingPos.putAll(other.kingPos);
|
||||||
log = new Log(other.log, false);
|
log = new Log(other.log, copyVariations);
|
||||||
|
|
||||||
|
// Synchronize the current move node with the board
|
||||||
|
while (log.getLast().hasVariations())
|
||||||
|
log.selectNextNode(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@ public class Log implements Iterable<MoveNode> {
|
|||||||
|
|
||||||
// The new root is the current node of the copied instance
|
// The new root is the current node of the copied instance
|
||||||
if (!other.isEmpty()) {
|
if (!other.isEmpty()) {
|
||||||
root = new MoveNode(other.current, copyVariations);
|
root = new MoveNode(other.root, copyVariations);
|
||||||
root.setParent(null);
|
root.setParent(null);
|
||||||
current = root;
|
current = root;
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ public class Log implements Iterable<MoveNode> {
|
|||||||
|
|
||||||
public int getFullmoveNumber() { return fullmoveNumber; }
|
public int getFullmoveNumber() { return fullmoveNumber; }
|
||||||
|
|
||||||
public void setFullmoveNumber(int fullmoveCounter) { this.fullmoveNumber = fullmoveCounter; }
|
public void setFullmoveNumber(int fullmoveCounter) { fullmoveNumber = fullmoveCounter; }
|
||||||
|
|
||||||
public int getHalfmoveClock() { return halfmoveClock; }
|
public int getHalfmoveClock() { return halfmoveClock; }
|
||||||
|
|
||||||
|
@ -157,8 +157,8 @@ public class Move {
|
|||||||
|
|
||||||
// Position
|
// Position
|
||||||
// TODO: Deconstruct position into optional file or rank
|
// TODO: Deconstruct position into optional file or rank
|
||||||
// TODO: Omit if the move is a pawn push
|
// Omit position if the move is a pawn push
|
||||||
sb.append(pos.toLAN());
|
if (!(piece instanceof Pawn && xDist == 0)) sb.append(pos.toLAN());
|
||||||
|
|
||||||
// Capture indicator
|
// Capture indicator
|
||||||
if (board.get(dest) != null) sb.append('x');
|
if (board.get(dest) != null) sb.append('x');
|
||||||
|
@ -64,11 +64,11 @@ public class MoveNode {
|
|||||||
other.fullmoveCounter, other.halfmoveClock);
|
other.fullmoveCounter, other.halfmoveClock);
|
||||||
if (copyVariations && other.variations != null) {
|
if (copyVariations && other.variations != null) {
|
||||||
if (variations == null) variations = new ArrayList<>();
|
if (variations == null) variations = new ArrayList<>();
|
||||||
other.variations.forEach(variation -> {
|
for (MoveNode variation : other.variations) {
|
||||||
MoveNode copy = new MoveNode(variation, true);
|
MoveNode copy = new MoveNode(variation, true);
|
||||||
copy.parent = this;
|
copy.parent = this;
|
||||||
variations.add(copy);
|
variations.add(copy);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public class AIPlayer extends Player {
|
|||||||
/*
|
/*
|
||||||
* Get a copy of the board and the available moves.
|
* Get a copy of the board and the available moves.
|
||||||
*/
|
*/
|
||||||
Board board = new Board(this.board);
|
Board board = new Board(this.board, false);
|
||||||
List<Move> moves = board.getMoves(color);
|
List<Move> moves = board.getMoves(color);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -66,7 +66,7 @@ public class AIPlayer extends Player {
|
|||||||
for (int i = 0; i < numThreads; i++) {
|
for (int i = 0; i < numThreads; i++) {
|
||||||
if (rem-- > 0) ++endIndex;
|
if (rem-- > 0) ++endIndex;
|
||||||
endIndex += step;
|
endIndex += step;
|
||||||
processors.add(new MoveProcessor(new Board(board), moves.subList(beginIndex, endIndex), color,
|
processors.add(new MoveProcessor(new Board(board, false), moves.subList(beginIndex, endIndex), color,
|
||||||
maxDepth, alphaBetaThreshold));
|
maxDepth, alphaBetaThreshold));
|
||||||
beginIndex = endIndex;
|
beginIndex = endIndex;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package dev.kske.chess.pgn;
|
package dev.kske.chess.pgn;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.regex.MatchResult;
|
import java.util.regex.MatchResult;
|
||||||
@ -9,7 +11,7 @@ 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.board.FENString;
|
||||||
import dev.kske.chess.board.Piece.Color;
|
import dev.kske.chess.board.Move;
|
||||||
import dev.kske.chess.exception.ChessException;
|
import dev.kske.chess.exception.ChessException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,11 +80,25 @@ public class PGNGame {
|
|||||||
// Insert newline if tags were printed
|
// Insert newline if tags were printed
|
||||||
if (!tagPairs.isEmpty()) pw.println();
|
if (!tagPairs.isEmpty()) pw.println();
|
||||||
|
|
||||||
|
// Collect SAN moves
|
||||||
|
Board clone = new Board(board, true);
|
||||||
|
List<String> sanMoves = new ArrayList<>();
|
||||||
|
|
||||||
|
while (clone.getLog().hasParent()) {
|
||||||
|
Move move = clone.getLog().getLast().move;
|
||||||
|
clone.revert();
|
||||||
|
sanMoves.add(move.toSAN(clone));
|
||||||
|
}
|
||||||
|
|
||||||
// Write movetext
|
// Write movetext
|
||||||
board.getLog().forEach(m -> {
|
for (int i = sanMoves.size() - 1; i >= 0; i--)
|
||||||
if (m.activeColor == Color.BLACK) pw.printf("%d. ", m.fullmoveCounter);
|
pw.printf("%s ", sanMoves.get(i));
|
||||||
pw.printf("%s ", m.move); // TODO: Convert to SAN
|
|
||||||
});
|
// Write movetext
|
||||||
|
// board.getLog().forEach(m -> {
|
||||||
|
// if (m.activeColor == Color.BLACK) pw.printf("%d. ", m.fullmoveCounter);
|
||||||
|
// pw.printf("%s ", m.move.toSAN(board));
|
||||||
|
// });
|
||||||
|
|
||||||
// Write game termination marker
|
// Write game termination marker
|
||||||
pw.print(tagPairs.get("Result"));
|
pw.print(tagPairs.get("Result"));
|
||||||
|
@ -62,7 +62,7 @@ public class DialogUtil {
|
|||||||
dialogPanel.add(lblWhite);
|
dialogPanel.add(lblWhite);
|
||||||
|
|
||||||
JComboBox<Object> cbWhite = new JComboBox<>();
|
JComboBox<Object> cbWhite = new JComboBox<>();
|
||||||
cbWhite.setModel(new DefaultComboBoxModel<Object>(options.toArray()));
|
cbWhite.setModel(new DefaultComboBoxModel<>(options.toArray()));
|
||||||
cbWhite.setBounds(98, 9, 159, 22);
|
cbWhite.setBounds(98, 9, 159, 22);
|
||||||
dialogPanel.add(cbWhite);
|
dialogPanel.add(cbWhite);
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class DialogUtil {
|
|||||||
dialogPanel.add(lblBlack);
|
dialogPanel.add(lblBlack);
|
||||||
|
|
||||||
JComboBox<Object> cbBlack = new JComboBox<>();
|
JComboBox<Object> cbBlack = new JComboBox<>();
|
||||||
cbBlack.setModel(new DefaultComboBoxModel<Object>(options.toArray()));
|
cbBlack.setModel(new DefaultComboBoxModel<>(options.toArray()));
|
||||||
cbBlack.setBounds(98, 36, 159, 22);
|
cbBlack.setBounds(98, 36, 159, 22);
|
||||||
dialogPanel.add(cbBlack);
|
dialogPanel.add(cbBlack);
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class BoardTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
void testClone() {
|
void testClone() {
|
||||||
Board clone = new Board(board);
|
Board clone = new Board(board, false);
|
||||||
assertNotSame(clone, board);
|
assertNotSame(clone, board);
|
||||||
assertNotSame(clone.getBoardArr(), board.getBoardArr());
|
assertNotSame(clone.getBoardArr(), board.getBoardArr());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user