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 --- // --- AUFGEBEN-BUTTON ---
gui.getResignButton().addActionListener(e -> { gui.getResignButton().addActionListener(e -> {
if (gameOver) return; // Nichts tun wenn Spiel vorbei if (gameOver) return;
int answer = javax.swing.JOptionPane.showConfirmDialog( int answer = javax.swing.JOptionPane.showConfirmDialog(
null, null,
@ -161,14 +161,50 @@ public class GameController {
askForRestart(); askForRestart();
} }
}); });
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) { private void handleClick(int guiRow, int guiCol) {
if (gameOver) return; 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 modelRow = flipRow(guiRow);
int modelCol = flipCol(guiCol); int modelCol = flipCol(guiCol);
@ -265,6 +301,7 @@ public class GameController {
public void updateGuiBoard() { public void updateGuiBoard() {
BoardDTO board = engine.getBoardAsDTO(); BoardDTO board = engine.getBoardAsDTO();
gui.updateBoard(board); gui.updateBoard(board);
gui.setOpeningLabel(engine.getOpeningName());
} }
private void switchTimers() { private void switchTimers() {

View File

@ -31,6 +31,8 @@ public class ChessEngine {
private Timer whiteTimer; private Timer whiteTimer;
private Timer blackTimer; private Timer blackTimer;
private Opening detectedOpening = null;
public ChessEngine() { public ChessEngine() {
logging(); logging();
board = new Board(); board = new Board();
@ -53,7 +55,7 @@ public class ChessEngine {
// Opening-Erkennung nach jedem erfolgreichen Zug // Opening-Erkennung nach jedem erfolgreichen Zug
String playedMovesUci = movesToUciString(moves); String playedMovesUci = movesToUciString(moves);
Opening detectedOpening = Opening.detect(playedMovesUci); detectedOpening = Opening.detect(playedMovesUci);
if (detectedOpening != null) { if (detectedOpening != null) {
logger.info("Aktuelles Opening erkannt: " + detectedOpening.getEco() + " - " + detectedOpening.getName()); logger.info("Aktuelles Opening erkannt: " + detectedOpening.getEco() + " - " + detectedOpening.getName());
@ -65,6 +67,13 @@ public class ChessEngine {
return false; return false;
} }
public String getOpeningName() {
if (detectedOpening != null) {
return detectedOpening.getEco() + " - " + detectedOpening.getName();
} else {
return "unbekannt";
}
}
private String movesToUciString(List<Move> moves) { private String movesToUciString(List<Move> moves) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
@ -186,6 +195,9 @@ public class ChessEngine {
board.doMove(moves.get(i)); board.doMove(moves.get(i));
} }
currentMoveIndex = idx; currentMoveIndex = idx;
String playedMovesUci = movesToUciString(moves.subList(0, idx));
detectedOpening = Opening.detect(playedMovesUci);
} }
public int getCurrentMoveIndex() { 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) { public void loadMoves(List<Move> moveList) {
board = new Board(); // Neues leeres Brett board = new Board(); // Neues leeres Brett

View File

@ -44,6 +44,7 @@ public class GameGui {
private JButton resignButton; private JButton resignButton;
private JButton drawButton; private JButton drawButton;
private JButton quickSaveButton; private JButton quickSaveButton;
private JButton undoButton;
Color LIGHT = new Color(0xe0e1dd); Color LIGHT = new Color(0xe0e1dd);
Color DARK = new Color(0x778da9); Color DARK = new Color(0x778da9);
@ -194,7 +195,15 @@ public class GameGui {
flipBoardButton.setBackground(new Color(0x5500ff)); flipBoardButton.setBackground(new Color(0x5500ff));
flipBoardButton.setForeground(Color.WHITE); flipBoardButton.setForeground(Color.WHITE);
flipBoardButton.setFocusPainted(false); 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(resignButton);
buttonRow.add(drawButton); buttonRow.add(drawButton);
buttonRow.add(flipBoardButton); buttonRow.add(flipBoardButton);
@ -356,6 +365,13 @@ public class GameGui {
public JLabel getWhiteTimerLabel() { return whiteTimerLabel; } public JLabel getWhiteTimerLabel() { return whiteTimerLabel; }
public JLabel getBlackTimerLabel() { return blackTimerLabel; } 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) { public void displayMessage(String msg) {
JOptionPane.showMessageDialog(null, msg); JOptionPane.showMessageDialog(null, msg);