Implemented saving to PGN file
+ copyVariations parameter in copy constructors of Board and Log This procedure still required work in the form of efficiently rewinding the board to the first position for SAN move extraction and shortening SAN moves to the smallest possible representation.
This commit is contained in:
parent
6af213ed4f
commit
44f91591b4
@ -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