Added undoMove feature and fixed replay issue

GitBranch^2
Justin 2025-06-24 00:50:32 +02:00
parent aaa4317c9c
commit ae07b4d719
3 changed files with 80 additions and 3 deletions

View File

@ -125,7 +125,7 @@ public class GameController {
// --- AUFGEBEN-BUTTON ---
gui.getResignButton().addActionListener(e -> {
if (gameOver) return; // Nichts tun wenn Spiel vorbei
if (gameOver) return;
int answer = javax.swing.JOptionPane.showConfirmDialog(
null,
@ -162,13 +162,49 @@ public class GameController {
}
});
gui.getUndoButton().addActionListener(e -> {
// Wer ist am Zug? (Das ist der, der gefragt wird)
String currentPlayer = engine.getCurrentPlayer(); // "WHITE" oder "BLACK"
// Wer möchte zurücknehmen? (Das ist der, der NICHT am Zug ist)
String currentName = currentPlayer.equals("WHITE") ? "Weiß" : "Schwarz";
String previousName = currentPlayer.equals("WHITE") ? "Schwarz" : "Weiß";
int answer = javax.swing.JOptionPane.showConfirmDialog(
null,
currentName + " ist am Zug. " +
previousName + " möchte seinen letzten Zug zurücknehmen.\n" +
currentName + ", erlaubst du das?",
"Zug zurücknehmen?",
javax.swing.JOptionPane.YES_NO_OPTION
);
if (answer == javax.swing.JOptionPane.YES_OPTION) {
engine.undoLastMove();
updateGuiBoard();
gui.updateMoveList(engine.getMoveListStringsGrouped());
gui.setOpeningLabel(engine.getOpeningName());
gui.displayMessage("Der letzte Zug wurde zurückgenommen.");
} else if (answer == javax.swing.JOptionPane.NO_OPTION) {
gui.displayMessage("Das Zurücknehmen wurde abgelehnt.");
}
});
}
private boolean isAtLatestMove() {
return engine.getCurrentMoveIndex() == engine.getMoveListSize();
}
private void handleClick(int guiRow, int guiCol) {
if (gameOver) return;
if (!isAtLatestMove()) {
gui.displayMessage("Du bist im Zug-Archiv und kannst keine Figuren bewegen. Klick auf '>|', um zum letzten Zug zu gehen.");
return;
}
int modelRow = flipRow(guiRow);
int modelCol = flipCol(guiCol);
@ -265,6 +301,7 @@ public class GameController {
public void updateGuiBoard() {
BoardDTO board = engine.getBoardAsDTO();
gui.updateBoard(board);
gui.setOpeningLabel(engine.getOpeningName());
}
private void switchTimers() {

View File

@ -31,6 +31,8 @@ public class ChessEngine {
private Timer whiteTimer;
private Timer blackTimer;
private Opening detectedOpening = null;
public ChessEngine() {
logging();
board = new Board();
@ -53,7 +55,7 @@ public class ChessEngine {
// Opening-Erkennung nach jedem erfolgreichen Zug
String playedMovesUci = movesToUciString(moves);
Opening detectedOpening = Opening.detect(playedMovesUci);
detectedOpening = Opening.detect(playedMovesUci);
if (detectedOpening != null) {
logger.info("Aktuelles Opening erkannt: " + detectedOpening.getEco() + " - " + detectedOpening.getName());
@ -65,6 +67,13 @@ public class ChessEngine {
return false;
}
public String getOpeningName() {
if (detectedOpening != null) {
return detectedOpening.getEco() + " - " + detectedOpening.getName();
} else {
return "unbekannt";
}
}
private String movesToUciString(List<Move> moves) {
StringBuilder sb = new StringBuilder();
@ -186,6 +195,9 @@ public class ChessEngine {
board.doMove(moves.get(i));
}
currentMoveIndex = idx;
String playedMovesUci = movesToUciString(moves.subList(0, idx));
detectedOpening = Opening.detect(playedMovesUci);
}
public int getCurrentMoveIndex() {
@ -372,6 +384,18 @@ public class ChessEngine {
}
public void undoLastMove() {
if (currentMoveIndex > 0 && moves.size() > 0) {
board.undoMove(); // 1. Brett zurücksetzen
moves.remove(currentMoveIndex - 1); // 2. Zug aus Move-Liste löschen
currentMoveIndex--; // 3. Index anpassen
// 4. Erkennung Opening neu machen!
String playedMovesUci = movesToUciString(moves.subList(0, currentMoveIndex));
detectedOpening = Opening.detect(playedMovesUci);
}
}
public void loadMoves(List<Move> moveList) {
board = new Board(); // Neues leeres Brett

View File

@ -44,6 +44,7 @@ public class GameGui {
private JButton resignButton;
private JButton drawButton;
private JButton quickSaveButton;
private JButton undoButton;
Color LIGHT = new Color(0xe0e1dd);
Color DARK = new Color(0x778da9);
@ -195,6 +196,14 @@ public class GameGui {
flipBoardButton.setForeground(Color.WHITE);
flipBoardButton.setFocusPainted(false);
undoButton = new JButton("↧");
undoButton.setPreferredSize(new Dimension(70, 70));
undoButton.setFont(new Font("SansSerif", Font.BOLD, 40));
undoButton.setBackground(new Color(0xffa500)); // Orange
undoButton.setForeground(Color.WHITE);
undoButton.setFocusPainted(false);
buttonRow.add(undoButton);
buttonRow.add(resignButton);
buttonRow.add(drawButton);
buttonRow.add(flipBoardButton);
@ -356,6 +365,13 @@ public class GameGui {
public JLabel getWhiteTimerLabel() { return whiteTimerLabel; }
public JLabel getBlackTimerLabel() { return blackTimerLabel; }
public void setOpeningLabel(String text) {
openingLabel.setText("Eröffnung: " + text);
}
public JButton getUndoButton() {
return undoButton;
}
public void displayMessage(String msg) {
JOptionPane.showMessageDialog(null, msg);