From 5544ea5e65111220ce32551a52f969bed40e3e0c Mon Sep 17 00:00:00 2001
From: "Ioana P." <3015825@stud.hs-mannheim.de>
Date: Mon, 13 Jan 2025 23:38:13 +0100
Subject: [PATCH] Javadocs, bessere Trennung von GUI, Fassade und Domain,
andere Files angepasst
---
Hitori/pom.xml | 191 +++++++++-----
Hitori/src/main/highscores/highscores.txt | 3 +-
.../java/PR2/HitoriSpiel/Domain/Action.java | 32 +++
.../PR2/HitoriSpiel/Domain/HitoriBoard.java | 38 +--
.../PR2/HitoriSpiel/Domain/HitoriCell.java | 13 +-
.../HitoriSpiel/Domain/HitoriValidator.java | 24 +-
.../HitoriSpiel/Domain/StateFileManager.java | 30 ++-
.../PR2/HitoriSpiel/Fassade/BoardManager.java | 24 ++
.../PR2/HitoriSpiel/Fassade/GameBoard.java | 238 ++++++++++++------
.../PR2/HitoriSpiel/Fassade/GameManager.java | 1 +
.../HitoriSpiel/Fassade/HighscoreManager.java | 82 +++++-
.../Fassade/HitoriSolutionLoader.java | 12 +-
.../java/PR2/HitoriSpiel/Fassade/Setup.java | 4 +
.../PR2/HitoriSpiel/Fassade/StateManager.java | 33 +++
.../java/PR2/HitoriSpiel/GUI/BoardLoader.java | 41 +--
.../PR2/HitoriSpiel/GUI/HighscoreDialog.java | 28 ++-
.../java/PR2/HitoriSpiel/GUI/PauseMenu.java | 15 ++
.../java/PR2/HitoriSpiel/GUI/StartMenu.java | 51 +++-
.../main/java/PR2/HitoriSpiel/Main/Main.java | 3 -
.../PR2/HitoriSpiel/project_structure.puml | 6 +-
.../src/test/java/Domain/HitoriBoardTest.java | 8 -
21 files changed, 644 insertions(+), 233 deletions(-)
create mode 100644 Hitori/src/main/java/PR2/HitoriSpiel/Fassade/BoardManager.java
diff --git a/Hitori/pom.xml b/Hitori/pom.xml
index d70a88f..4020365 100644
--- a/Hitori/pom.xml
+++ b/Hitori/pom.xml
@@ -1,71 +1,132 @@
-
+4.0.0
-
org.exampleHitoriTeamProjekt1.0-SNAPSHOT
- jar
+
+ UTF-8
+ 21
+ 21
+
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.8.1
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-engine
+ 5.8.1
+ test
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.24.2
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.13.0
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.6.0
+
+ false
+
+
+
+ package
+
+ shade
+
+
+
+
+ PR2.HitoriSpiel.Main.Main
+
+
+
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ 0.8.12
+
+
+
+ prepare-agent
+
+
+
+ report
+ test
+
+ report
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-pmd-plugin
+ 3.26.0
+
+ false
+ true
+
+
+
+ verify
+
+ check
+
+
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+ 3.3.1
+
+ private
+ true
+
+
-
- 21
- 21
- UTF-8
-
-
-
-
-
- org.assertj
- assertj-swing
- 3.17.1
- test
-
-
- junit
- junit
- 4.13.1
- test
-
-
- org.junit.jupiter
- junit-jupiter
- 5.8.2
- test
-
-
- org.mockito
- mockito-core
- 4.5.1
- test
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
- 3.11.0
-
- 21
- 21
-
-
-
- org.apache.maven.plugins
- maven-jar-plugin
- 3.2.0
-
-
-
- PR2.HitoriSpiel.Main.Main
-
-
-
-
-
-
-
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ 3.1.2
+
+ checkstyle.xml
+ true
+
+
+
+
+
\ No newline at end of file
diff --git a/Hitori/src/main/highscores/highscores.txt b/Hitori/src/main/highscores/highscores.txt
index 167a4d9..3d5c33d 100644
--- a/Hitori/src/main/highscores/highscores.txt
+++ b/Hitori/src/main/highscores/highscores.txt
@@ -5,4 +5,5 @@ Test3,100,Hitori8x8_medium.csv,0
Test4,200,Hitori15x15_medium.csv,10
IOANA VERSUCH 156,105,Hitori5x5_leicht.csv,0
IOANA VERSUCH 439,44,Hitori5x5_leicht.csv,0
-Yovu,46,Hitori4x4_leicht.csv,0
\ No newline at end of file
+Yovu,46,Hitori4x4_leicht.csv,0
+hi,18,Hitori4x4_leicht.csv,0
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/Action.java b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/Action.java
index b15c8eb..9e4488e 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/Action.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/Action.java
@@ -1,11 +1,27 @@
package PR2.HitoriSpiel.Domain;
+/**
+ * Die Klasse Action repräsentiert eine Aktion im Hitori-Spiel, die eine Änderung
+ * an einer bestimmten Zelle des Spielfelds beschreibt, einschließlich der Koordinaten,
+ * des alten Zustands und des neuen Zustands.
+ */
+
public class Action {
private final int row; // Zeile, in der die Änderung erfolgt ist
private final int col; // Spalte, in der die Änderung erfolgt ist
private final String oldState; // Alter Zustand der Zelle
private final String newState; // Neuer Zustand der Zelle
+ /**
+ * Erstellt ein neues Action-Objekt mit den angegebenen Koordinaten,
+ * dem alten Zustand und dem neuen Zustand.
+ *
+ * @param row Die Zeile, in der die Änderung erfolgt ist.
+ * @param col Die Spalte, in der die Änderung erfolgt ist.
+ * @param oldState Der alte Zustand der Zelle.
+ * @param newState Der neue Zustand der Zelle.
+ */
+
public Action(int row, int col, String oldState, String newState) {
this.row = row;
this.col = col;
@@ -13,6 +29,15 @@ public class Action {
this.newState = newState;
}
+ /**
+ * Erstellt ein neues Action-Objekt mit den angegebenen Koordinaten
+ * und dem neuen Zustand; der alte Zustand wird auf "GRAY" gesetzt.
+ *
+ * @param row Die Zeile, in der die Änderung erfolgt ist.
+ * @param col Die Spalte, in der die Änderung erfolgt ist.
+ * @param newState Der neue Zustand der Zelle.
+ */
+
// Alternative Konstruktor für Standardwerte
public Action(int row, int col, String newState) {
this(row, col, "GRAY", newState);
@@ -52,6 +77,13 @@ public class Action {
newState.equals(action.newState);
}
+ /**
+ * Berechnet den Hashcode für das Action-Objekt basierend
+ * auf den Attributen row, col, oldState und newState.
+ *
+ * @return Der berechnete Hashcode.
+ */
+
@Override
public int hashCode() {
int result = row;
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriBoard.java b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriBoard.java
index cf0280d..c4b10f8 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriBoard.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriBoard.java
@@ -3,7 +3,8 @@ package PR2.HitoriSpiel.Domain;
import java.util.List;
/**
- * Represents the Hitori game board.
+ * Die Klasse HitoriBoard repräsentiert das Spielfeld des Hitori-Spiels.
+ * Sie enthält die Zellen des Spielfelds, die Lösungskonfiguration und den Namen des Spielfelds.
*/
public class HitoriBoard {
@@ -12,6 +13,15 @@ public class HitoriBoard {
private final String boardName; // Name des Spielfelds
+ /**
+ * Konstruktor, der das Spielfeld mit den Zahlen, der Lösungskonfiguration
+ * und dem Namen des Spielfelds initialisiert.
+ *
+ * @param numbers 2D-Array mit den Zahlen des Spielfelds.
+ * @param solutionCoordinates Liste der Koordinaten, die zur Lösung gehören.
+ * @param boardName Name des Spielfelds.
+ */
+
public HitoriBoard(int[][] numbers, List solutionCoordinates, String boardName) {
this.board = new HitoriCell[numbers.length][numbers[0].length];
this.solutionCoordinates = solutionCoordinates;
@@ -81,32 +91,6 @@ public class HitoriBoard {
}
}
- /**
- * Gibt das gesamte Spielfeld als 2D-Array zurück.
- *
- * @return 2D-Array mit den Zahlen des Spielfelds.
- */
- public int[][] getNumbers() {
- int[][] numbers = new int[board.length][board[0].length];
- for (int i = 0; i < board.length; i++) {
- for (int j = 0; j < board[i].length; j++) {
- numbers[i][j] = board[i][j].getNumber();
- }
- }
- return numbers;
- }
- /**
- * Setzt die Zahlen des Spielfelds basierend auf einem 2D-Array.
- *
- * @param numbers 2D-Array mit den neuen Zahlen.
- */
- public void setNumbers(int[][] numbers) {
- for (int i = 0; i < board.length; i++) {
- for (int j = 0; j < board[i].length; j++) {
- board[i][j].setNumber(numbers[i][j]);
- }
- }
- }
}
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriCell.java b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriCell.java
index bc085b5..9e425b5 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriCell.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriCell.java
@@ -1,17 +1,28 @@
package PR2.HitoriSpiel.Domain;
/**
- * Represents a single cell on the Hitori board.
+ * Die Klasse HitoriCell repräsentiert eine einzelne Zelle auf dem Hitori-Spielfeld.
+ * Sie speichert die Zahl der Zelle und deren Zustand (GRAY, WHITE, BLACK).
*/
public class HitoriCell {
+ /**
+ * Enum zur Darstellung der möglichen Zustände einer Zelle.
+ */
+
public enum CellState {
GRAY, WHITE, BLACK
}
private int number;
private CellState state;
+ /**
+ * Konstruktor, der eine Zelle mit einer Zahl erstellt und den Zustand auf GRAY setzt.
+ *
+ * @param number Die Zahl der Zelle.
+ */
+
public HitoriCell(int number) {
this.number = number;
this.state = CellState.GRAY;
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriValidator.java b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriValidator.java
index a69c1cf..fc37deb 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriValidator.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/HitoriValidator.java
@@ -3,32 +3,44 @@ package PR2.HitoriSpiel.Domain;
import java.util.List;
/**
- * Validates the Hitori board against the solution.
+ * Die Klasse HitoriValidator überprüft, ob das aktuelle Spielfeld des Hitori-Spiels korrekt gelöst ist,
+ * indem es mit der angegebenen Lösung verglichen wird.
*/
+
public class HitoriValidator {
private final HitoriBoard board;
+ /**
+ * Konstruktor, der den Validator mit einem Hitori-Spielfeld initialisiert.
+ *
+ * @param board Das zu überprüfende Hitori-Spielfeld.
+ */
+
public HitoriValidator(HitoriBoard board) {
this.board = board;
}
/**
- * Validates the current board against the solution.
- * @param solutionCoordinates The coordinates of the correct black cells in "row,column" format.
- * @return true if the current board matches the solution, false otherwise.
+ * Überprüft, ob das aktuelle Spielfeld der Lösung entspricht.
+ *
+ * @param solutionCoordinates Die Koordinaten der korrekten schwarzen Felder im Format "row,column".
+ * @return true, wenn das aktuelle Spielfeld der Lösung entspricht, andernfalls false.
*/
+
public boolean validateBoard(List solutionCoordinates) {
+ // Überprüfe, ob alle Koordinaten der Lösung korrekt schwarz markiert sind
for (String coordinate : solutionCoordinates) {
String[] parts = coordinate.split(",");
int row = Integer.parseInt(parts[0]) - 1;
int col = Integer.parseInt(parts[1]) - 1;
if (board.getCell(row,col).getState() != HitoriCell.CellState.BLACK){
- return false;
+ return false; // Ein Feld, das schwarz sein sollte, ist aber nicht
}
}
+ // Überprüfe alle Zellen des Spielfelds
for (int i = 0; i < board.getSize(); i++) {
for (int j = 0; j < board.getSize(); j++) {
HitoriCell cell = board.getCell(i, j);
@@ -44,7 +56,7 @@ public class HitoriValidator {
}
}
- return true;
+ return true; // Das Spielfeld entspricht der Lösung
}
}
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/StateFileManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/StateFileManager.java
index ca02e0f..809963f 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Domain/StateFileManager.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Domain/StateFileManager.java
@@ -1,17 +1,23 @@
package PR2.HitoriSpiel.Domain;
import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
+import java.nio.file.*;
import java.util.Stack;
+/**
+ * Die Klasse StateFileManager verwaltet das Speichern und Laden der Zustände des Undo- und Redo-Stacks
+ * in eine Datei. Sie stellt sicher, dass der Speicherort existiert und ermöglicht so die Persistenz der Spielzustände.
+ */
+
public class StateFileManager {
// Speicherort für die Undo/Redo-Datei im Benutzerverzeichnis
private static final String BASE_DIR = System.getProperty("user.home") + "/HitoriGame";
private static final String FILE_NAME = BASE_DIR + "/undoRedoLog.txt";
- // Stellt sicher, dass der Ordner und die Datei existieren
+ /**
+ * Stellt sicher, dass der Ordner und die Datei existieren.
+ */
+
private static void ensureFileExists() {
try {
// Erstellt den Ordner, falls er nicht existiert
@@ -32,7 +38,13 @@ public class StateFileManager {
}
}
- // Speichert den Zustand in der Datei
+ /**
+ * Speichert den Zustand der Undo- und Redo-Stacks in der Datei.
+ *
+ * @param undoStack Der aktuelle Undo-Stack.
+ * @param redoStack Der aktuelle Redo-Stack.
+ */
+
public static void saveState(Stack undoStack, Stack redoStack) {
ensureFileExists(); // Stellt sicher, dass die Datei existiert
try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_NAME))) {
@@ -54,7 +66,13 @@ public class StateFileManager {
}
}
- // Lädt den Zustand aus der Datei
+ /**
+ * Lädt den Zustand der Undo- und Redo-Stacks aus der Datei.
+ *
+ * @param undoStack Der Stack, in den die Undo-Zustände geladen werden.
+ * @param redoStack Der Stack, in den die Redo-Zustände geladen werden.
+ */
+
public static void loadState(Stack undoStack, Stack redoStack) {
ensureFileExists(); // Stellt sicher, dass die Datei existiert
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/BoardManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/BoardManager.java
new file mode 100644
index 0000000..a1a4f41
--- /dev/null
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/BoardManager.java
@@ -0,0 +1,24 @@
+package PR2.HitoriSpiel.Fassade;
+
+import PR2.HitoriSpiel.Domain.HitoriBoard;
+
+import java.util.List;
+
+/**
+ * Die Klasse BoardManager dient als Fassade, um ein HitoriBoard-Objekt zu erstellen
+ * und die Spielfeld-Initialisierung zu kapseln.
+ */
+
+public class BoardManager {
+ /**
+ * Erstellt und gibt ein HitoriBoard-Objekt basierend auf den angegebenen Parametern zurück.
+ *
+ * @param boardData Die Daten des Spielfelds.
+ * @param solutionCoordinates Die Koordinaten der Lösung.
+ * @param selectedFile Die ausgewählte Datei mit den Spielfeldinformationen.
+ * @return Das erstellte HitoriBoard-Objekt.
+ */
+ public HitoriBoard createBoard(int[][] boardData, List solutionCoordinates, String selectedFile) {
+ return new HitoriBoard(boardData, solutionCoordinates, selectedFile);
+ }
+}
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameBoard.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameBoard.java
index 4ca781f..e6de42a 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameBoard.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameBoard.java
@@ -10,15 +10,26 @@ import PR2.HitoriSpiel.GUI.StartMenu;
import javax.swing.*;
import java.awt.*;
+/**
+ * Die Klasse GameBoard repräsentiert das Spielfeld des Hitori-Spiels mit zugehörigen Steuerungselementen.
+ * Sie bietet Funktionalitäten wie Timer, Spielfeldvalidierung, Undo/Redo und Highscore-Management.
+ */
+
public class GameBoard extends JPanel {
- private final HitoriBoard board;
- private Timer timer;
- private long startTime;
- private JLabel timerLabel;
+ private final HitoriBoard board; // Das Hitori-Spielfeld-Objekt
+ private Timer timer; // Timer für die Spielzeitmessung
+ private long startTime; // Startzeit des Timers
+ private JLabel timerLabel; // Anzeigeelement für die aktuelle Spielzeit
private long pausedTime = 0; // Zeit, die beim Pausieren bereits abgelaufen ist
private JPanel gamePanel; // Das Spielfeld als JPanel
- private final StateManager stateManager = new StateManager();
+ private final StateManager stateManager = new StateManager(); // Manager für Undo/Redo-Operationen
+ private long elapsedTime = 0;
+ /**
+ * Konstruktor, der das Spielfeld und die Steuerungselemente initialisiert.
+ *
+ * @param board Das Hitori-Spielfeld.
+ */
public GameBoard(HitoriBoard board) {
this.board = board;
@@ -32,13 +43,17 @@ public class GameBoard extends JPanel {
// Spielfeld erstellen
gamePanel = createGamePanel();
- add(gamePanel, BorderLayout.CENTER);
+ add(gamePanel, BorderLayout.CENTER); // Spielfeld im Zentrum hinzufügen
// Kontroll-Buttons unten hinzufügen
JPanel controlPanel = createControlPanel();
- add(controlPanel, BorderLayout.SOUTH);
+ add(controlPanel, BorderLayout.SOUTH); // Buttons am unteren Rand platzieren
}
+ /**
+ * Initialisiert das Timer-Label.
+ */
+
private void initializeTimerLabel() {
timerLabel = new JLabel("Zeit: 0 Sekunden");
timerLabel.setHorizontalAlignment(SwingConstants.CENTER);
@@ -46,42 +61,12 @@ public class GameBoard extends JPanel {
add(timerLabel, BorderLayout.NORTH);
}
- private void startTimer() {
- if (timer == null) { // Timer nur beim ersten Start erstellen
- timer = new Timer(1000, e -> {
- long elapsedTime = (System.currentTimeMillis() - startTime + pausedTime) / 1000; // Zeit berechnen
- timerLabel.setText("Zeit: " + elapsedTime + " Sekunden");
- });
- }
- startTime = System.currentTimeMillis(); // Startzeit setzen, bevor der Timer gestartet wird
- timer.start(); // Timer starten
- System.out.println("Startzeit: " + startTime);
- System.out.println("Pausierte Zeit: " + pausedTime);
- }
-
- private void stopTimer() {
- if (timer != null && timer.isRunning()) {
- timer.stop(); // Timer anhalten
- pausedTime += System.currentTimeMillis() - startTime; // Zeit während der Pause speichern
- System.out.println("Timer gestoppt. Pausierte Zeit: " + pausedTime);
- }
- }
-
- public void resumeTimer() {
- startTime = System.currentTimeMillis(); // Startzeit neu setzen
- startTimer(); // Timer erneut starten
- System.out.println("Timer fortgesetzt. Startzeit: " + startTime + ", Pausierte Zeit: " + pausedTime);
- }
-
- private void resetTimer() {
- if (timer != null) {
- timer.stop();
- }
- startTime = 0;
- pausedTime = 0;
- timerLabel.setText("Zeit: 0 Sekunden");
- }
+ /**
+ * Erstellt das Steuerungspanel mit Kontroll-Buttons.
+ *
+ * @return Das erstellte Panel.
+ */
private JPanel createControlPanel() {
JPanel controlPanel = new JPanel();
@@ -95,24 +80,36 @@ public class GameBoard extends JPanel {
return controlPanel;
}
+ /**
+ * Erstellt den "Zurücksetzen"-Button.
+ *
+ * @return Der Reset-Button.
+ */
+
private JButton createResetButton() {
JButton resetButton = Setup.createGameBoardButton("Zurücksetzen", 150, 30);
resetButton.addActionListener(e -> {
//saveStateForUndo();
- resetBoard();
+ resetBoard(); // Spielfeld zurücksetzen
});
return resetButton;
}
+ /**
+ * Erstellt den "Undo"-Button.
+ *
+ * @return Der Undo-Button.
+ */
+
private JButton createUndoButton() {
JButton undoButton = Setup.createGameBoardButton("Undo", 80, 30);
undoButton.addActionListener(e -> {
- Action action = stateManager.undo();
+ Action action = stateManager.undo(); // Letzte Aktion rückgängig machen
if (action != null) {
- HitoriCell cell = board.getCell(action.getRow(), action.getCol());
- cell.setState(HitoriCell.CellState.valueOf(action.getOldState()));
+ HitoriCell cell = board.getCell(action.getRow(), action.getCol()); // Betroffene Zelle abrufen
+ cell.setState(HitoriCell.CellState.valueOf(action.getOldState())); // Zustand der Zelle zurücksetzen
JButton button = (JButton) gamePanel.getComponent(action.getRow() * board.getSize() + action.getCol());
- updateButtonState(button, cell);
+ updateButtonState(button, cell); // Button-Status aktualisieren
} else {
JOptionPane.showMessageDialog(this, "Kein Zustand zum Zurücksetzen vorhanden.", "Undo", JOptionPane.INFORMATION_MESSAGE);
}
@@ -121,10 +118,16 @@ public class GameBoard extends JPanel {
return undoButton;
}
+ /**
+ * Erstellt den "Redo"-Button.
+ *
+ * @return Der Redo-Button.
+ */
+
private JButton createRedoButton() {
JButton redoButton = Setup.createGameBoardButton("Redo", 80, 30);
redoButton.addActionListener(e -> {
- Action action = stateManager.redo();
+ Action action = stateManager.redo(); // Letzte rückgängig gemachte Aktion wiederherstellen
if (action != null) {
HitoriCell cell = board.getCell(action.getRow(), action.getCol());
cell.setState(HitoriCell.CellState.valueOf(action.getNewState()));
@@ -137,12 +140,18 @@ public class GameBoard extends JPanel {
return redoButton;
}
+ /**
+ * Erstellt den "Lösen"-Button.
+ *
+ * @return Der Validate-Button.
+ */
+
private JButton createValidateButton() {
JButton validateButton = Setup.createGameBoardButton("Lösen", 80, 30);
validateButton.addActionListener(e -> {
- if (validateCurrentBoard()) {
- stopTimer();
- handleHighscore();
+ if (validateCurrentBoard()) { // Prüfen, ob das Spielfeld korrekt gelöst ist
+ stopTimer(); // Timer anhalten
+ handleHighscore(); // Highscore bearbeiten
} else {
JOptionPane.showMessageDialog(this, "Das Spielfeld enthält Fehler!", "Fehler", JOptionPane.ERROR_MESSAGE);
}
@@ -150,6 +159,12 @@ public class GameBoard extends JPanel {
return validateButton;
}
+ /**
+ * Erstellt den "Pause"-Button.
+ *
+ * @return Der Pause-Button.
+ */
+
private JButton createPauseButton() {
JButton pauseButton = Setup.createGameBoardButton("Pause", 80, 30);
pauseButton.addActionListener(e -> {
@@ -159,18 +174,28 @@ public class GameBoard extends JPanel {
return pauseButton;
}
- public boolean validateCurrentBoard() {
+ /**
+ * Validiert das aktuelle Spielfeld gegen die Lösung.
+ *
+ * @return true, wenn das Spielfeld korrekt ist, sonst false.
+ */
+
+ public boolean validateCurrentBoard() {
HitoriValidator validator = new HitoriValidator(board);
- return validator.validateBoard(board.getSolutionCoordinates());
+ return validator.validateBoard(board.getSolutionCoordinates()); // Prüfen, ob das Spielfeld korrekt ist
}
+ /**
+ * Verarbeitet die Highscore-Logik, einschließlich der Überprüfung, ob ein neuer Highscore erreicht wurde,
+ * und speichert den Highscore, wenn der Spieler seinen Namen eingibt.
+ */
+
private void handleHighscore() {
- int elapsedTime = (int) ((System.currentTimeMillis() - startTime) / 1000); // Spielzeit in Sekunden
String boardName = board.getBoardName();
int errors = 0; // Aktuelle Fehlerzahl (falls vorhanden, muss noch angepasst werden)
HighscoreManager manager = new HighscoreManager();
- boolean isNewHighscore = manager.isNewHighscore(elapsedTime, boardName);
+ boolean isNewHighscore = manager.isNewHighscore((int)elapsedTime, boardName); // Prüfen, ob ein neuer Highscore erreicht wurde
// Zeige ein Dialogfenster zur Namenseingabe
String playerName = JOptionPane.showInputDialog(this,
@@ -186,7 +211,7 @@ public class GameBoard extends JPanel {
}
// Speichere den Highscore
- manager.addHighscore(playerName, elapsedTime, boardName, errors);
+ manager.addHighscore(playerName, (int)elapsedTime, boardName, errors);
JOptionPane.showMessageDialog(this,
isNewHighscore
@@ -200,6 +225,10 @@ public class GameBoard extends JPanel {
}
+ /**
+ * Zeigt das Pausenmenü an.
+ */
+
private void showPauseMenu() {
stopTimer(); // Timer pausieren
PauseMenu pauseMenu = new PauseMenu(
@@ -212,6 +241,15 @@ public class GameBoard extends JPanel {
pauseMenu.setVisible(true);
}
+ /**
+ * Erstellt einen Button für eine Zelle des Spielfelds.
+ *
+ * @param cell Die Zelle.
+ * @param row Die Zeile der Zelle.
+ * @param col Die Spalte der Zelle.
+ * @return Der Button.
+ */
+
private JButton createCellButton(HitoriCell cell, int row, int col) {
JButton button = new JButton(String.valueOf(cell.getNumber()));
button.setBackground(Color.LIGHT_GRAY);
@@ -222,6 +260,14 @@ public class GameBoard extends JPanel {
return button;
}
+ /**
+ * Schaltet den Zustand einer Zelle um.
+ *
+ * @param cell Die zu toggelnde Zelle.
+ * @param row Die Zeile der Zelle.
+ * @param col Die Spalte der Zelle.
+ */
+
public void toggleCellState(HitoriCell cell, int row, int col) {
if (cell == null) {
System.err.println("Ungültige Zelle! Der Zustand kann nicht geändert werden.");
@@ -252,6 +298,13 @@ public class GameBoard extends JPanel {
System.out.println("Aktion gespeichert: " + oldState + " -> " + newState);
}
+ /**
+ * Aktualisiert die Darstellung eines Buttons basierend auf dem Zustand der Zelle.
+ *
+ * @param button Der Button.
+ * @param cell Die Zelle.
+ */
+
private void updateButtonState(JButton button, HitoriCell cell) {
switch (cell.getState()) {
case GRAY -> {
@@ -272,22 +325,9 @@ public class GameBoard extends JPanel {
}
}
- private void addHighscore(int elapsedTime, String boardName, int errors) {
- String playerName = JOptionPane.showInputDialog(this,
- "Neuer Highscore! Bitte Namen eingeben:",
- "Highscore speichern",
- JOptionPane.PLAIN_MESSAGE);
-
- if (playerName == null || playerName.trim().isEmpty()) return;
-
- HighscoreManager manager = new HighscoreManager();
- manager.addHighscore(playerName, elapsedTime, boardName, errors);
-
- JOptionPane.showMessageDialog(this,
- "Highscore erfolgreich gespeichert!",
- "Erfolg",
- JOptionPane.INFORMATION_MESSAGE);
- }
+ /**
+ * Kehrt ins Hauptmenü zurück.
+ */
private void returnToMainMenu() {
/// Eltern-Frame abrufen
@@ -304,6 +344,10 @@ public class GameBoard extends JPanel {
}
}
+ /**
+ * Setzt das Spielfeld zurück.
+ */
+
public void resetBoard() {
// Spiellogik zurücksetzen
board.resetBoard();
@@ -330,6 +374,7 @@ public class GameBoard extends JPanel {
repaint();
}
+ // Aktualisiert das Spielfeld
private void refreshBoard() {
remove(1); // Entferne das aktuelle Spielfeld im CENTER
if (getLayout() instanceof BorderLayout) {
@@ -357,6 +402,12 @@ public class GameBoard extends JPanel {
repaint();
}
+ /**
+ * Erstellt das Spielfeld als JPanel.
+ *
+ * @return Das erstellte JPanel mit Spielfeldzellen.
+ */
+
private JPanel createGamePanel() {
JPanel gamePanel = new JPanel(new GridLayout(board.getSize(), board.getSize()));
for (int i = 0; i < board.getSize(); i++) {
@@ -381,4 +432,47 @@ public class GameBoard extends JPanel {
}
+ // --------Hilfsmethoden---------
+
+ // Startet den Timer
+ private void startTimer() {
+ if (timer == null) { // Timer nur beim ersten Start erstellen
+ timer = new Timer(1000, e -> {
+ elapsedTime = (System.currentTimeMillis() - startTime + pausedTime) / 1000; // Zeit berechnen
+ timerLabel.setText("Zeit: " + elapsedTime + " Sekunden");
+ });
+ }
+
+ startTime = System.currentTimeMillis(); // Startzeit setzen, bevor der Timer gestartet wird
+ timer.start(); // Timer starten
+ System.out.println("Startzeit: " + startTime);
+ System.out.println("Pausierte Zeit: " + pausedTime);
+ }
+
+ // Hält den Timer an
+ private void stopTimer() {
+ if (timer != null && timer.isRunning()) {
+ timer.stop(); // Timer anhalten
+ pausedTime += System.currentTimeMillis() - startTime; // Zeit während der Pause speichern
+ System.out.println("Timer gestoppt. Pausierte Zeit: " + pausedTime);
+ }
+ }
+
+ // Setzt den Timer fort
+ public void resumeTimer() {
+ startTime = System.currentTimeMillis(); // Startzeit neu setzen
+ startTimer(); // Timer erneut starten
+ System.out.println("Timer fortgesetzt. Startzeit: " + startTime + ", Pausierte Zeit: " + pausedTime);
+ }
+
+ // Setzt den Timer zurück
+ private void resetTimer() {
+ if (timer != null) {
+ timer.stop();
+ }
+ startTime = 0;
+ pausedTime = 0;
+ timerLabel.setText("Zeit: 0 Sekunden");
+ }
+
}
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameManager.java
index 7d0cc11..8f2b29d 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameManager.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/GameManager.java
@@ -1,5 +1,6 @@
package PR2.HitoriSpiel.Fassade;
+// TODO: Spiel fortsetzen
public class GameManager {
private static GameBoard gameBoard;
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HighscoreManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HighscoreManager.java
index 2ab2a85..1c2a4eb 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HighscoreManager.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HighscoreManager.java
@@ -4,6 +4,12 @@ import java.io.*;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
+/**
+ * Die Klasse HighscoreManager verwaltet die Highscores für das Hitori-Spiel.
+ * Sie unterstützt das Hinzufügen, Speichern, Laden und Analysieren von Highscore-Daten
+ * sowie die Berechnung von Durchschnittszeiten pro Spielfeld.
+ */
+
public class HighscoreManager {
private static final String HIGHSCORE_FILE = "Hitori/src/main/highscores/highscores.txt";
@@ -11,11 +17,22 @@ public class HighscoreManager {
// Highscore-Datenstruktur
private final List highscoreList = new ArrayList<>();
+ /**
+ * Konstruktor, der Highscores aus der Datei lädt.
+ */
+
public HighscoreManager() {
loadHighscores();
}
- // Prüft, ob die gegebene Zeit ein neuer Highscore ist
+ /**
+ * Überprüft, ob die gegebene Zeit ein neuer Highscore für das angegebene Spielfeld ist.
+ *
+ * @param elapsedTime Die benötigte Zeit.
+ * @param boardName Der Name des Spielfelds.
+ * @return true, wenn es ein neuer Highscore ist, sonst false.
+ */
+
public boolean isNewHighscore(int elapsedTime, String boardName) {
// Filtere die Highscores für das gegebene Spielfeld
List highscoresForBoard = getHighscoresForBoard(boardName);
@@ -34,13 +51,27 @@ public class HighscoreManager {
return elapsedTime < bestTime;
}
- // Highscore hinzufügen
+ /**
+ * Fügt einen neuen Highscore hinzu und speichert die aktualisierten Highscores.
+ *
+ * @param playerName Der Name des Spielers.
+ * @param time Die benötigte Zeit.
+ * @param boardName Der Name des Spielfelds.
+ * @param errors Die Anzahl der Fehler.
+ */
+
public synchronized void addHighscore(String playerName, int time, String boardName, int errors) {
highscoreList.add(new Highscore(playerName, time, boardName, errors));
saveHighscores();
}
- // Highscores für ein bestimmtes Spielfeld abrufen
+ /**
+ * Gibt die Highscores für ein bestimmtes Spielfeld zurück, sortiert nach kürzester Zeit.
+ *
+ * @param boardName Der Name des Spielfelds.
+ * @return Eine Liste der Top 10 Highscores für das Spielfeld.
+ */
+
public List getHighscoresForBoard(String boardName) {
return highscoreList.stream()
.filter(highscore -> highscore.getBoardName().equals(boardName))
@@ -49,7 +80,10 @@ public class HighscoreManager {
.toList();
}
- // Highscores speichern
+ /**
+ * Speichert die Highscores in einer Datei.
+ */
+
private void saveHighscores() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(HIGHSCORE_FILE))) {
for (Highscore highscore : highscoreList) {
@@ -61,7 +95,10 @@ public class HighscoreManager {
}
}
- // Highscores laden
+ /**
+ * Lädt die Highscores aus einer Datei.
+ */
+
private void loadHighscores() {
try (BufferedReader reader = new BufferedReader(new FileReader(HIGHSCORE_FILE))) {
String line;
@@ -94,7 +131,12 @@ public class HighscoreManager {
}
}
- // Durchschnittszeit für jedes Spielfeld berechnen
+ /**
+ * Berechnet die Durchschnittszeiten für jedes Spielfeld.
+ *
+ * @return Eine Map mit Spielfeldnamen und deren Durchschnittszeiten.
+ */
+
public Map getAverageTimesByBoard() {
fileLock.lock();
try {
@@ -117,12 +159,20 @@ public class HighscoreManager {
}
}
- // Highscores abrufen
+ /**
+ * Gibt alle Highscores zurück.
+ *
+ * @return Eine Liste aller Highscores.
+ */
+
public List getHighscores() {
return new ArrayList<>(highscoreList); // Modifizierbare Kopie zurückgeben
}
-
- // Löscht alle Highscores
+
+ /**
+ * Löscht alle Highscores und aktualisiert die Datei.
+ */
+
public void clearHighscores() {
fileLock.lock();
try {
@@ -133,13 +183,25 @@ public class HighscoreManager {
}
}
- // Innere Highscore-Klasse
+ /**
+ * Innere Klasse, die einen Highscore repräsentiert.
+ */
+
public static class Highscore {
private final String playerName;
private final int time;
private final String boardName;
private final int errors;
+ /**
+ * Konstruktor für einen Highscore-Eintrag.
+ *
+ * @param playerName Der Name des Spielers.
+ * @param score Die benötigte Zeit.
+ * @param boardName Der Name des Spielfelds.
+ * @param errors Die Anzahl der Fehler.
+ */
+
public Highscore(String playerName, int score, String boardName, int errors) {
this.playerName = playerName;
this.time = score;
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HitoriSolutionLoader.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HitoriSolutionLoader.java
index 97ce4e2..2f25d60 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HitoriSolutionLoader.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/HitoriSolutionLoader.java
@@ -4,10 +4,20 @@ import java.io.*;
import java.util.*;
/**
- * Utility class to load the solution from a CSV file.
+ * Die Klasse HitoriSolutionLoader ist eine Hilfsklasse zum Laden der Lösung für ein Hitori-Spielfeld aus einer CSV-Datei.
+ * Die Lösung wird im Abschnitt "//Lösung" der Datei erwartet und enthält die Koordinaten der schwarzen Zellen.
*/
+
public class HitoriSolutionLoader {
+ /**
+ * Lädt die Lösung für ein Hitori-Spielfeld aus einer Ressourcendatei.
+ *
+ * @param resourcePath Der Pfad zur Ressourcendatei.
+ * @return Eine Liste der Koordinaten der schwarzen Zellen im Format "row,column".
+ * @throws IOException Wenn die Datei nicht gefunden wird oder ein Lesefehler auftritt.
+ */
+
public static List loadSolution(String resourcePath) throws IOException {
List solutionCoordinates = new ArrayList<>();
boolean solutionSectionFound = false;
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/Setup.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/Setup.java
index 5175ec4..05e5ee4 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/Setup.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/Setup.java
@@ -5,6 +5,10 @@ import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+/**
+ * Die Klasse Setup bietet zentrale Methoden und Konstanten zur Gestaltung und Vereinheitlichung der GUI-Komponenten für das Hitori-Spiel.
+ */
+
public class Setup {
// Standardfarben
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/StateManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/StateManager.java
index ed43030..11134d8 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/StateManager.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Fassade/StateManager.java
@@ -6,16 +6,38 @@ import PR2.HitoriSpiel.Domain.StateFileManager;
import java.io.*;
import java.util.Stack;
+/**
+ * Die Klasse StateManager verwaltet die Undo- und Redo-Funktionalität für das Hitori-Spiel
+ * und speichert Zustandsänderungen in einer Datei.
+ */
+
public class StateManager implements Serializable {
private final Stack undoStack = new Stack<>();
private final Stack redoStack = new Stack<>();
+ /**
+ * Speichert eine neue Aktion im Undo-Stack und leert den Redo-Stack.
+ * Speichert zudem den aktuellen Zustand in einer Datei.
+ *
+ * @param row Die Zeile der Aktion.
+ * @param col Die Spalte der Aktion.
+ * @param oldState Der alte Zustand.
+ * @param newState Der neue Zustand.
+ */
+
public void saveAction(int row, int col, String oldState, String newState) {
undoStack.push(new Action(row, col, oldState, newState));
redoStack.clear(); // Redo-Stack leeren, da ein neuer Zustand hinzugefügt wurde
StateFileManager.saveState(undoStack, redoStack); // Speichern in Datei
}
+ /**
+ * Führt eine Undo-Aktion aus, verschiebt die Aktion in den Redo-Stack
+ * und speichert den aktuellen Zustand in einer Datei.
+ *
+ * @return Die rückgängig gemachte Aktion oder null, wenn der Undo-Stack leer ist.
+ */
+
public Action undo() {
if (!undoStack.isEmpty()) {
Action action = undoStack.pop();
@@ -26,6 +48,13 @@ public class StateManager implements Serializable {
return null;
}
+ /**
+ * Führt eine Redo-Aktion aus, verschiebt die Aktion in den Undo-Stack
+ * und speichert den aktuellen Zustand in einer Datei.
+ *
+ * @return Die wiederhergestellte Aktion oder null, wenn der Redo-Stack leer ist.
+ */
+
public Action redo() {
if (!redoStack.isEmpty()) {
Action action = redoStack.pop();
@@ -36,6 +65,10 @@ public class StateManager implements Serializable {
return null;
}
+ /**
+ * Lädt die Undo- und Redo-Stacks aus einer Datei, um den letzten gespeicherten Zustand wiederherzustellen.
+ */
+
public void loadStateFromFile() {
StateFileManager.loadState(undoStack, redoStack); // Stacks aus Datei laden
}
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/BoardLoader.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/BoardLoader.java
index 6d24734..fc40c1e 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/BoardLoader.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/BoardLoader.java
@@ -5,25 +5,19 @@ import java.net.URLDecoder;
import java.util.*;
import java.util.jar.*;
+/**
+ * Die Klasse BoardLoader lädt Spielfeld-Dateien für das Hitori-Spiel aus dem Dateisystem oder einem JAR-Archiv
+ * und bietet Funktionen zum Parsen der Dateien in ein 2D-Array.
+ */
+
public class BoardLoader {
- public static class BoardData {
- private final int[][] board;
- private final List solution;
-
- public BoardData(int[][] board, List solution) {
- this.board = board;
- this.solution = solution;
- }
-
- public int[][] getBoard() {
- return board;
- }
-
- public List getSolution() {
- return solution;
- }
- }
+ /**
+ * Lädt eine Liste von Spielfelddateien aus dem Verzeichnis oder dem JAR-Archiv.
+ * Sortiert die Dateien nach Schwierigkeitsgrad (leicht, medium) und Größe.
+ *
+ * @return Eine Liste der gefundenen Spielfelddateien.
+ */
public static List loadBoardsAsList() {
List boardFiles = new ArrayList<>();
@@ -87,8 +81,13 @@ public class BoardLoader {
return boardFiles;
}
-
-
+ /**
+ * Lädt ein Spielfeld aus einer Ressourcendatei und gibt es als 2D-Array zurück.
+ *
+ * @param resourcePath Der Pfad zur Ressourcendatei.
+ * @return Ein 2D-Array, das das geladene Spielfeld darstellt.
+ * @throws IOException Wenn die Datei nicht gefunden oder fehlerhaft ist.
+ */
public static int[][] loadBoard(String resourcePath) throws IOException {
List rows = new ArrayList<>();
@@ -142,6 +141,10 @@ public class BoardLoader {
}
+
+ //--------------------------Hilfsmethoden----------------------------------
+
+
// Hilfsmethode zum Extrahieren der Größe aus dem Dateinamen
private static int extractSize(String fileName) {
try {
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java
index f498ba2..4fc504c 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java
@@ -2,22 +2,34 @@ package PR2.HitoriSpiel.GUI;
import PR2.HitoriSpiel.Fassade.HighscoreManager;
import PR2.HitoriSpiel.Fassade.Setup;
-import javax.swing.table.DefaultTableModel;
+import javax.swing.table.DefaultTableModel;
import javax.swing.*;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
+import java.util.*;
import java.util.List;
-import java.util.Map;
-// aktueller Stand
+
+/**
+ * Die Klasse HighscoreDialog erstellt ein Dialogfenster, das die Highscores für verschiedene Spielfelder des Hitori-Spiels
+ * anzeigt und verwaltet. Sie ermöglicht die Auswahl eines Spielfelds, das Anzeigen der zugehörigen Highscores und die
+ * Berechnung der Durchschnittszeiten.
+ */
+
+
public class HighscoreDialog extends JDialog {
private final HighscoreManager highscoreManager;
private final DefaultTableModel tableModel;
private final JComboBox boardSelector;
+ /**
+ * Konstruktor, der das Highscore-Dialogfenster erstellt und initialisiert.
+ *
+ * @param parentFrame Das übergeordnete Fenster, in dem der Dialog angezeigt wird.
+ * @param boardNames Eine Liste von Spielfelddateinamen.
+ */
+
public HighscoreDialog(JFrame parentFrame, List boardNames) {
super(parentFrame, "Highscoreliste", true);
@@ -64,7 +76,6 @@ public class HighscoreDialog extends JDialog {
closeButton.setFont(new Font(closeButton.getFont().getName(), closeButton.getFont().getStyle(), 18)); // Schriftgröße ändern
closeButton.addActionListener(e -> dispose());
buttonPanel.add(closeButton);
-
Setup.stylePanel(buttonPanel); // Hintergrundstil setzen
add(buttonPanel, BorderLayout.SOUTH);
@@ -75,6 +86,11 @@ public class HighscoreDialog extends JDialog {
}
}
+ /**
+ * Lädt die Highscores für ein ausgewähltes Spielfeld und aktualisiert die Tabelle.
+ *
+ * @param boardName Der Name des ausgewählten Spielfelds.
+ */
private void loadHighscoresForBoard(String boardName) {
tableModel.setRowCount(0); // Tabelle zurücksetzen
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/PauseMenu.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/PauseMenu.java
index 7dce088..7b80534 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/PauseMenu.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/PauseMenu.java
@@ -7,9 +7,24 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;
+/**
+ * Die Klasse PauseMenu erstellt ein Dialogfenster, das während einer Pause im Hitori-Spiel angezeigt wird.
+ * Sie bietet Optionen, das Spiel fortzusetzen, zum Hauptmenü zurückzukehren oder das Spiel zu beenden.
+ */
+
public class PauseMenu extends JDialog {
private final GameBoard gameBoard;
+ /**
+ * Konstruktor, der das Pause-Menü erstellt und die entsprechenden Buttons konfiguriert.
+ *
+ * @param parent Das übergeordnete Fenster, in dem der Dialog angezeigt wird.
+ * @param gameBoard Das aktuelle GameBoard-Objekt, um den Timer fortzusetzen.
+ * @param resumeAction Aktion, die ausgeführt wird, wenn der "Spiel fortsetzen"-Button geklickt wird.
+ * @param mainMenuAction Aktion, die ausgeführt wird, wenn der "Zum Hauptmenü"-Button geklickt wird.
+ * @param exitAction Aktion, die ausgeführt wird, wenn der "Spiel beenden"-Button geklickt wird.
+ */
+
public PauseMenu(JFrame parent, GameBoard gameBoard, ActionListener resumeAction, ActionListener mainMenuAction, ActionListener exitAction) {
super(parent, "Pause", true);
this.gameBoard = gameBoard; // Instanz speichern
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/StartMenu.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/StartMenu.java
index d84c79f..bad10d2 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/StartMenu.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/StartMenu.java
@@ -1,22 +1,31 @@
package PR2.HitoriSpiel.GUI;
-import PR2.HitoriSpiel.Domain.HitoriBoard;
+import PR2.HitoriSpiel.Fassade.BoardManager;
import PR2.HitoriSpiel.Fassade.GameBoard;
import PR2.HitoriSpiel.Fassade.HitoriSolutionLoader;
import PR2.HitoriSpiel.Fassade.Setup;
import javax.swing.*;
import java.awt.*;
-import java.util.LinkedHashMap;
+import java.util.*;
import java.util.List;
-import java.util.Map;
-import java.util.Random;
import static PR2.HitoriSpiel.GUI.BoardLoader.loadBoard;
+/**
+ * Die Klasse StartMenu erstellt das Hauptmenü des Hitori-Spiels und bietet Optionen wie Spielfeldauswahl,
+ * Fortsetzen eines Spiels, Start eines zufälligen Spielfelds, Highscore-Anzeige und Spielbeendigung.
+ */
+
public class StartMenu extends JPanel {
private final JFrame parentFrame;
+ /**
+ * Konstruktor, der das Hauptmenü erstellt und alle relevanten Buttons und Aktionen initialisiert.
+ *
+ * @param parentFrame Das übergeordnete JFrame-Fenster, in dem das Menü angezeigt wird.
+ */
+
public StartMenu(JFrame parentFrame) {
this.parentFrame = parentFrame;
setLayout(new GridBagLayout());
@@ -56,11 +65,21 @@ public class StartMenu extends JPanel {
}
+ /**
+ * Aktion für den "Spiel fortsetzen"-Button.
+ * Zeigt einen Hinweis an, da die Funktion noch nicht implementiert ist.
+ */
+
public void continueGame() {
// TODO: Logik zum Fortsetzen des Spiels implementieren
JOptionPane.showMessageDialog(this, "Spiel fortsetzen wurde angeklickt");
}
+ /**
+ * Aktion für den "Spielfeld aussuchen"-Button.
+ * Öffnet ein Dialogfenster zur Auswahl eines Spielfelds aus der verfügbaren Liste.
+ */
+
public void selectBoard() {
// Lade die Liste der Dateinamen
@@ -109,6 +128,10 @@ public class StartMenu extends JPanel {
}
}
+ /**
+ * Aktion für den "Zufälliges Spielfeld"-Button.
+ * Wählt ein zufälliges Spielfeld aus der Liste und lädt es.
+ */
public void randomBoard() {
List boardFileNames = BoardLoader.loadBoardsAsList();
@@ -121,6 +144,10 @@ public class StartMenu extends JPanel {
loadAndDisplayBoard(randomFile);
}
+ /**
+ * Aktion für den "Highscoreliste anschauen"-Button.
+ * Öffnet das Highscore-Dialogfenster.
+ */
public void highscorelist() {
List boardNames = BoardLoader.loadBoardsAsList(); // Lade die Spielfeldnamen
@@ -132,6 +159,12 @@ public class StartMenu extends JPanel {
new HighscoreDialog((JFrame) SwingUtilities.getWindowAncestor(this), boardNames).setVisible(true);
}
+ /**
+ * Lädt ein Spielfeld aus einer Datei und zeigt es im Hauptfenster an.
+ *
+ * @param selectedFile Der Name der ausgewählten Datei.
+ */
+
private void loadAndDisplayBoard(String selectedFile) {
try {
String resourcePath = "/persistent/Hitori_Spielfelder/" + selectedFile;
@@ -140,8 +173,10 @@ public class StartMenu extends JPanel {
int[][] boardData = loadBoard(resourcePath);
java.util.List solutionCoordinates = HitoriSolutionLoader.loadSolution(resourcePath);
- HitoriBoard hitoriBoard = new HitoriBoard(boardData, solutionCoordinates, selectedFile); // Stelle sicher, dass die Lösung korrekt geladen wird
- GameBoard gameBoard = new GameBoard(hitoriBoard);
+ //HitoriBoard hitoriBoard = new HitoriBoard(boardData, solutionCoordinates, selectedFile); // Stelle sicher, dass die Lösung korrekt geladen wird
+ // BoardManager-Instanz erstellen
+ BoardManager boardManager = new BoardManager();
+ GameBoard gameBoard = new GameBoard(boardManager.createBoard(boardData, solutionCoordinates, selectedFile));
loadGameBoard(gameBoard, solutionCoordinates);
System.out.println("Ausgewählte Datei: " + selectedFile);
@@ -152,7 +187,9 @@ public class StartMenu extends JPanel {
}
}
- // Hilfsmethoden
+ // --------------------Hilfsmethoden--------------------------------------------
+
+ //Aktualisiert die Benutzeroberfläche, um das geladene Spielfeld anzuzeigen
private void loadGameBoard(GameBoard gameBoard, java.util.List solutionCoordinates) {
removeAll();
setLayout(new BorderLayout());
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Main/Main.java b/Hitori/src/main/java/PR2/HitoriSpiel/Main/Main.java
index 5469b63..ad70667 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/Main/Main.java
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/Main/Main.java
@@ -11,9 +11,6 @@ import javax.swing.*;
public class Main {
public static void main(String[] args) {
- // Initialisiere den StateManager
- StateManager stateManager = new StateManager();
-
// Füge einen Shutdown-Hook hinzu, um Zustände bei Beendigung zu speichern
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
//stateManager.saveStateToFile(); // Speichert die aktuellen Zustände in einer Datei
diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/project_structure.puml b/Hitori/src/main/java/PR2/HitoriSpiel/project_structure.puml
index 3a4ffbe..209e04a 100644
--- a/Hitori/src/main/java/PR2/HitoriSpiel/project_structure.puml
+++ b/Hitori/src/main/java/PR2/HitoriSpiel/project_structure.puml
@@ -71,6 +71,10 @@ package PR2.HitoriSpiel.Fassade {
+ addHighscore(String playerName, int score, String boardName, int errors): void
+ getHighscoresForBoard(String boardName): List
}
+
+ class BoardManager {
+ + createBoard(int[][] boardData, List solutionCoordinates, String selectedFile): HitoriBoard
+ }
}
package PR2.HitoriSpiel.GUI {
@@ -106,7 +110,7 @@ package PR2.HitoriSpiel.Main {
PR2.HitoriSpiel.Domain.HitoriBoard "1" *-- "many" PR2.HitoriSpiel.Domain.HitoriCell
PR2.HitoriSpiel.Domain.StateManager "1" *-- "many" PR2.HitoriSpiel.Domain.Action
PR2.HitoriSpiel.Fassade.GameBoard "1" *-- "1" PR2.HitoriSpiel.Domain.HitoriBoard
-PR2.HitoriSpiel.GUI.BoardLoader ..> PR2.HitoriSpiel.Domain.HitoriBoard
+PR2.HitoriSpiel.Fassade.BoardManager ..> PR2.HitoriSpiel.GUI.StartMenu
PR2.HitoriSpiel.GUI.HighscoreDialog ..> PR2.HitoriSpiel.Fassade.HighscoreManager
PR2.HitoriSpiel.GUI.PauseMenu --> PR2.HitoriSpiel.Fassade.GameBoard
PR2.HitoriSpiel.GUI.StartMenu --> PR2.HitoriSpiel.GUI.BoardLoader
diff --git a/Hitori/src/test/java/Domain/HitoriBoardTest.java b/Hitori/src/test/java/Domain/HitoriBoardTest.java
index ac4b2de..94f7e36 100644
--- a/Hitori/src/test/java/Domain/HitoriBoardTest.java
+++ b/Hitori/src/test/java/Domain/HitoriBoardTest.java
@@ -25,12 +25,4 @@ public class HitoriBoardTest {
assertEquals(HitoriCell.CellState.GRAY, board.getCell(0, 0).getState());
}
- @Test
- public void testSetAndGetNumbers() {
- int[][] initialNumbers = {{9, 10}, {11, 12}};
- HitoriBoard board = new HitoriBoard(initialNumbers, Arrays.asList(), "SetNumbersTest");
- int[][] newNumbers = {{1, 2}, {3, 4}};
- board.setNumbers(newNumbers);
- assertArrayEquals(newNumbers, board.getNumbers());
- }
}