Fixed LogPanel to support new log data model

This commit is contained in:
Kai S. K. Engelbart 2019-09-23 17:37:42 +02:00
parent 2c3ac42516
commit b969ff9e2b
4 changed files with 119 additions and 27 deletions

View File

@ -1,8 +1,10 @@
package dev.kske.chess.board; package dev.kske.chess.board;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import java.util.List;
import dev.kske.chess.board.Log.MoveNode;
import dev.kske.chess.board.Piece.Color; import dev.kske.chess.board.Piece.Color;
/** /**
@ -11,7 +13,7 @@ import dev.kske.chess.board.Piece.Color;
* Created: <strong>09.07.2019</strong><br> * Created: <strong>09.07.2019</strong><br>
* Author: <strong>Kai S. K. Engelbart</strong> * Author: <strong>Kai S. K. Engelbart</strong>
*/ */
public class Log { public class Log implements Iterable<MoveNode> {
private MoveNode root, current; private MoveNode root, current;
@ -46,6 +48,28 @@ public class Log {
} }
} }
@Override
public Iterator<MoveNode> iterator() {
return new Iterator<MoveNode>() {
private MoveNode current = root;
private boolean hasNext = true;
@Override
public boolean hasNext() {
return hasNext;
}
@Override
public MoveNode next() {
MoveNode result = current;
if (current.hasVariations()) current = current.variations.get(0);
else hasNext = false;
return result;
}
};
}
/** /**
* Adds a move to the move history and adjusts the log to the new position. * Adds a move to the move history and adjusts the log to the new position.
* *
@ -75,18 +99,19 @@ public class Log {
* move. * move.
*/ */
public void removeLast() { public void removeLast() {
if (!isEmpty() && current.parent != null) { if (hasParent()) {
current.parent.variations.remove(current); current.parent.variations.remove(current);
current = current.parent; current = current.parent;
activeColor = current.activeColor; update();
enPassant = current.enPassant;
fullmoveCounter = current.fullmoveCounter;
halfmoveClock = current.halfmoveClock;
} else reset(); } else reset();
} }
public boolean isEmpty() { return root == null; } public boolean isEmpty() { return root == null; }
public boolean hasParent() {
return !isEmpty() && current.parent != null;
}
/** /**
* Reverts the log to its initial state corresponding to the default board * Reverts the log to its initial state corresponding to the default board
* position. * position.
@ -100,6 +125,44 @@ public class Log {
halfmoveClock = 0; halfmoveClock = 0;
} }
/**
*
* @param index
*/
public void selectNextNode(int index) {
if (!isEmpty() && current.variations != null && index < current.variations.size()) {
current = current.variations.get(index);
update();
}
}
/**
* Selects the parent of the current {@link MoveNode} as the current node.
*/
public void selectPreviousNode() {
if (hasParent()) {
current = current.parent;
update();
}
}
/**
* Selects the root {@link MoveNode} as the current node.
*/
public void selectRootNode() {
if (!isEmpty()) {
current = root;
update();
}
}
private void update() {
activeColor = current.activeColor;
enPassant = current.enPassant;
fullmoveCounter = current.fullmoveCounter;
halfmoveClock = current.halfmoveClock;
}
/** /**
* @return The first logged move, or {@code null} if there is none * @return The first logged move, or {@code null} if there is none
*/ */
@ -196,5 +259,9 @@ public class Log {
* @return A list of all variations associated with this {@link MoveNode} * @return A list of all variations associated with this {@link MoveNode}
*/ */
public List<MoveNode> getVariations() { return variations; } public List<MoveNode> getVariations() { return variations; }
public boolean hasVariations() {
return variations != null && variations.size() > 0;
}
} }
} }

View File

@ -80,8 +80,6 @@ public class Game {
// Run garbage collection // Run garbage collection
System.gc(); System.gc();
System.out.printf("%s: %s%n", player.color, move);
System.out.println("FEN: " + board.toFEN());
EventBus.getInstance().dispatch(new MoveEvent(move)); EventBus.getInstance().dispatch(new MoveEvent(move));
GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite()); GameState eventType = board.getGameEventType(board.getDest(move).getColor().opposite());
switch (eventType) { switch (eventType) {

View File

@ -28,6 +28,10 @@ public class GamePane extends JComponent {
private LogPanel logPanel; private LogPanel logPanel;
private Game game; private Game game;
private Color activeColor; private Color activeColor;
private JPanel moveSelectionPanel;
private JButton btnNext;
private JButton btnFirst;
private JButton btnLast;
public GamePane() { public GamePane() {
activeColor = Color.WHITE; activeColor = Color.WHITE;
@ -35,8 +39,8 @@ public class GamePane extends JComponent {
GridBagLayout gridBagLayout = new GridBagLayout(); GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] { 450, 1, 0 }; gridBagLayout.columnWidths = new int[] { 450, 1, 0 };
gridBagLayout.rowHeights = new int[] { 33, 267, 1, 0 }; gridBagLayout.rowHeights = new int[] { 33, 267, 1, 0 };
gridBagLayout.columnWeights = new double[] { 0.0, 0.0, Double.MIN_VALUE }; gridBagLayout.columnWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE }; gridBagLayout.rowWeights = new double[] { 1.0, 0.0, 0.0, Double.MIN_VALUE };
setLayout(gridBagLayout); setLayout(gridBagLayout);
JPanel toolPanel = new JPanel(); JPanel toolPanel = new JPanel();
@ -58,7 +62,31 @@ public class GamePane extends JComponent {
gbc_toolPanel.fill = GridBagConstraints.HORIZONTAL; gbc_toolPanel.fill = GridBagConstraints.HORIZONTAL;
gbc_toolPanel.gridx = 0; gbc_toolPanel.gridx = 0;
gbc_toolPanel.gridy = 0; gbc_toolPanel.gridy = 0;
gbc_toolPanel.gridwidth = 2;
add(toolPanel, gbc_toolPanel); add(toolPanel, gbc_toolPanel);
moveSelectionPanel = new JPanel();
GridBagConstraints gbc_moveSelectionPanel = new GridBagConstraints();
gbc_moveSelectionPanel.fill = GridBagConstraints.BOTH;
gbc_moveSelectionPanel.gridx = 2;
gbc_moveSelectionPanel.gridy = 0;
add(moveSelectionPanel, gbc_moveSelectionPanel);
btnFirst = new JButton("First");
btnFirst.setEnabled(false);
moveSelectionPanel.add(btnFirst);
JButton btnPreviousMove = new JButton("Previous");
btnPreviousMove.setEnabled(false);
moveSelectionPanel.add(btnPreviousMove);
btnNext = new JButton("Next");
btnNext.setEnabled(false);
moveSelectionPanel.add(btnNext);
btnLast = new JButton("Last");
btnLast.setEnabled(false);
moveSelectionPanel.add(btnLast);
boardPane = new BoardPane(); boardPane = new BoardPane();
GridBagConstraints gbc_boardPane = new GridBagConstraints(); GridBagConstraints gbc_boardPane = new GridBagConstraints();
gbc_boardPane.fill = GridBagConstraints.BOTH; gbc_boardPane.fill = GridBagConstraints.BOTH;
@ -93,10 +121,11 @@ public class GamePane extends JComponent {
// Initialize LogPanel // Initialize LogPanel
logPanel = new LogPanel(); logPanel = new LogPanel();
GridBagConstraints gbc_logPanel = new GridBagConstraints(); GridBagConstraints gbc_logPanel = new GridBagConstraints();
gbc_logPanel.anchor = GridBagConstraints.EAST; gbc_logPanel.anchor = GridBagConstraints.EAST;
gbc_logPanel.fill = GridBagConstraints.VERTICAL; gbc_logPanel.fill = GridBagConstraints.VERTICAL;
gbc_logPanel.gridx = 2; gbc_logPanel.gridx = 2;
gbc_logPanel.gridy = 1; gbc_logPanel.gridy = 1;
gbc_logPanel.gridheight = 2;
add(logPanel, gbc_logPanel); add(logPanel, gbc_logPanel);
} }

View File

@ -1,10 +1,9 @@
package dev.kske.chess.ui; package dev.kske.chess.ui;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import javax.swing.JPanel; import javax.swing.JPanel;
@ -30,7 +29,7 @@ public class LogPanel extends JPanel implements Subscribable {
private static final long serialVersionUID = 1932671698254197119L; private static final long serialVersionUID = 1932671698254197119L;
private JTable mtable; private JTable mtable;
private Log log; private Log log;
@ -53,18 +52,17 @@ public class LogPanel extends JPanel implements Subscribable {
return new HashSet<>(Arrays.asList(MoveEvent.class)); return new HashSet<>(Arrays.asList(MoveEvent.class));
} }
// TODO: Implement support for variation selection
@Override @Override
public void handle(Event<?> event) { public void handle(Event<?> event) {
if (log == null) return; if (log == null || log.isEmpty()) return;
final DefaultTableModel model = new DefaultTableModel(new String[] { "White", "Black" }, 0);
// TODO: Display log with variations for (Iterator<MoveNode> iter = log.iterator(); iter.hasNext();) {
final List<MoveNode> moves = /* log.getLoggedMoves() */ new ArrayList<>(); String[] row = new String[] { iter.next().move.toSAN(), "" };
String[][] data = new String[moves.size() / 2 + moves.size() % 2][2]; if (iter.hasNext()) row[1] = iter.next().move.toSAN();
for (int i = 0; i < data.length; i++) { model.addRow(row);
data[i][0] = moves.get(i * 2).move.toSAN();
if (i * 2 + 1 < moves.size()) data[i][1] = moves.get(i * 2 + 1).move.toSAN();
} }
mtable.setModel(new DefaultTableModel(data, new String[] { "White", "Black" })); mtable.setModel(model);
} }
public Log getLog() { return log; } public Log getLog() { return log; }