Working on move history navigation

* Enabled "next" and "previous" buttons
* Added corresponding methods to Board
* Added Move#invert()
* Rendering variation count in MoveNodeRenderer

The added functionality does not work correctly at the moment. This is
probably caused due to missing synchronization between the state of the
board, the game and the user interface.
This commit is contained in:
Kai S. K. Engelbart 2020-01-06 15:03:20 +02:00
parent b32a4f2414
commit f4768b7ac3
Signed by: kske
GPG Key ID: 8BEB13EC5DF7EF13
5 changed files with 58 additions and 4 deletions

View File

@ -8,6 +8,8 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import dev.kske.chess.board.Piece.Color; import dev.kske.chess.board.Piece.Color;
import dev.kske.chess.event.EventBus;
import dev.kske.chess.event.MoveEvent;
/** /**
* Project: <strong>Chess</strong><br> * Project: <strong>Chess</strong><br>
@ -120,6 +122,32 @@ public class Board {
log.removeLast(); log.removeLast();
} }
public void selectPreviousNode() {
MoveNode moveNode = log.getLast();
Move move = moveNode.move;
// Revert the move
move.revert(this, moveNode.capturedPiece);
// Select previous move node
log.selectPreviousNode();
// Dispatch move event
EventBus.getInstance().dispatch(new MoveEvent(move.invert(), getGameEventType(log.getActiveColor().opposite())));
}
public void selectNextNode(int index) {
log.selectNextNode(index);
MoveNode moveNode = log.getLast();
Move move = moveNode.move;
// Execute the next move
move.execute(this);
// Dispatch move event
EventBus.getInstance().dispatch(new MoveEvent(move, getGameEventType(log.getActiveColor().opposite())));
}
/** /**
* Generated every legal move for one color * Generated every legal move for one color
* *

View File

@ -44,6 +44,10 @@ public class Move {
board.set(dest, capturedPiece); board.set(dest, capturedPiece);
} }
public Move invert() {
return new Move(dest, pos);
}
public static Move fromLAN(String move) { public static Move fromLAN(String move) {
Position pos = Position.fromLAN(move.substring(0, 2)); Position pos = Position.fromLAN(move.substring(0, 2));
Position dest = Position.fromLAN(move.substring(2)); Position dest = Position.fromLAN(move.substring(2));

View File

@ -29,7 +29,7 @@ import dev.kske.chess.ui.OverlayComponent;
*/ */
public class Game { public class Game {
private Map<Color, Player> players = new HashMap<>(); private Map<Color, Player> players = new HashMap<>(2);
private Board board; private Board board;
private OverlayComponent overlayComponent; private OverlayComponent overlayComponent;
private BoardComponent boardComponent; private BoardComponent boardComponent;

View File

@ -12,6 +12,7 @@ import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
@ -95,11 +96,29 @@ public class GamePane extends JComponent {
moveSelectionPanel.add(btnFirst); moveSelectionPanel.add(btnFirst);
btnPrevious = new JButton("Previous"); btnPrevious = new JButton("Previous");
btnPrevious.setEnabled(false); btnPrevious.addActionListener((evt) -> {
if (game != null) {
game.getBoard().selectPreviousNode();
getBoardPane().getOverlayComponent().clearArrow();
repaint();
}
});
moveSelectionPanel.add(btnPrevious); moveSelectionPanel.add(btnPrevious);
btnNext = new JButton("Next"); btnNext = new JButton("Next");
btnNext.setEnabled(false); btnNext.addActionListener((evt) -> {
if(game != null) {
int numVariations = game.getBoard().getLog().getLast().getVariations().size();
int index;
if(numVariations == 1)
index = 1;
else
index = Integer.parseInt(JOptionPane.showInputDialog("Enter the variation index."));
game.getBoard().selectNextNode(index);
getBoardPane().getOverlayComponent().clearArrow();
repaint();
}
});
moveSelectionPanel.add(btnNext); moveSelectionPanel.add(btnNext);
btnLast = new JButton("Last"); btnLast = new JButton("Last");

View File

@ -26,7 +26,10 @@ public class MoveNodeRenderer extends JLabel implements ListCellRenderer<MoveNod
public Component getListCellRendererComponent(JList<? extends MoveNode> list, MoveNode node, int index, public Component getListCellRendererComponent(JList<? extends MoveNode> list, MoveNode node, int index,
boolean isSelected, boolean cellHasFocus) { boolean isSelected, boolean cellHasFocus) {
setBorder(new EmptyBorder(5, 5, 5, 5)); setBorder(new EmptyBorder(5, 5, 5, 5));
setText(node.move.toLAN());
int numVariations = node.hasVariations() ? node.getVariations().size() : 0;
setText(String.format("%s (%d)", node.move.toLAN(), numVariations));
setBackground(isSelected ? Color.red : Color.white); setBackground(isSelected ? Color.red : Color.white);
setOpaque(true); setOpaque(true);
return this; return this;