diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/GameBoard.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/GameBoard.java index 83875ec..7d845d6 100644 --- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/GameBoard.java +++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/GameBoard.java @@ -1,38 +1,170 @@ package PR2.HitoriSpiel.GUI; +import PR2.HitoriSpiel.Domain.StateManager; import PR2.HitoriSpiel.Domain.HitoriBoard; import PR2.HitoriSpiel.Domain.HitoriCell; import PR2.HitoriSpiel.Domain.HitoriValidator; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; +import java.io.FileWriter; +import java.io.IOException; +public class GameBoard extends JPanel { + private final HitoriBoard board; + private Timer timer; + private long startTime; + private JLabel timerLabel; + private final StateManager stateManager = new StateManager(); -public class GameBoard extends JPanel { - - private final HitoriBoard board; // Verbindung zur Logik public GameBoard(HitoriBoard board) { this.board = board; - setLayout(new GridLayout(board.getSize(), board.getSize())); + setLayout(new BorderLayout()); - // Buttons für jede Zelle erstellen + // Timer-Label oben hinzufügen + timerLabel = new JLabel("Zeit: 0 Sekunden"); + timerLabel.setHorizontalAlignment(SwingConstants.CENTER); + add(timerLabel, BorderLayout.NORTH); + + // Timer starten + startTimer(); + + // Spielfeld erstellen + JPanel gamePanel = new JPanel(new GridLayout(board.getSize(), board.getSize())); for (int i = 0; i < board.getSize(); i++) { for (int j = 0; j < board.getSize(); j++) { HitoriCell cell = board.getCell(i, j); JButton button = createCellButton(cell, i, j); - add(button); + gamePanel.add(button); } } + add(gamePanel, BorderLayout.CENTER); + + // Kontroll-Buttons unten hinzufügen + JPanel controlPanel = createControlPanel(); + add(controlPanel, BorderLayout.SOUTH); + } + + private void startTimer() { + startTime = System.currentTimeMillis(); + timer = new Timer(1000, e -> { + long elapsedTime = (System.currentTimeMillis() - startTime) / 1000; + timerLabel.setText("Zeit: " + elapsedTime + " Sekunden"); + }); + timer.start(); + } + + private void stopTimer() { + if (timer != null) { + timer.stop(); + } + } + + private JPanel createControlPanel() { + JPanel controlPanel = new JPanel(); + + JButton resetButton = createButton("Zurücksetzen", 200, 30); + resetButton.addActionListener(e -> { + saveStateForUndo(); + resetBoard(); + refreshBoard(); + }); + + JButton undoButton = createButton("Undo", 200, 30); + undoButton.addActionListener(e -> { + int[][] previousState = stateManager.undo(board.getNumbers()); + if (previousState != null) { + board.setNumbers(previousState); + refreshBoard(); + } else { + JOptionPane.showMessageDialog(this, "Kein Zustand zum Zurücksetzen vorhanden.", "Undo", JOptionPane.INFORMATION_MESSAGE); + } + }); + + JButton redoButton = createButton("Redo", 200, 30); + redoButton.addActionListener(e -> { + int[][] nextState = stateManager.redo(board.getNumbers()); + if (nextState != null) { + board.setNumbers(nextState); + refreshBoard(); + } else { + JOptionPane.showMessageDialog(this, "Kein Zustand zum Wiederholen vorhanden.", "Redo", JOptionPane.INFORMATION_MESSAGE); + } + }); + + JButton validateButton = createButton("Validieren", 200, 30); + validateButton.addActionListener(e -> { + if (validateCurrentBoard()) { + stopTimer(); + JOptionPane.showMessageDialog(this, "Das Spielfeld ist korrekt gelöst!", "Erfolg", JOptionPane.INFORMATION_MESSAGE); + } else { + JOptionPane.showMessageDialog(this, "Das Spielfeld enthält Fehler!", "Fehler", JOptionPane.ERROR_MESSAGE); + } + }); + + JButton pauseButton = createButton("Pause", 200, 30); + pauseButton.addActionListener(e -> { + stopTimer(); + showPauseMenu(); + }); + + + controlPanel.add(resetButton); + controlPanel.add(undoButton); + controlPanel.add(redoButton); + controlPanel.add(validateButton); + controlPanel.add(pauseButton); + + return controlPanel; + } + + public void resetBoard() { + // Spielfeldlogik zurücksetzen + //stopTimer(); + //startTimer(); // Timer neu starten + board.resetBoard(); + removeAll(); + add(timerLabel, BorderLayout.NORTH); + + JPanel gamePanel = new JPanel(new GridLayout(board.getSize(), board.getSize())); + for (int i = 0; i < board.getSize(); i++) { + for (int j = 0; j < board.getSize(); j++) { + HitoriCell cell = board.getCell(i, j); + JButton button = createCellButton(cell, i, j); + gamePanel.add(button); + } + } + add(gamePanel, BorderLayout.CENTER); + + // Kontroll-Buttons unten behalten + JPanel controlPanel = createControlPanel(); + add(controlPanel, BorderLayout.SOUTH); + + // Oberfläche neu laden + revalidate(); + repaint(); + } + + // TODO: Spiel validieren + public boolean validateCurrentBoard() { + return true; + } + + private void showPauseMenu() { + PauseMenu pauseMenu = new PauseMenu( + (JFrame) SwingUtilities.getWindowAncestor(this), + e -> startTimer(), // Spiel fortsetzen + e -> returnToMainMenu(), // Zum Hauptmenü + e -> System.exit(0) // Spiel beenden + ); + pauseMenu.setVisible(true); } private JButton createCellButton(HitoriCell cell, int row, int col) { JButton button = new JButton(String.valueOf(cell.getNumber())); - updateButtonState(button, cell); - - // ActionListener für Benutzereinganen - button.addActionListener((ActionEvent e) -> { + button.setBackground(Color.LIGHT_GRAY); + button.addActionListener(e -> { toggleCellState(cell); updateButtonState(button, cell); }); @@ -59,6 +191,7 @@ public class GameBoard extends JPanel { switch (cell.getState()) { case GRAY: button.setBackground(Color.LIGHT_GRAY); + button.setText(String.valueOf(cell.getNumber())); break; case BLACK: button.setBackground(Color.BLACK); @@ -66,33 +199,68 @@ public class GameBoard extends JPanel { break; case WHITE: button.setBackground(Color.WHITE); + button.setText(String.valueOf(cell.getNumber())); button.setForeground(Color.BLACK); break; } } - public void resetBoard() { - board.resetBoard(); // Logik zurücksetzen - removeAll(); // Entferne alle bisherigen Komponenten (Buttons) - setLayout(new GridLayout(board.getSize(), board.getSize())); - - // Neue Buttons erstellen und hinzufügen - for (int i = 0; i < board.getSize(); i++) { - for (int j = 0; j < board.getSize(); j++) { - HitoriCell cell = board.getCell(i, j); - JButton button = createCellButton(cell, i, j); - add(button); - } - } - - revalidate(); // Layout neu laden - repaint(); // Oberfläche neu zeichnen - System.out.println("Spielfeld wurde aktualisiert"); + private void saveGame() { + try { + FileWriter writer = new FileWriter("hitori_savegame.txt"); + writer.write("Spielzeit: " + (System.currentTimeMillis() - startTime) / 1000 + " Sekunden\n"); + writer.write("Spielfeldzustand:\n"); + for (int i = 0; i < board.getSize(); i++) { + for (int j = 0; j < board.getSize(); j++) { + writer.write(board.getCell(i, j).getState().name() + " "); + } + writer.write("\n"); + } + writer.close(); + JOptionPane.showMessageDialog(this, "Spiel erfolgreich gespeichert."); + } catch (IOException ex) { + JOptionPane.showMessageDialog(this, "Fehler beim Speichern des Spiels: " + ex.getMessage(), "Fehler", JOptionPane.ERROR_MESSAGE); + } } - public boolean validateCurrentBoard() { - HitoriValidator validator = new HitoriValidator(board); - return validator.validateBoard(board.getSolutionCoordinates()); + private void returnToMainMenu() { + // Eltern-Frame abrufen + JFrame parentFrame = (JFrame) SwingUtilities.getWindowAncestor(this); + + // Inhalt des Frames auf das Hauptmenü setzen + parentFrame.getContentPane().removeAll(); + parentFrame.add(new StartMenu()); + parentFrame.revalidate(); + parentFrame.repaint(); } -} \ No newline at end of file + private JButton createButton(String text, int width, int height) { + JButton button = new JButton(text); + button.setPreferredSize(new Dimension(width, height)); + return button; + } + + private void refreshBoard() { + removeAll(); + JPanel gamePanel = new JPanel(new GridLayout(board.getSize(), board.getSize())); + for (int i = 0; i < board.getSize(); i++) { + for (int j = 0; j < board.getSize(); j++) { + HitoriCell cell = board.getCell(i, j); + JButton button = createCellButton(cell, i, j); + gamePanel.add(button); + } + } + add(gamePanel, BorderLayout.CENTER); + + JPanel controlPanel = createControlPanel(); + add(controlPanel, BorderLayout.SOUTH); + + revalidate(); + repaint(); + } + + private void saveStateForUndo() { + stateManager.saveState(board.getNumbers()); + } + +}