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 cb4f44539a
commit 0968fddce0
5 changed files with 58 additions and 4 deletions

View File

@ -8,6 +8,8 @@ import java.util.Map;
import java.util.Objects;
import dev.kske.chess.board.Piece.Color;
import dev.kske.chess.event.EventBus;
import dev.kske.chess.event.MoveEvent;
/**
* Project: <strong>Chess</strong><br>
@ -120,6 +122,32 @@ public class Board {
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
*

View File

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

View File

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

View File

@ -12,6 +12,7 @@ import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
@ -95,11 +96,29 @@ public class GamePane extends JComponent {
moveSelectionPanel.add(btnFirst);
btnPrevious = new JButton("Previous");
btnPrevious.setEnabled(false);
btnPrevious.addActionListener((evt) -> {
if (game != null) {
game.getBoard().selectPreviousNode();
getBoardPane().getOverlayComponent().clearArrow();
repaint();
}
});
moveSelectionPanel.add(btnPrevious);
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);
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,
boolean isSelected, boolean cellHasFocus) {
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);
setOpaque(true);
return this;