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:
parent
b32a4f2414
commit
f4768b7ac3
@ -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
|
||||||
*
|
*
|
||||||
|
@ -43,6 +43,10 @@ public class Move {
|
|||||||
board.set(pos, board.get(dest));
|
board.set(pos, board.get(dest));
|
||||||
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));
|
||||||
|
@ -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;
|
||||||
|
@ -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");
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user