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
927d5ed254
commit
719e4f99ef
@ -34,9 +34,9 @@ public class Board {
|
||||
* apart from the current {@link MoveNode}.
|
||||
*
|
||||
* @param other The {@link Board} instance to copy
|
||||
* @param copyVariations TODO
|
||||
*/
|
||||
public Board(Board other) {
|
||||
boardArr = new Piece[8][8];
|
||||
public Board(Board other, boolean copyVariations) {
|
||||
for (int i = 0; i < 8; i++)
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (other.boardArr[i][j] == null) continue;
|
||||
@ -45,7 +45,11 @@ public class Board {
|
||||
}
|
||||
|
||||
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
|
||||
if (!other.isEmpty()) {
|
||||
root = new MoveNode(other.current, copyVariations);
|
||||
root = new MoveNode(other.root, copyVariations);
|
||||
root.setParent(null);
|
||||
current = root;
|
||||
}
|
||||
@ -244,7 +244,7 @@ public class Log implements Iterable<MoveNode> {
|
||||
|
||||
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; }
|
||||
|
||||
|
@ -157,8 +157,8 @@ public class Move {
|
||||
|
||||
// Position
|
||||
// TODO: Deconstruct position into optional file or rank
|
||||
// TODO: Omit if the move is a pawn push
|
||||
sb.append(pos.toLAN());
|
||||
// Omit position if the move is a pawn push
|
||||
if (!(piece instanceof Pawn && xDist == 0)) sb.append(pos.toLAN());
|
||||
|
||||
// Capture indicator
|
||||
if (board.get(dest) != null) sb.append('x');
|
||||
|
@ -64,11 +64,11 @@ public class MoveNode {
|
||||
other.fullmoveCounter, other.halfmoveClock);
|
||||
if (copyVariations && other.variations != null) {
|
||||
if (variations == null) variations = new ArrayList<>();
|
||||
other.variations.forEach(variation -> {
|
||||
for (MoveNode variation : other.variations) {
|
||||
MoveNode copy = new MoveNode(variation, true);
|
||||
copy.parent = this;
|
||||
variations.add(copy);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ public class AIPlayer extends Player {
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
@ -66,7 +66,7 @@ public class AIPlayer extends Player {
|
||||
for (int i = 0; i < numThreads; i++) {
|
||||
if (rem-- > 0) ++endIndex;
|
||||
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));
|
||||
beginIndex = endIndex;
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package dev.kske.chess.pgn;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
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.FENString;
|
||||
import dev.kske.chess.board.Piece.Color;
|
||||
import dev.kske.chess.board.Move;
|
||||
import dev.kske.chess.exception.ChessException;
|
||||
|
||||
/**
|
||||
@ -78,11 +80,25 @@ public class PGNGame {
|
||||
// Insert newline if tags were printed
|
||||
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
|
||||
board.getLog().forEach(m -> {
|
||||
if (m.activeColor == Color.BLACK) pw.printf("%d. ", m.fullmoveCounter);
|
||||
pw.printf("%s ", m.move); // TODO: Convert to SAN
|
||||
});
|
||||
for (int i = sanMoves.size() - 1; i >= 0; i--)
|
||||
pw.printf("%s ", sanMoves.get(i));
|
||||
|
||||
// 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
|
||||
pw.print(tagPairs.get("Result"));
|
||||
|
@ -62,7 +62,7 @@ public class DialogUtil {
|
||||
dialogPanel.add(lblWhite);
|
||||
|
||||
JComboBox<Object> cbWhite = new JComboBox<>();
|
||||
cbWhite.setModel(new DefaultComboBoxModel<Object>(options.toArray()));
|
||||
cbWhite.setModel(new DefaultComboBoxModel<>(options.toArray()));
|
||||
cbWhite.setBounds(98, 9, 159, 22);
|
||||
dialogPanel.add(cbWhite);
|
||||
|
||||
@ -72,7 +72,7 @@ public class DialogUtil {
|
||||
dialogPanel.add(lblBlack);
|
||||
|
||||
JComboBox<Object> cbBlack = new JComboBox<>();
|
||||
cbBlack.setModel(new DefaultComboBoxModel<Object>(options.toArray()));
|
||||
cbBlack.setModel(new DefaultComboBoxModel<>(options.toArray()));
|
||||
cbBlack.setBounds(98, 36, 159, 22);
|
||||
dialogPanel.add(cbBlack);
|
||||
|
||||
|
@ -31,7 +31,7 @@ class BoardTest {
|
||||
*/
|
||||
@Test
|
||||
void testClone() {
|
||||
Board clone = new Board(board);
|
||||
Board clone = new Board(board, false);
|
||||
assertNotSame(clone, board);
|
||||
assertNotSame(clone.getBoardArr(), board.getBoardArr());
|
||||
|
||||
|
Reference in New Issue
Block a user