Reworked and fixed issues with savePgn feature
commit
a669a4b2ff
|
@ -15,20 +15,33 @@ import de.hs_mannheim.informatik.chess.model.MoveDTO;
|
|||
import de.hs_mannheim.informatik.chess.model.PieceDTO;
|
||||
import de.hs_mannheim.informatik.chess.model.BoardDTO;
|
||||
import de.hs_mannheim.informatik.chess.view.GameGui;
|
||||
import de.hs_mannheim.informatik.chess.view.MainGui;
|
||||
|
||||
public class GameController {
|
||||
GameGui gui;
|
||||
ChessEngine engine;
|
||||
GameEndCallback callback;
|
||||
|
||||
private boolean gameOver = false;
|
||||
private int selectedRow = -1, selectedCol = -1;
|
||||
private List<int[]> highlightedFields = new ArrayList<>();
|
||||
|
||||
public GameController(GameGui gui, ChessEngine engine) {
|
||||
public GameController(GameGui gui, ChessEngine engine, GameEndCallback callback) {
|
||||
this.gui = gui;
|
||||
this.engine = engine;
|
||||
this.callback = callback;
|
||||
engine.initTimers(3, 0);
|
||||
time();
|
||||
initListeners();
|
||||
updateGuiBoard();
|
||||
}
|
||||
|
||||
private void time() {
|
||||
engine.getWhiteTimer().setOnTick(secs -> gui.updateWhiteTimerLabel(secs));
|
||||
engine.getBlackTimer().setOnTick(secs -> gui.updateBlackTimerLabel(secs));
|
||||
engine.getWhiteTimer().setOnTimeout(() -> onTimeout("WHITE"));
|
||||
engine.getBlackTimer().setOnTimeout(() -> onTimeout("BLACK"));
|
||||
engine.getWhiteTimer().start();
|
||||
}
|
||||
private int flipRow(int row) {
|
||||
return gui.isFlipped() ? 7 - row : row;
|
||||
}
|
||||
|
@ -114,6 +127,9 @@ public class GameController {
|
|||
}
|
||||
|
||||
private void handleClick(int guiRow, int guiCol) {
|
||||
|
||||
if (gameOver) return;
|
||||
|
||||
int modelRow = flipRow(guiRow);
|
||||
int modelCol = flipCol(guiCol);
|
||||
|
||||
|
@ -159,6 +175,9 @@ public class GameController {
|
|||
}
|
||||
|
||||
private void handleMove(MoveDTO move) {
|
||||
|
||||
if (gameOver) return;
|
||||
|
||||
BoardDTO boardDTO = engine.getBoardAsDTO();
|
||||
PieceDTO piece = boardDTO.getBoard()[move.getFromRow()][move.getFromCol()];
|
||||
boolean isPawn = piece != null && piece.getType().equals("PAWN");
|
||||
|
@ -190,8 +209,16 @@ public class GameController {
|
|||
if (engine.isMated()) {
|
||||
String winner = engine.getCurrentPlayer().equals("WHITE") ? "SCHWARZ" : "WEIß";
|
||||
gui.displayMessage(winner + " hat gewonnen (Schachmatt)!");
|
||||
gameOver = true;
|
||||
askForRestart();
|
||||
} else if (engine.isStalemate() || engine.isDraw()) {
|
||||
gui.displayMessage("Remis! (Stalemate oder andere Regel)");
|
||||
gameOver = true;
|
||||
askForRestart();
|
||||
}
|
||||
|
||||
if (!engine.isMated() && !engine.isStalemate() && !engine.isDraw()) {
|
||||
switchTimers();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,6 +228,17 @@ public class GameController {
|
|||
gui.updateBoard(board);
|
||||
}
|
||||
|
||||
private void switchTimers() {
|
||||
if (engine.getCurrentPlayer().equals("WHITE")) {
|
||||
engine.getBlackTimer().stop();
|
||||
engine.getWhiteTimer().start();
|
||||
} else {
|
||||
engine.getWhiteTimer().stop();
|
||||
engine.getBlackTimer().start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Hilfsmethode, um von Koordinaten (row/col) auf z.B. "E2" zu kommen
|
||||
private String coordToChessNotation(int modelRow, int modelCol) {
|
||||
char file = (char)('A' + modelCol);
|
||||
|
@ -209,6 +247,32 @@ public class GameController {
|
|||
}
|
||||
|
||||
|
||||
// Timeout-Methode
|
||||
private void onTimeout(String color) {
|
||||
if (gameOver) return; // Doppelt hält besser
|
||||
gameOver = true;
|
||||
String winner = color.equals("WHITE") ? "SCHWARZ" : "WEIß";
|
||||
gui.displayMessage(winner + " hat durch Zeit gewonnen!");
|
||||
engine.getWhiteTimer().stop();
|
||||
engine.getBlackTimer().stop();
|
||||
askForRestart();
|
||||
}
|
||||
|
||||
private void askForRestart() {
|
||||
int answer = javax.swing.JOptionPane.showConfirmDialog(
|
||||
null,
|
||||
"Neue Partie starten?",
|
||||
"Spiel beendet",
|
||||
javax.swing.JOptionPane.YES_NO_OPTION
|
||||
);
|
||||
javax.swing.SwingUtilities.getWindowAncestor(gui.getField(0, 0)).dispose();
|
||||
if (answer == javax.swing.JOptionPane.YES_OPTION) {
|
||||
callback.onNewGameRequested();
|
||||
} else {
|
||||
callback.onReturnToMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private void resetFieldBackground(int row, int col) {
|
||||
Color LIGHT = new Color(0xe0e1dd);
|
||||
Color DARK = new Color(0x778da9);
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package de.hs_mannheim.informatik.chess.controller;
|
||||
|
||||
public interface GameEndCallback {
|
||||
void onNewGameRequested();
|
||||
void onReturnToMenu();
|
||||
}
|
|
@ -31,7 +31,15 @@ public class MainController {
|
|||
mainGui.close();
|
||||
GameGui gameGui = new GameGui();
|
||||
ChessEngine engine = new ChessEngine();
|
||||
new GameController(gameGui, engine);
|
||||
GameEndCallback callback = new GameEndCallback() {
|
||||
public void onNewGameRequested() {
|
||||
startNormalMode();
|
||||
}
|
||||
public void onReturnToMenu() {
|
||||
new MainController();
|
||||
}
|
||||
};
|
||||
new GameController(gameGui, engine, callback);
|
||||
}
|
||||
|
||||
private void startCreativeMode() {
|
||||
|
|
|
@ -28,6 +28,8 @@ public class ChessEngine {
|
|||
private static final Logger logger = Logger.getLogger(ChessEngine.class.getName());
|
||||
|
||||
private int currentMoveIndex = 0;
|
||||
private Timer whiteTimer;
|
||||
private Timer blackTimer;
|
||||
|
||||
public ChessEngine() {
|
||||
logging();
|
||||
|
@ -245,6 +247,11 @@ public class ChessEngine {
|
|||
return games;
|
||||
}
|
||||
|
||||
public void initTimers(int min, int sec) {
|
||||
whiteTimer = new Timer(min, sec);
|
||||
blackTimer = new Timer(min, sec);
|
||||
}
|
||||
|
||||
public void saveAsPgn(Game game, String path, String dateiname) {
|
||||
// Sicher alle Strings holen (nie null)
|
||||
String event = safe(game.getRound().getEvent().getName());
|
||||
|
@ -362,4 +369,7 @@ public class ChessEngine {
|
|||
|
||||
}
|
||||
|
||||
public Timer getWhiteTimer() { return whiteTimer; }
|
||||
public Timer getBlackTimer() { return blackTimer; }
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package de.hs_mannheim.informatik.chess.model;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Timer {
|
||||
private int secondsLeft;
|
||||
private javax.swing.Timer swingTimer;
|
||||
private Runnable onTimeout;
|
||||
private Consumer<Integer> onTick;
|
||||
|
||||
|
||||
public Timer(int minutes, int seconds) {
|
||||
this.secondsLeft = minutes * 60 + seconds;
|
||||
}
|
||||
|
||||
public void setOnTimeout(Runnable onTimeout) {
|
||||
this.onTimeout = onTimeout;
|
||||
}
|
||||
|
||||
public void setOnTick(Consumer<Integer> onTick) {
|
||||
this.onTick = onTick;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (swingTimer != null && swingTimer.isRunning()) {
|
||||
swingTimer.stop();
|
||||
}
|
||||
swingTimer = new javax.swing.Timer(1000, e -> {
|
||||
secondsLeft--;
|
||||
if (onTick != null) {
|
||||
onTick.accept(secondsLeft);
|
||||
}
|
||||
if (secondsLeft <= 0) {
|
||||
stop();
|
||||
if (onTimeout != null) {
|
||||
onTimeout.run();
|
||||
}
|
||||
}
|
||||
});
|
||||
swingTimer.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (swingTimer != null) {
|
||||
swingTimer.stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(int minutes, int seconds) {
|
||||
stop();
|
||||
this.secondsLeft = minutes * 60 + seconds;
|
||||
if (onTick != null) {
|
||||
onTick.accept(secondsLeft);
|
||||
}
|
||||
}
|
||||
|
||||
public int getSecondsLeft() {
|
||||
return secondsLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,12 +27,15 @@ public class GameGui {
|
|||
private JLabel[][] fields = new JLabel[8][8];
|
||||
private JButton flipBoardButton;
|
||||
private boolean isFlipped = false;
|
||||
JButton btnSave = new JButton("💾");
|
||||
|
||||
private JLabel whiteTimerLabel;
|
||||
private JLabel blackTimerLabel;
|
||||
|
||||
JButton btnFirst = new JButton("|<");
|
||||
JButton btnPrev = new JButton("<");
|
||||
JButton btnNext = new JButton(">");
|
||||
JButton btnLast = new JButton(">|");
|
||||
JButton btnSave = new JButton("SavePgn");
|
||||
|
||||
Color LIGHT = new Color(0xe0e1dd);
|
||||
Color DARK = new Color(0x778da9);
|
||||
|
@ -161,6 +164,9 @@ public class GameGui {
|
|||
JPanel statsPanel = new JPanel(new BorderLayout());
|
||||
statsPanel.setBackground(new Color(0x0d1b2a));
|
||||
|
||||
// Panel für die Timer (NORD)
|
||||
statsPanel.add(timerPanel(), BorderLayout.NORTH);
|
||||
|
||||
// Move-Liste
|
||||
moveListPanel = new JPanel();
|
||||
moveListPanel.setLayout(new BoxLayout(moveListPanel, BoxLayout.Y_AXIS));
|
||||
|
@ -169,32 +175,49 @@ public class GameGui {
|
|||
moveListScroll.setPreferredSize(new Dimension(250, 800));
|
||||
statsPanel.add(moveListScroll, BorderLayout.CENTER);
|
||||
|
||||
// Button-Leiste
|
||||
// Button-Leiste (SÜD)
|
||||
JPanel buttonPanel = new JPanel();
|
||||
buttonPanel.setBackground(new Color(0x0d1b2a));
|
||||
// Grid oder Flow
|
||||
buttonPanel.setLayout(new GridLayout(1, 4, 10, 0));
|
||||
|
||||
// Style (optional)
|
||||
buttonPanel.setLayout(new GridLayout(1, 5, 10, 0)); // Jetzt 5 statt 4 Spalten!
|
||||
btnFirst.setBackground(new Color(0x212529)); btnFirst.setForeground(Color.WHITE);
|
||||
btnPrev.setBackground(new Color(0x212529)); btnPrev.setForeground(Color.WHITE);
|
||||
btnNext.setBackground(new Color(0x212529)); btnNext.setForeground(Color.WHITE);
|
||||
btnLast.setBackground(new Color(0x212529)); btnLast.setForeground(Color.WHITE);
|
||||
btnLast.setBackground(new Color(0x212529)); btnSave.setForeground(Color.WHITE);
|
||||
|
||||
// Hinzufügen
|
||||
btnSave.setBackground(new Color(0x218838)); btnSave.setForeground(Color.WHITE);
|
||||
buttonPanel.add(btnFirst);
|
||||
buttonPanel.add(btnPrev);
|
||||
buttonPanel.add(btnNext);
|
||||
buttonPanel.add(btnLast);
|
||||
buttonPanel.add(btnSave);
|
||||
|
||||
// Unten ins BorderLayout
|
||||
statsPanel.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
return statsPanel;
|
||||
}
|
||||
|
||||
|
||||
private JPanel timerPanel() {
|
||||
JPanel panel = new JPanel(new GridLayout(2, 1));
|
||||
panel.setBackground(new Color(0x0d1b2a));
|
||||
|
||||
whiteTimerLabel = new JLabel("Weiß: 03:00", SwingConstants.CENTER);
|
||||
blackTimerLabel = new JLabel("Schwarz: 03:00", SwingConstants.CENTER);
|
||||
|
||||
whiteTimerLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
||||
whiteTimerLabel.setForeground(Color.WHITE);
|
||||
whiteTimerLabel.setBackground(new Color(0x1b263b));
|
||||
whiteTimerLabel.setOpaque(true);
|
||||
|
||||
blackTimerLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
|
||||
blackTimerLabel.setForeground(Color.WHITE);
|
||||
blackTimerLabel.setBackground(new Color(0x1b263b));
|
||||
blackTimerLabel.setOpaque(true);
|
||||
|
||||
panel.add(whiteTimerLabel);
|
||||
panel.add(blackTimerLabel);
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
public String showPromotionDialog(String color) {
|
||||
String[] choices = {"Dame", "Turm", "Springer", "Läufer"};
|
||||
String choice = (String) JOptionPane.showInputDialog(
|
||||
|
@ -268,6 +291,24 @@ public class GameGui {
|
|||
}
|
||||
}
|
||||
|
||||
public void updateWhiteTimerLabel(int secondsLeft) {
|
||||
whiteTimerLabel.setText("Weiß: " + formatTime(secondsLeft));
|
||||
}
|
||||
|
||||
public void updateBlackTimerLabel(int secondsLeft) {
|
||||
blackTimerLabel.setText("Schwarz: " + formatTime(secondsLeft));
|
||||
}
|
||||
|
||||
private String formatTime(int seconds) {
|
||||
int min = seconds / 60;
|
||||
int sec = seconds % 60;
|
||||
return String.format("%02d:%02d", min, sec);
|
||||
}
|
||||
|
||||
// Optional: Getter, falls du direkt ran willst (braucht man aber fast nie)
|
||||
public JLabel getWhiteTimerLabel() { return whiteTimerLabel; }
|
||||
public JLabel getBlackTimerLabel() { return blackTimerLabel; }
|
||||
|
||||
|
||||
public void displayMessage(String msg) {
|
||||
JOptionPane.showMessageDialog(null, msg);
|
||||
|
|
Loading…
Reference in New Issue