Compare commits
No commits in common. "main" and "feature/CSVReader" have entirely different histories.
main
...
feature/CS
33
pom.xml
33
pom.xml
|
|
@ -21,31 +21,6 @@
|
||||||
<version>5.8.1</version>
|
<version>5.8.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.junit.jupiter</groupId>
|
|
||||||
<artifactId>junit-jupiter</artifactId>
|
|
||||||
<version>5.9.3</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.powermock</groupId>
|
|
||||||
<artifactId>powermock-module-junit4</artifactId>
|
|
||||||
<version>2.0.9</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.powermock</groupId>
|
|
||||||
<artifactId>powermock-api-mockito2</artifactId>
|
|
||||||
<version>2.0.9</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.powermock</groupId>
|
|
||||||
<artifactId>powermock-module-junit4-rule</artifactId>
|
|
||||||
<version>2.0.9</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-checkstyle-plugin -->
|
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-checkstyle-plugin -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
|
@ -53,14 +28,6 @@
|
||||||
<version>3.6.0</version>
|
<version>3.6.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mockito</groupId>
|
|
||||||
<artifactId>mockito-core</artifactId>
|
|
||||||
<version>5.15.2</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-javadoc-plugin -->
|
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-javadoc-plugin -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package de.deversmann;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
de.deversmann.gui.HitoriApp app = new de.deversmann.gui.HitoriApp();
|
System.out.println("Hello, World!");
|
||||||
app.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,54 +4,36 @@ import java.io.BufferedReader;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CSVReader {
|
public class CSVReader {
|
||||||
|
|
||||||
public PuzzleData readPuzzleWithSolution(String csvFile) throws IOException {
|
/**
|
||||||
List<int[]> puzzleRows = new ArrayList<>();
|
* Liest die CSV-Datei ein und gibt die enthaltenen Werte als zweidimensionales int-Array zurück.
|
||||||
List<int[]> solutionCoordinates = new ArrayList<>();
|
*
|
||||||
|
* @param csvFile Pfad zur CSV-Datei
|
||||||
|
* @return zweidimensionales Array, das die Zahlen aus der CSV enthält
|
||||||
|
* @throws IOException wenn ein Fehler beim Lesen auftritt
|
||||||
|
*/
|
||||||
|
public int[][] readCsvToIntArray(String csvFile) throws IOException {
|
||||||
|
ArrayList<int[]> rows = new ArrayList<>();
|
||||||
|
|
||||||
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
|
try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
|
||||||
String line;
|
String line;
|
||||||
boolean inSolutionPart = false;
|
|
||||||
|
|
||||||
while ((line = br.readLine()) != null) {
|
while ((line = br.readLine()) != null) {
|
||||||
line = line.trim();
|
String[] tokens = line.split(",");
|
||||||
if (line.isEmpty()) {
|
int[] row = new int[tokens.length];
|
||||||
continue;
|
for (int i = 0; i < tokens.length; i++) {
|
||||||
}
|
row[i] = Integer.parseInt(tokens[i].trim());
|
||||||
if (line.startsWith("//Lösung") || line.startsWith("//")) {
|
|
||||||
inSolutionPart = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!inSolutionPart) {
|
|
||||||
// Puzzle-Teil
|
|
||||||
String[] tokens = line.split(",");
|
|
||||||
int[] rowValues = new int[tokens.length];
|
|
||||||
for (int i = 0; i < tokens.length; i++) {
|
|
||||||
rowValues[i] = Integer.parseInt(tokens[i].trim());
|
|
||||||
}
|
|
||||||
puzzleRows.add(rowValues);
|
|
||||||
} else {
|
|
||||||
// Lösungsteil
|
|
||||||
String[] coords = line.split(",");
|
|
||||||
if (coords.length == 2) {
|
|
||||||
int row = Integer.parseInt(coords[0].trim());
|
|
||||||
int col = Integer.parseInt(coords[1].trim());
|
|
||||||
solutionCoordinates.add(new int[]{row, col});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
rows.add(row);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// puzzleRows -> 2D-Array
|
// ArrayList in 2D-Array umwandeln
|
||||||
int[][] puzzleArray = new int[puzzleRows.size()][];
|
int[][] result = new int[rows.size()][];
|
||||||
for (int i = 0; i < puzzleRows.size(); i++) {
|
for (int i = 0; i < rows.size(); i++) {
|
||||||
puzzleArray[i] = puzzleRows.get(i);
|
result[i] = rows.get(i);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
return new PuzzleData(puzzleArray, solutionCoordinates);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
public class HighscoreEntry {
|
|
||||||
|
|
||||||
private final String playerName;
|
|
||||||
private final long timeSeconds;
|
|
||||||
private final int errorCount;
|
|
||||||
|
|
||||||
public HighscoreEntry(String playerName, long timeSeconds, int errorCount) {
|
|
||||||
this.playerName = playerName;
|
|
||||||
this.timeSeconds = timeSeconds;
|
|
||||||
this.errorCount = errorCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPlayerName() {
|
|
||||||
return playerName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTimeSeconds() {
|
|
||||||
return timeSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getErrorCount() {
|
|
||||||
return errorCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return playerName + " - " + timeSeconds + "s (Fehler: " + errorCount + ")";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -4,99 +4,72 @@ import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HighscoreManager {
|
public class HighscoreManager {
|
||||||
|
private final Map<String, List<HighscoreEntry>> highscoreMap;
|
||||||
private Map<String, List<HighscoreEntry>> highscoreMap;
|
|
||||||
|
|
||||||
public HighscoreManager() {
|
public HighscoreManager() {
|
||||||
this.highscoreMap = new HashMap<>();
|
highscoreMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHighscore(String puzzleName, String playerName, long timeSeconds, int errorCount) {
|
public void addHighscore(String spielfeld, String name, long zeit, int fehler) {
|
||||||
highscoreMap.putIfAbsent(puzzleName, new ArrayList<>());
|
HighscoreEntry entry = new HighscoreEntry(name, zeit, fehler);
|
||||||
highscoreMap.get(puzzleName).add(new HighscoreEntry(playerName, timeSeconds, errorCount));
|
highscoreMap.computeIfAbsent(spielfeld, k -> new ArrayList<>()).add(entry);
|
||||||
|
saveHighscores();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HighscoreEntry> getHighscores(String puzzleName) {
|
public List<HighscoreEntry> getHighscores(String spielfeld) {
|
||||||
return highscoreMap.getOrDefault(puzzleName, Collections.emptyList());
|
return highscoreMap.getOrDefault(spielfeld, new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getAverageTime(String puzzleName) {
|
public double getDurchschnittszeit(String spielfeld) {
|
||||||
List<HighscoreEntry> entries = highscoreMap.get(puzzleName);
|
List<HighscoreEntry> highscores = getHighscores(spielfeld);
|
||||||
if (entries == null || entries.isEmpty()) {
|
return highscores.stream().mapToLong(HighscoreEntry::getZeit).average().orElse(0);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
long sum = 0;
|
|
||||||
for (HighscoreEntry e : entries) {
|
|
||||||
sum += e.getTimeSeconds();
|
|
||||||
}
|
|
||||||
return (double) sum / entries.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveSinglePuzzle(String puzzleName, String filename) throws IOException {
|
private void saveHighscores() {
|
||||||
List<HighscoreEntry> entries = getHighscores(puzzleName);
|
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("highscores.dat"))) {
|
||||||
|
oos.writeObject(highscoreMap);
|
||||||
entries.sort(Comparator
|
} catch (IOException e) {
|
||||||
.comparingInt(HighscoreEntry::getErrorCount)
|
System.err.println("Fehler beim Speichern der Highscores: " + e.getMessage());
|
||||||
.thenComparingLong(HighscoreEntry::getTimeSeconds));
|
|
||||||
|
|
||||||
double avgTime = getAverageTime(puzzleName);
|
|
||||||
|
|
||||||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filename))) {
|
|
||||||
if (avgTime < 0) {
|
|
||||||
writer.write("Durchschnittszeit: Keine Einträge");
|
|
||||||
} else {
|
|
||||||
writer.write(String.format("Durchschnittszeit: %.2f s", avgTime));
|
|
||||||
}
|
|
||||||
writer.newLine();
|
|
||||||
writer.newLine();
|
|
||||||
|
|
||||||
writer.write(String.format("%-6s | %-5s | %-6s | %-15s",
|
|
||||||
"Platz", "Zeit", "Fehler", "Name"));
|
|
||||||
writer.newLine();
|
|
||||||
writer.write("------------------------------------------------------------");
|
|
||||||
writer.newLine();
|
|
||||||
|
|
||||||
int place = 1;
|
|
||||||
for (HighscoreEntry e : entries) {
|
|
||||||
writer.write(String.format("%-6s | %-5d | %-6d | %-15s",
|
|
||||||
place + ".",
|
|
||||||
e.getTimeSeconds(),
|
|
||||||
e.getErrorCount(),
|
|
||||||
e.getPlayerName()));
|
|
||||||
writer.newLine();
|
|
||||||
place++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadSinglePuzzle(String puzzleName, String filename) throws IOException {
|
@SuppressWarnings("unchecked")
|
||||||
File file = new File(filename);
|
public void loadHighscores() {
|
||||||
if (!file.exists()) {
|
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("highscores.dat"))) {
|
||||||
System.out.println("Highscore-Datei " + filename + " existiert nicht; wird neu erstellt.");
|
Map<String, List<HighscoreEntry>> loadedMap = (Map<String, List<HighscoreEntry>>) ois.readObject();
|
||||||
return;
|
highscoreMap.clear();
|
||||||
}
|
highscoreMap.putAll(loadedMap);
|
||||||
|
} catch (IOException | ClassNotFoundException e) {
|
||||||
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
|
System.err.println("Fehler beim Laden der Highscores: " + e.getMessage());
|
||||||
// Durchschnittszeit und Header überspringen
|
|
||||||
reader.readLine();
|
|
||||||
reader.readLine();
|
|
||||||
reader.readLine();
|
|
||||||
reader.readLine();
|
|
||||||
|
|
||||||
String line;
|
|
||||||
while ((line = reader.readLine()) != null) {
|
|
||||||
String[] parts = line.split("\\|");
|
|
||||||
if (parts.length < 4) continue;
|
|
||||||
|
|
||||||
String timeStr = parts[1].trim();
|
|
||||||
String errorStr = parts[2].trim();
|
|
||||||
String nameStr = parts[3].trim();
|
|
||||||
|
|
||||||
long timeSeconds = Long.parseLong(timeStr);
|
|
||||||
int errorCount = Integer.parseInt(errorStr);
|
|
||||||
|
|
||||||
addHighscore(puzzleName, nameStr, timeSeconds, errorCount);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public static class HighscoreEntry implements Serializable {
|
||||||
|
private final String name;
|
||||||
|
private final long zeit;
|
||||||
|
private final int fehler;
|
||||||
|
|
||||||
|
public HighscoreEntry(String name, long zeit, int fehler) {
|
||||||
|
this.name = name;
|
||||||
|
this.zeit = zeit;
|
||||||
|
this.fehler = fehler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getZeit() {
|
||||||
|
return zeit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFehler() {
|
||||||
|
return fehler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + ": " + zeit + "ms, Fehler: " + fehler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class PuzzleData {
|
|
||||||
|
|
||||||
private final int[][] puzzle;
|
|
||||||
private final List<int[]> solutionCoordinates;
|
|
||||||
|
|
||||||
public PuzzleData(int[][] puzzle, List<int[]> solutionCoordinates) {
|
|
||||||
this.puzzle = puzzle;
|
|
||||||
this.solutionCoordinates = solutionCoordinates;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[][] getPuzzle() {
|
|
||||||
return puzzle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<int[]> getSolutionCoordinates() {
|
|
||||||
return solutionCoordinates;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,37 +1,41 @@
|
||||||
package de.deversmann.domain;
|
package de.deversmann.domain;
|
||||||
|
|
||||||
public class Zeiterfassung {
|
public class Zeiterfassung {
|
||||||
|
private long startzeit;
|
||||||
private long startTime;
|
private long endzeit;
|
||||||
private long endTime;
|
private boolean laufen;
|
||||||
private boolean isRunning;
|
|
||||||
|
|
||||||
public Zeiterfassung() {
|
|
||||||
this.isRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
if (!isRunning) {
|
this.startzeit = System.currentTimeMillis();
|
||||||
startTime = System.currentTimeMillis();
|
this.laufen= true;
|
||||||
isRunning = true;
|
|
||||||
System.out.println("Zeiterfassung gestartet");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (isRunning) {
|
this.endzeit = System.currentTimeMillis();
|
||||||
endTime = System.currentTimeMillis();
|
this.laufen= false;
|
||||||
isRunning = false;
|
|
||||||
System.out.println("Zeiterfassung gestoppt, diff=" + getElapsedTimeInSeconds() + "s");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getElapsedTimeInSeconds() {
|
public long getElapsedTimeMillis() {
|
||||||
if (isRunning) {
|
long endTime = laufen ? System.currentTimeMillis() : endzeit;
|
||||||
long current = System.currentTimeMillis();
|
return endTime - startzeit;
|
||||||
return (current - startTime) / 1000;
|
|
||||||
} else {
|
|
||||||
return (endTime - startTime) / 1000;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void reset() {
|
||||||
|
this.startzeit = 0;
|
||||||
|
this.endzeit = 0;
|
||||||
|
this.laufen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFormattedTime() {
|
||||||
|
long elapsed = getElapsedTimeMillis();
|
||||||
|
long hours = elapsed / (3600_000);
|
||||||
|
long remainder = elapsed % 3600_000;
|
||||||
|
long minutes = remainder / 60_000;
|
||||||
|
remainder = remainder % 60_000;
|
||||||
|
long seconds = remainder / 1_000;
|
||||||
|
long millis = remainder % 1_000;
|
||||||
|
|
||||||
|
// Formatierung zu einer lesbaren Zeitangabe
|
||||||
|
return String.format("%02d:%02d:%02d.%03d", hours, minutes, seconds, millis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,4 @@
|
||||||
package de.deversmann.facade;
|
package de.deversmann.facade;
|
||||||
|
|
||||||
import de.deversmann.domain.*;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class Facade {
|
public class Facade {
|
||||||
|
}
|
||||||
private final CSVReader csvReader;
|
|
||||||
private final HighscoreManager highscoreManager;
|
|
||||||
private final Zeiterfassung zeiterfassung;
|
|
||||||
|
|
||||||
private PuzzleData currentPuzzleData;
|
|
||||||
private String currentPuzzleName;
|
|
||||||
private int currentErrorCount = 0;
|
|
||||||
|
|
||||||
public Facade() {
|
|
||||||
this.csvReader = new CSVReader();
|
|
||||||
this.highscoreManager = new HighscoreManager();
|
|
||||||
this.zeiterfassung = new Zeiterfassung();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ladeSpielfeld(String csvPfad) throws IOException {
|
|
||||||
this.currentPuzzleData = csvReader.readPuzzleWithSolution(csvPfad);
|
|
||||||
this.currentPuzzleName = csvPfad;
|
|
||||||
this.currentErrorCount = 0;
|
|
||||||
|
|
||||||
zeiterfassung.stop();
|
|
||||||
zeiterfassung.start();
|
|
||||||
System.out.println("Neues Spielfeld geladen, Timer + Fehler=0");
|
|
||||||
}
|
|
||||||
|
|
||||||
public long stopZeiterfassung() {
|
|
||||||
zeiterfassung.stop();
|
|
||||||
return zeiterfassung.getElapsedTimeInSeconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getElapsedTimeSoFar() {
|
|
||||||
return zeiterfassung.getElapsedTimeInSeconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[][] getAktuellesPuzzle() {
|
|
||||||
return (currentPuzzleData != null) ? currentPuzzleData.getPuzzle() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<int[]> getLoesungsKoordinaten() {
|
|
||||||
return (currentPuzzleData != null) ? currentPuzzleData.getSolutionCoordinates() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fehler-Tracking
|
|
||||||
public void incrementErrorCount() {
|
|
||||||
currentErrorCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentErrorCount() {
|
|
||||||
return currentErrorCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Highscore
|
|
||||||
public void addHighscoreForCurrentPuzzle(String playerName, long timeSeconds, int errorCount) {
|
|
||||||
if (currentPuzzleName != null && !currentPuzzleName.isEmpty()) {
|
|
||||||
highscoreManager.addHighscore(currentPuzzleName, playerName, timeSeconds, errorCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<HighscoreEntry> getHighscoresForCurrentPuzzle() {
|
|
||||||
if (currentPuzzleName == null) {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
return highscoreManager.getHighscores(currentPuzzleName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getAverageTimeForCurrentPuzzle() {
|
|
||||||
if (currentPuzzleName == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return highscoreManager.getAverageTime(currentPuzzleName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveCurrentPuzzleHighscoreToFile() throws IOException {
|
|
||||||
if (currentPuzzleName == null) return;
|
|
||||||
String base = currentPuzzleName.replaceAll(".*/", "");
|
|
||||||
String shortName = base.replace(".csv", "") + "_highscore.txt";
|
|
||||||
highscoreManager.saveSinglePuzzle(currentPuzzleName, shortName);
|
|
||||||
System.out.println("Highscore zu " + base + " in " + shortName + " gespeichert.");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void loadCurrentPuzzleHighscoreFromFile() throws IOException {
|
|
||||||
if (currentPuzzleName == null) return;
|
|
||||||
String base = currentPuzzleName.replaceAll(".*/", "");
|
|
||||||
String shortName = base.replace(".csv", "") + "_highscore.txt";
|
|
||||||
highscoreManager.loadSinglePuzzle(currentPuzzleName, shortName);
|
|
||||||
System.out.println("Highscore zu " + base + " aus " + shortName + " geladen (falls existiert).");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,237 +1,4 @@
|
||||||
package de.deversmann.gui;
|
package de.deversmann.gui;
|
||||||
|
|
||||||
import de.deversmann.facade.Facade;
|
public class GameView {
|
||||||
|
}
|
||||||
import javax.swing.*;
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class GameView extends JFrame {
|
|
||||||
|
|
||||||
private final Facade facade;
|
|
||||||
SpielfeldGUI spielfeldGUI;
|
|
||||||
|
|
||||||
JComboBox<String> cbSpielfelder;
|
|
||||||
JButton btnLoad;
|
|
||||||
JButton btnRandom;
|
|
||||||
JButton btnCheckSolution;
|
|
||||||
JButton btnShowSolution;
|
|
||||||
JButton btnReset;
|
|
||||||
JLabel timeLabel;
|
|
||||||
Timer timer;
|
|
||||||
|
|
||||||
private final String[] spielfelder = {
|
|
||||||
"4x4.csv",
|
|
||||||
"5x5.csv",
|
|
||||||
"8x8_leicht.csv",
|
|
||||||
"8x8_medium.csv",
|
|
||||||
"10x10.csv",
|
|
||||||
"15x15.csv"
|
|
||||||
};
|
|
||||||
|
|
||||||
public GameView(Facade facade) {
|
|
||||||
this.facade = facade;
|
|
||||||
setTitle("Hitori App");
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
setSize(800, 700);
|
|
||||||
initComponents();
|
|
||||||
startTimer();
|
|
||||||
setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
JPanel controlPanel = new JPanel();
|
|
||||||
|
|
||||||
cbSpielfelder = new JComboBox<>(spielfelder);
|
|
||||||
btnLoad = new JButton("Spielfeld laden");
|
|
||||||
btnRandom = new JButton("Zufällig");
|
|
||||||
btnCheckSolution = new JButton("Lösung prüfen");
|
|
||||||
btnShowSolution = new JButton("Lösung anzeigen");
|
|
||||||
btnReset = new JButton("Reset");
|
|
||||||
|
|
||||||
timeLabel = new JLabel("Time: 0s");
|
|
||||||
|
|
||||||
btnLoad.addActionListener(e -> {
|
|
||||||
String selectedFile = (String) cbSpielfelder.getSelectedItem();
|
|
||||||
if (selectedFile != null) {
|
|
||||||
ladeSpielfeld("src/Spielfelder/" + selectedFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
btnRandom.addActionListener(e -> {
|
|
||||||
Random rand = new Random();
|
|
||||||
int idx = rand.nextInt(spielfelder.length);
|
|
||||||
String randomField = spielfelder[idx];
|
|
||||||
cbSpielfelder.setSelectedItem(randomField);
|
|
||||||
ladeSpielfeld("src/Spielfelder/" + randomField);
|
|
||||||
});
|
|
||||||
|
|
||||||
btnCheckSolution.addActionListener(e -> checkSolution());
|
|
||||||
btnShowSolution.addActionListener(e -> showSolution());
|
|
||||||
btnReset.addActionListener(e -> resetField());
|
|
||||||
|
|
||||||
controlPanel.add(new JLabel("Wähle ein Spielfeld:"));
|
|
||||||
controlPanel.add(cbSpielfelder);
|
|
||||||
controlPanel.add(btnLoad);
|
|
||||||
controlPanel.add(btnRandom);
|
|
||||||
controlPanel.add(btnCheckSolution);
|
|
||||||
controlPanel.add(btnShowSolution);
|
|
||||||
controlPanel.add(btnReset);
|
|
||||||
controlPanel.add(timeLabel);
|
|
||||||
|
|
||||||
getContentPane().setLayout(new BorderLayout());
|
|
||||||
getContentPane().add(controlPanel, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
spielfeldGUI = new SpielfeldGUI(1, 1);
|
|
||||||
getContentPane().add(spielfeldGUI, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startTimer() {
|
|
||||||
timer = new Timer(1000, e -> {
|
|
||||||
long seconds = facade.getElapsedTimeSoFar();
|
|
||||||
timeLabel.setText("Time: " + seconds + "s");
|
|
||||||
});
|
|
||||||
timer.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ladeSpielfeld(String pfad) {
|
|
||||||
try {
|
|
||||||
facade.ladeSpielfeld(pfad);
|
|
||||||
facade.loadCurrentPuzzleHighscoreFromFile();
|
|
||||||
|
|
||||||
int[][] feld = facade.getAktuellesPuzzle();
|
|
||||||
if (feld != null) {
|
|
||||||
spielfeldGUI.updateGrid(feld);
|
|
||||||
timeLabel.setText("Time: 0s");
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
"Fehler beim Laden: " + ex.getMessage(),
|
|
||||||
"Fehler",
|
|
||||||
JOptionPane.ERROR_MESSAGE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkSolution() {
|
|
||||||
var blackCells = spielfeldGUI.getBlackCells();
|
|
||||||
var solutionCoordinates = facade.getLoesungsKoordinaten();
|
|
||||||
if (solutionCoordinates == null) {
|
|
||||||
JOptionPane.showMessageDialog(this, "Kein Puzzle geladen!", "Fehler", JOptionPane.ERROR_MESSAGE);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> solutionSet = new HashSet<>();
|
|
||||||
for (int[] sol : solutionCoordinates) {
|
|
||||||
solutionSet.add((sol[0] - 1) + "," + (sol[1] - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
int errorsThisCheck = 0;
|
|
||||||
for (int[] bc : blackCells) {
|
|
||||||
String bcStr = bc[0] + "," + bc[1];
|
|
||||||
if (!solutionSet.contains(bcStr)) {
|
|
||||||
spielfeldGUI.markCellAsError(bc[0], bc[1]);
|
|
||||||
facade.incrementErrorCount();
|
|
||||||
errorsThisCheck++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorsThisCheck > 0) {
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
"Noch nicht korrekt! " + errorsThisCheck + " falsche Felder markiert.",
|
|
||||||
"Ergebnis",
|
|
||||||
JOptionPane.WARNING_MESSAGE
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean allSet = true;
|
|
||||||
for (String sol : solutionSet) {
|
|
||||||
if (!containsCell(blackCells, sol)) {
|
|
||||||
allSet = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!allSet) {
|
|
||||||
JOptionPane.showMessageDialog(this,
|
|
||||||
"Nicht alle richtigen Felder sind schwarz!",
|
|
||||||
"Ergebnis",
|
|
||||||
JOptionPane.WARNING_MESSAGE
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
long finalTime = facade.stopZeiterfassung();
|
|
||||||
timeLabel.setText("Time: " + finalTime + "s");
|
|
||||||
|
|
||||||
String playerName = JOptionPane.showInputDialog(
|
|
||||||
this,
|
|
||||||
"Gratulation, richtig gelöst!\nBitte Namen eingeben:",
|
|
||||||
"Name eingeben",
|
|
||||||
JOptionPane.QUESTION_MESSAGE
|
|
||||||
);
|
|
||||||
if (playerName == null || playerName.isBlank()) {
|
|
||||||
playerName = "Unbekannt";
|
|
||||||
}
|
|
||||||
|
|
||||||
int totalErrors = facade.getCurrentErrorCount();
|
|
||||||
facade.addHighscoreForCurrentPuzzle(playerName, finalTime, totalErrors);
|
|
||||||
|
|
||||||
try {
|
|
||||||
facade.saveCurrentPuzzleHighscoreToFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println("Konnte Puzzle-spezifischen Highscore nicht speichern: " + e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
double avgTime = facade.getAverageTimeForCurrentPuzzle();
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Spiel gelöst!\n");
|
|
||||||
sb.append("Deine Zeit: ").append(finalTime).append("s\n");
|
|
||||||
sb.append("Fehler: ").append(totalErrors).append("\n");
|
|
||||||
if (avgTime < 0) {
|
|
||||||
sb.append("Durchschnittszeit: Keine Einträge\n");
|
|
||||||
} else {
|
|
||||||
sb.append(String.format("Durchschnittszeit: %.2f s\n", avgTime));
|
|
||||||
}
|
|
||||||
|
|
||||||
JOptionPane.showMessageDialog(this, sb.toString(), "Ergebnis", JOptionPane.INFORMATION_MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean containsCell(List<int[]> blackCells, String sol) {
|
|
||||||
String[] parts = sol.split(",");
|
|
||||||
int rr = Integer.parseInt(parts[0]);
|
|
||||||
int cc = Integer.parseInt(parts[1]);
|
|
||||||
for (int[] bc : blackCells) {
|
|
||||||
if (bc[0] == rr && bc[1] == cc) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void showSolution() {
|
|
||||||
var feld = facade.getAktuellesPuzzle();
|
|
||||||
if (feld == null) return;
|
|
||||||
spielfeldGUI.updateGrid(feld);
|
|
||||||
|
|
||||||
var solution = facade.getLoesungsKoordinaten();
|
|
||||||
if (solution != null) {
|
|
||||||
for (int[] coord : solution) {
|
|
||||||
spielfeldGUI.setCellBlack(coord[0] - 1, coord[1] - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
spielfeldGUI.setAllNonBlackToWhite();
|
|
||||||
}
|
|
||||||
|
|
||||||
void resetField() {
|
|
||||||
var feld = facade.getAktuellesPuzzle();
|
|
||||||
if (feld != null) {
|
|
||||||
spielfeldGUI.updateGrid(feld);
|
|
||||||
timeLabel.setText("Time: 0s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,4 @@
|
||||||
package de.deversmann.gui;
|
package de.deversmann.gui;
|
||||||
|
|
||||||
import de.deversmann.facade.Facade;
|
|
||||||
|
|
||||||
|
|
||||||
public class HitoriApp {
|
public class HitoriApp {
|
||||||
|
|
||||||
private Facade facade;
|
|
||||||
|
|
||||||
public HitoriApp() {
|
|
||||||
facade = new Facade();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
GameView view = new GameView(facade);
|
|
||||||
view.setVisible(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,136 +1,97 @@
|
||||||
package de.deversmann.gui;
|
package de.deversmann.gui;
|
||||||
|
|
||||||
|
import de.deversmann.domain.Spielfeld;
|
||||||
|
import de.deversmann.domain.Zeiterfassung;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.MouseAdapter;
|
|
||||||
import java.awt.event.MouseEvent;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class SpielfeldGUI extends JPanel {
|
public class SpielfeldGUI {
|
||||||
|
|
||||||
private JLabel[][] grid;
|
private JFrame frame;
|
||||||
private Set<String> errorCells = new HashSet<>();
|
private JPanel spielfeldPanel;
|
||||||
|
private JLabel timerLabel;
|
||||||
|
private Timer guiTimer;
|
||||||
|
private Spielfeld spielfeld;
|
||||||
|
private Zeiterfassung timer;
|
||||||
|
|
||||||
public SpielfeldGUI(int rows, int cols) {
|
public SpielfeldGUI() {
|
||||||
setLayout(new GridLayout(rows, cols));
|
// Initialisiere Domain-Klassen
|
||||||
grid = new JLabel[rows][cols];
|
spielfeld = new Spielfeld();
|
||||||
|
timer = new Zeiterfassung();
|
||||||
|
|
||||||
for (int r = 0; r < rows; r++) {
|
// Erstelle das Hauptfenster
|
||||||
for (int c = 0; c < cols; c++) {
|
frame = new JFrame("Hitori Spielfeld");
|
||||||
JLabel label = createCellLabel("-", r, c);
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
grid[r][c] = label;
|
frame.setSize(800, 600);
|
||||||
add(label);
|
frame.setLayout(new BorderLayout());
|
||||||
}
|
|
||||||
}
|
// Timer-Anzeige
|
||||||
|
timerLabel = new JLabel("00:00:00.000");
|
||||||
|
timerLabel.setFont(new Font("Monospaced", Font.BOLD, 16));
|
||||||
|
frame.add(timerLabel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// Spielfeld-Panel
|
||||||
|
spielfeldPanel = new JPanel();
|
||||||
|
frame.add(spielfeldPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// Button-Panel
|
||||||
|
JPanel buttonPanel = new JPanel();
|
||||||
|
JButton selectButton = new JButton("Spielfeld auswählen");
|
||||||
|
JButton startButton = new JButton("Timer starten");
|
||||||
|
JButton stopButton = new JButton("Timer stoppen");
|
||||||
|
|
||||||
|
buttonPanel.add(selectButton);
|
||||||
|
buttonPanel.add(startButton);
|
||||||
|
buttonPanel.add(stopButton);
|
||||||
|
frame.add(buttonPanel, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
// Aktionen für Buttons
|
||||||
|
selectButton.addActionListener(e -> ladeSpielfeldMitAuswahl());
|
||||||
|
startButton.addActionListener(e -> starteTimer());
|
||||||
|
stopButton.addActionListener(e -> stoppeTimer());
|
||||||
|
|
||||||
|
// Timer für GUI-Updates
|
||||||
|
guiTimer = new Timer(100, e -> timerLabel.setText(timer.getFormattedTime()));
|
||||||
|
|
||||||
|
// Fenster sichtbar machen
|
||||||
|
frame.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateGrid(int[][] feld) {
|
private void starteTimer() {
|
||||||
if (feld == null) {
|
timer.start();
|
||||||
return;
|
guiTimer.start();
|
||||||
}
|
|
||||||
removeAll();
|
|
||||||
int rows = feld.length;
|
|
||||||
int cols = feld[0].length;
|
|
||||||
setLayout(new GridLayout(rows, cols));
|
|
||||||
grid = new JLabel[rows][cols];
|
|
||||||
errorCells.clear();
|
|
||||||
|
|
||||||
for (int r = 0; r < rows; r++) {
|
|
||||||
for (int c = 0; c < cols; c++) {
|
|
||||||
String text = String.valueOf(feld[r][c]);
|
|
||||||
JLabel label = createCellLabel(text, r, c);
|
|
||||||
grid[r][c] = label;
|
|
||||||
add(label);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAllNonBlackToWhite() {
|
private void stoppeTimer() {
|
||||||
if (grid == null) return;
|
timer.stop();
|
||||||
for (int r = 0; r < grid.length; r++) {
|
guiTimer.stop();
|
||||||
for (int c = 0; c < grid[r].length; c++) {
|
|
||||||
JLabel lbl = grid[r][c];
|
|
||||||
if (lbl != null) {
|
|
||||||
if (!lbl.getBackground().equals(Color.BLACK)) {
|
|
||||||
lbl.setBackground(Color.WHITE);
|
|
||||||
lbl.setForeground(Color.BLACK);
|
|
||||||
clearErrorMark(r, c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void markCellAsError(int row, int col) {
|
private void ladeSpielfeldMitAuswahl() {
|
||||||
if (!isValidCell(row, col)) return;
|
|
||||||
errorCells.add(row + "," + col);
|
|
||||||
grid[row][col].setBorder(BorderFactory.createLineBorder(Color.RED, 3));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearErrorMark(int row, int col) {
|
private void zeigeSpielfeld() {
|
||||||
errorCells.remove(row + "," + col);
|
|
||||||
if (!isValidCell(row, col)) return;
|
|
||||||
grid[row][col].setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<int[]> getBlackCells() {
|
private void feldAktion(int x, int y, JButton button) {
|
||||||
List<int[]> black = new ArrayList<>();
|
String aktuellerZustand = spielfeld.getZustand(x, y);
|
||||||
if (grid == null) return black;
|
String neuerZustand = switch (aktuellerZustand) {
|
||||||
|
case "grau" -> "schwarz";
|
||||||
for (int r = 0; r < grid.length; r++) {
|
case "schwarz" -> "weiß";
|
||||||
for (int c = 0; c < grid[r].length; c++) {
|
default -> "grau";
|
||||||
JLabel lbl = grid[r][c];
|
};
|
||||||
if (lbl != null && lbl.getBackground().equals(Color.BLACK)) {
|
spielfeld.setzeZustand(x, y, neuerZustand);
|
||||||
black.add(new int[]{r, c});
|
button.setBackground(switch (neuerZustand) {
|
||||||
}
|
case "schwarz" -> Color.BLACK;
|
||||||
}
|
case "weiß" -> Color.WHITE;
|
||||||
}
|
default -> Color.GRAY;
|
||||||
return black;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCellBlack(int row, int col) {
|
|
||||||
if (!isValidCell(row, col)) return;
|
|
||||||
JLabel lbl = grid[row][col];
|
|
||||||
lbl.setBackground(Color.BLACK);
|
|
||||||
lbl.setForeground(Color.WHITE);
|
|
||||||
clearErrorMark(row, col);
|
|
||||||
}
|
|
||||||
|
|
||||||
private JLabel createCellLabel(String text, int row, int col) {
|
|
||||||
JLabel label = new JLabel(text, SwingConstants.CENTER);
|
|
||||||
label.setOpaque(true);
|
|
||||||
label.setBackground(Color.GRAY);
|
|
||||||
label.setForeground(Color.BLACK);
|
|
||||||
label.setFont(new Font("Arial", Font.BOLD, 24));
|
|
||||||
label.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
|
|
||||||
|
|
||||||
label.addMouseListener(new MouseAdapter() {
|
|
||||||
@Override
|
|
||||||
public void mouseClicked(MouseEvent e) {
|
|
||||||
toggleColor(label, row, col);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return label;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void toggleColor(JLabel label, int row, int col) {
|
public static void main(String[] args) {
|
||||||
if (label.getBackground().equals(Color.GRAY) || label.getBackground().equals(Color.WHITE)) {
|
SwingUtilities.invokeLater(SpielfeldGUI::new);
|
||||||
label.setBackground(Color.BLACK);
|
|
||||||
label.setForeground(Color.WHITE);
|
|
||||||
} else {
|
|
||||||
label.setBackground(Color.WHITE);
|
|
||||||
label.setForeground(Color.BLACK);
|
|
||||||
}
|
|
||||||
if (errorCells.contains(row + "," + col)) {
|
|
||||||
clearErrorMark(row, col);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isValidCell(int r, int c) {
|
|
||||||
if (grid == null) return false;
|
|
||||||
return (r >= 0 && r < grid.length && c >= 0 && c < grid[r].length);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
Manifest-Version: 1.0
|
|
||||||
Main-Class: de.deversmann.Main
|
|
||||||
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class CSVReaderTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReadPuzzleWithSolutionRealData() throws IOException {
|
|
||||||
String csvContent = """
|
|
||||||
4,5,6,7
|
|
||||||
8,9,10,11
|
|
||||||
12,13,14,15
|
|
||||||
16,17,18,19
|
|
||||||
//Lösung
|
|
||||||
2,2
|
|
||||||
3,3
|
|
||||||
""";
|
|
||||||
Path tempFile = Files.createTempFile("realPuzzle", ".csv");
|
|
||||||
Files.writeString(tempFile, csvContent);
|
|
||||||
|
|
||||||
CSVReader reader = new CSVReader();
|
|
||||||
PuzzleData data = reader.readPuzzleWithSolution(tempFile.toString());
|
|
||||||
|
|
||||||
int[][] expectedPuzzle = {
|
|
||||||
{4, 5, 6, 7},
|
|
||||||
{8, 9, 10, 11},
|
|
||||||
{12, 13, 14, 15},
|
|
||||||
{16, 17, 18, 19}
|
|
||||||
};
|
|
||||||
assertArrayEquals(expectedPuzzle, data.getPuzzle());
|
|
||||||
assertEquals(2, data.getSolutionCoordinates().size());
|
|
||||||
assertArrayEquals(new int[]{2, 2}, data.getSolutionCoordinates().get(0));
|
|
||||||
assertArrayEquals(new int[]{3, 3}, data.getSolutionCoordinates().get(1));
|
|
||||||
|
|
||||||
Files.delete(tempFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReadPuzzleWithInvalidData() throws IOException {
|
|
||||||
String csvContent = """
|
|
||||||
1,2,3
|
|
||||||
4,5
|
|
||||||
//Lösung
|
|
||||||
a,b
|
|
||||||
""";
|
|
||||||
Path tempFile = Files.createTempFile("invalidPuzzle", ".csv");
|
|
||||||
Files.writeString(tempFile, csvContent);
|
|
||||||
|
|
||||||
CSVReader reader = new CSVReader();
|
|
||||||
|
|
||||||
assertThrows(NumberFormatException.class, () -> reader.readPuzzleWithSolution(tempFile.toString()));
|
|
||||||
|
|
||||||
Files.delete(tempFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testReadPuzzleWithoutSolution() throws IOException {
|
|
||||||
String csvContent = """
|
|
||||||
1,2,3
|
|
||||||
4,5,6
|
|
||||||
7,8,9
|
|
||||||
""";
|
|
||||||
Path tempFile = Files.createTempFile("noSolutionPuzzle", ".csv");
|
|
||||||
Files.writeString(tempFile, csvContent);
|
|
||||||
|
|
||||||
CSVReader reader = new CSVReader();
|
|
||||||
PuzzleData data = reader.readPuzzleWithSolution(tempFile.toString());
|
|
||||||
|
|
||||||
assertNotNull(data.getPuzzle());
|
|
||||||
assertTrue(data.getSolutionCoordinates().isEmpty());
|
|
||||||
|
|
||||||
Files.delete(tempFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
|
|
||||||
class HighscoreEntryTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testHighscoreEntryProperties() {
|
|
||||||
HighscoreEntry entry = new HighscoreEntry("Alice", 120, 3);
|
|
||||||
|
|
||||||
assertEquals("Alice", entry.getPlayerName());
|
|
||||||
assertEquals(120, entry.getTimeSeconds());
|
|
||||||
assertEquals(3, entry.getErrorCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testToString() {
|
|
||||||
HighscoreEntry entry = new HighscoreEntry("Alice", 120, 3);
|
|
||||||
|
|
||||||
assertEquals("Alice - 120s (Fehler: 3)", entry.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class HighscoreManagerTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAddAndRetrieveHighscores() {
|
|
||||||
HighscoreManager manager = new HighscoreManager();
|
|
||||||
manager.addHighscore("Puzzle1", "Alice", 120, 2);
|
|
||||||
|
|
||||||
List<HighscoreEntry> highscores = manager.getHighscores("Puzzle1");
|
|
||||||
|
|
||||||
assertEquals(1, highscores.size());
|
|
||||||
assertEquals("Alice", highscores.get(0).getPlayerName());
|
|
||||||
assertEquals(120, highscores.get(0).getTimeSeconds());
|
|
||||||
assertEquals(2, highscores.get(0).getErrorCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSaveAndLoadHighscores() throws IOException {
|
|
||||||
HighscoreManager manager = new HighscoreManager();
|
|
||||||
manager.addHighscore("Puzzle1", "Alice", 120, 2);
|
|
||||||
|
|
||||||
Path tempFile = Files.createTempFile("testHighscores", ".txt");
|
|
||||||
manager.saveSinglePuzzle("Puzzle1", tempFile.toString());
|
|
||||||
|
|
||||||
HighscoreManager newManager = new HighscoreManager();
|
|
||||||
newManager.loadSinglePuzzle("Puzzle1", tempFile.toString());
|
|
||||||
|
|
||||||
List<HighscoreEntry> highscores = newManager.getHighscores("Puzzle1");
|
|
||||||
|
|
||||||
assertEquals(1, highscores.size());
|
|
||||||
assertEquals("Alice", highscores.get(0).getPlayerName());
|
|
||||||
assertEquals(120, highscores.get(0).getTimeSeconds());
|
|
||||||
assertEquals(2, highscores.get(0).getErrorCount());
|
|
||||||
|
|
||||||
Files.delete(tempFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetAverageTimeNoEntries() {
|
|
||||||
HighscoreManager manager = new HighscoreManager();
|
|
||||||
double avgTime = manager.getAverageTime("Puzzle1");
|
|
||||||
|
|
||||||
assertEquals(-1, avgTime, "Average time should be -1 for no entries.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadSinglePuzzleFileNotFound() {
|
|
||||||
HighscoreManager manager = new HighscoreManager();
|
|
||||||
|
|
||||||
assertDoesNotThrow(() -> manager.loadSinglePuzzle("Puzzle1", "nonexistent.txt"));
|
|
||||||
assertTrue(manager.getHighscores("Puzzle1").isEmpty());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class PuzzleDataTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetPuzzle() {
|
|
||||||
int[][] puzzle = {{1, 2}, {3, 4}};
|
|
||||||
List<int[]> solution = List.of(new int[]{1, 1}, new int[]{2, 2});
|
|
||||||
|
|
||||||
PuzzleData data = new PuzzleData(puzzle, solution);
|
|
||||||
|
|
||||||
assertArrayEquals(puzzle, data.getPuzzle());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetSolutionCoordinates() {
|
|
||||||
int[][] puzzle = {{1, 2}, {3, 4}};
|
|
||||||
List<int[]> solution = List.of(new int[]{1, 1}, new int[]{2, 2});
|
|
||||||
|
|
||||||
PuzzleData data = new PuzzleData(puzzle, solution);
|
|
||||||
|
|
||||||
assertEquals(solution, data.getSolutionCoordinates());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
package de.deversmann.domain;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class ZeiterfassungTest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testZeiterfassungStartStop() throws InterruptedException {
|
|
||||||
Zeiterfassung timer = new Zeiterfassung();
|
|
||||||
timer.start();
|
|
||||||
|
|
||||||
Thread.sleep(1000); // 1 Sekunde warten
|
|
||||||
|
|
||||||
timer.stop();
|
|
||||||
long elapsedTime = timer.getElapsedTimeInSeconds();
|
|
||||||
|
|
||||||
assertTrue(elapsedTime >= 1 && elapsedTime < 2, "Elapsed time should be approximately 1 second.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
package de.deversmann.facade;
|
|
||||||
|
|
||||||
import de.deversmann.domain.*;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.powermock.api.mockito.PowerMockito;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
class FacadeTest {
|
|
||||||
|
|
||||||
private CSVReader csvReaderMock;
|
|
||||||
private HighscoreManager highscoreManagerMock;
|
|
||||||
private Zeiterfassung zeiterfassungMock;
|
|
||||||
private Facade facade;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() throws Exception {
|
|
||||||
facade = new Facade();
|
|
||||||
|
|
||||||
csvReaderMock = mock(CSVReader.class);
|
|
||||||
highscoreManagerMock = mock(HighscoreManager.class);
|
|
||||||
zeiterfassungMock = mock(Zeiterfassung.class);
|
|
||||||
|
|
||||||
PowerMockito.field(Facade.class, "csvReader").set(facade, csvReaderMock);
|
|
||||||
PowerMockito.field(Facade.class, "highscoreManager").set(facade, highscoreManagerMock);
|
|
||||||
PowerMockito.field(Facade.class, "zeiterfassung").set(facade, zeiterfassungMock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLadeSpielfeldMitEchtenDaten() throws IOException {
|
|
||||||
PuzzleData puzzleData = new PuzzleData(new int[][]{{1, 2, 3, 4}}, List.of(new int[]{1, 1}));
|
|
||||||
when(csvReaderMock.readPuzzleWithSolution(anyString())).thenReturn(puzzleData);
|
|
||||||
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
assertNotNull(facade.getAktuellesPuzzle());
|
|
||||||
assertEquals(1, facade.getLoesungsKoordinaten().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testStopZeiterfassung() {
|
|
||||||
when(zeiterfassungMock.getElapsedTimeInSeconds()).thenReturn(42L);
|
|
||||||
|
|
||||||
long elapsedTime = facade.stopZeiterfassung();
|
|
||||||
|
|
||||||
verify(zeiterfassungMock, times(1)).stop();
|
|
||||||
assertEquals(42L, elapsedTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetElapsedTimeSoFar() {
|
|
||||||
when(zeiterfassungMock.getElapsedTimeInSeconds()).thenReturn(15L);
|
|
||||||
|
|
||||||
long elapsedTime = facade.getElapsedTimeSoFar();
|
|
||||||
|
|
||||||
verify(zeiterfassungMock, times(1)).getElapsedTimeInSeconds();
|
|
||||||
assertEquals(15L, elapsedTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testIncrementErrorCount() {
|
|
||||||
assertEquals(0, facade.getCurrentErrorCount());
|
|
||||||
|
|
||||||
facade.incrementErrorCount();
|
|
||||||
|
|
||||||
assertEquals(1, facade.getCurrentErrorCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testAddHighscoreForCurrentPuzzle() throws IOException {
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
facade.addHighscoreForCurrentPuzzle("Player1", 100L, 3);
|
|
||||||
|
|
||||||
verify(highscoreManagerMock, times(1))
|
|
||||||
.addHighscore(eq("test.csv"), eq("Player1"), eq(100L), eq(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetHighscoresForCurrentPuzzle() throws IOException {
|
|
||||||
when(highscoreManagerMock.getHighscores("test.csv"))
|
|
||||||
.thenReturn(List.of(new HighscoreEntry("Player1", 100L, 2)));
|
|
||||||
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
List<HighscoreEntry> highscores = facade.getHighscoresForCurrentPuzzle();
|
|
||||||
|
|
||||||
assertEquals(1, highscores.size());
|
|
||||||
assertEquals("Player1", highscores.get(0).getPlayerName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetAverageTimeForCurrentPuzzle() throws IOException {
|
|
||||||
when(highscoreManagerMock.getAverageTime("test.csv")).thenReturn(75.0);
|
|
||||||
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
double avgTime = facade.getAverageTimeForCurrentPuzzle();
|
|
||||||
|
|
||||||
assertEquals(75.0, avgTime, 0.01);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSaveCurrentPuzzleHighscoreToFile() throws IOException {
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
facade.saveCurrentPuzzleHighscoreToFile();
|
|
||||||
|
|
||||||
verify(highscoreManagerMock, times(1))
|
|
||||||
.saveSinglePuzzle(eq("test.csv"), anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadCurrentPuzzleHighscoreFromFile() throws IOException {
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
facade.loadCurrentPuzzleHighscoreFromFile();
|
|
||||||
|
|
||||||
verify(highscoreManagerMock, times(1))
|
|
||||||
.loadSinglePuzzle(eq("test.csv"), anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetAktuellesPuzzle() throws IOException {
|
|
||||||
PuzzleData puzzleData = new PuzzleData(new int[][]{{1, 2, 3, 4}}, List.of());
|
|
||||||
when(csvReaderMock.readPuzzleWithSolution(anyString())).thenReturn(puzzleData);
|
|
||||||
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
int[][] puzzle = facade.getAktuellesPuzzle();
|
|
||||||
|
|
||||||
assertNotNull(puzzle);
|
|
||||||
assertEquals(4, puzzle[0].length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testGetLoesungsKoordinaten() throws IOException {
|
|
||||||
PuzzleData puzzleData = new PuzzleData(new int[][]{{1, 2}}, List.of(new int[]{1, 1}));
|
|
||||||
when(csvReaderMock.readPuzzleWithSolution(anyString())).thenReturn(puzzleData);
|
|
||||||
|
|
||||||
facade.ladeSpielfeld("test.csv");
|
|
||||||
|
|
||||||
List<int[]> solutionCoordinates = facade.getLoesungsKoordinaten();
|
|
||||||
|
|
||||||
assertNotNull(solutionCoordinates);
|
|
||||||
assertEquals(1, solutionCoordinates.size());
|
|
||||||
assertArrayEquals(new int[]{1, 1}, solutionCoordinates.get(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,153 +0,0 @@
|
||||||
package de.deversmann.gui;
|
|
||||||
|
|
||||||
import de.deversmann.facade.Facade;
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import static org.mockito.Mockito.*;
|
|
||||||
|
|
||||||
class GameViewTest {
|
|
||||||
|
|
||||||
private Facade facadeMock;
|
|
||||||
private GameView gameView;
|
|
||||||
|
|
||||||
@BeforeEach
|
|
||||||
void setup() {
|
|
||||||
facadeMock = mock(Facade.class);
|
|
||||||
gameView = new GameView(facadeMock);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testInitComponents() {
|
|
||||||
assertNotNull(gameView.cbSpielfelder);
|
|
||||||
assertNotNull(gameView.btnLoad);
|
|
||||||
assertNotNull(gameView.btnRandom);
|
|
||||||
assertNotNull(gameView.btnCheckSolution);
|
|
||||||
assertNotNull(gameView.btnShowSolution);
|
|
||||||
assertNotNull(gameView.btnReset);
|
|
||||||
assertNotNull(gameView.timeLabel);
|
|
||||||
assertNotNull(gameView.spielfeldGUI);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadPuzzleActionWithRealData() throws Exception {
|
|
||||||
doNothing().when(facadeMock).ladeSpielfeld("4x4.csv");
|
|
||||||
|
|
||||||
gameView.ladeSpielfeld("4x4.csv");
|
|
||||||
|
|
||||||
verify(facadeMock, times(1)).ladeSpielfeld("4x4.csv");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testLoadInvalidPuzzle() throws IOException {
|
|
||||||
doThrow(new IOException("Invalid file")).when(facadeMock).ladeSpielfeld("invalid.csv");
|
|
||||||
|
|
||||||
gameView.ladeSpielfeld("invalid.csv");
|
|
||||||
|
|
||||||
verify(facadeMock, times(1)).ladeSpielfeld("invalid.csv");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckSolutionWithCorrectData() {
|
|
||||||
var blackCells = List.of(new int[]{0, 0});
|
|
||||||
var solutionCoordinates = List.of(new int[]{1, 1});
|
|
||||||
|
|
||||||
when(facadeMock.getLoesungsKoordinaten()).thenReturn(solutionCoordinates);
|
|
||||||
when(facadeMock.getAktuellesPuzzle()).thenReturn(new int[][]{{1, 2}});
|
|
||||||
|
|
||||||
SpielfeldGUI spielfeldGUIMock = mock(SpielfeldGUI.class);
|
|
||||||
when(spielfeldGUIMock.getBlackCells()).thenReturn(blackCells);
|
|
||||||
|
|
||||||
gameView.spielfeldGUI = spielfeldGUIMock;
|
|
||||||
gameView.checkSolution();
|
|
||||||
|
|
||||||
verify(spielfeldGUIMock, never()).markCellAsError(anyInt(), anyInt());
|
|
||||||
verify(facadeMock, times(1)).stopZeiterfassung();
|
|
||||||
verify(facadeMock, times(1)).addHighscoreForCurrentPuzzle(anyString(), anyLong(), anyInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testCheckSolutionWithErrors() {
|
|
||||||
var blackCells = List.of(new int[]{0, 1});
|
|
||||||
var solutionCoordinates = List.of(new int[]{1, 1});
|
|
||||||
|
|
||||||
when(facadeMock.getLoesungsKoordinaten()).thenReturn(solutionCoordinates);
|
|
||||||
when(facadeMock.getAktuellesPuzzle()).thenReturn(new int[][]{{1, 2}});
|
|
||||||
|
|
||||||
SpielfeldGUI spielfeldGUIMock = mock(SpielfeldGUI.class);
|
|
||||||
when(spielfeldGUIMock.getBlackCells()).thenReturn(blackCells);
|
|
||||||
|
|
||||||
gameView.spielfeldGUI = spielfeldGUIMock;
|
|
||||||
gameView.checkSolution();
|
|
||||||
|
|
||||||
verify(spielfeldGUIMock, times(1)).markCellAsError(0, 1);
|
|
||||||
verify(facadeMock, times(1)).incrementErrorCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testShowSolution() {
|
|
||||||
int[][] mockGrid = {{1, 2}, {3, 4}};
|
|
||||||
List<int[]> solution = List.of(new int[]{1, 1}, new int[]{2, 2});
|
|
||||||
|
|
||||||
when(facadeMock.getAktuellesPuzzle()).thenReturn(mockGrid);
|
|
||||||
when(facadeMock.getLoesungsKoordinaten()).thenReturn(solution);
|
|
||||||
|
|
||||||
SpielfeldGUI spielfeldGUIMock = mock(SpielfeldGUI.class);
|
|
||||||
gameView.spielfeldGUI = spielfeldGUIMock;
|
|
||||||
|
|
||||||
gameView.showSolution();
|
|
||||||
|
|
||||||
verify(spielfeldGUIMock, times(1)).updateGrid(mockGrid);
|
|
||||||
verify(spielfeldGUIMock, times(1)).setCellBlack(0, 0); // Lösung wird schwarz markiert
|
|
||||||
verify(spielfeldGUIMock, times(1)).setCellBlack(1, 1);
|
|
||||||
verify(spielfeldGUIMock, times(1)).setAllNonBlackToWhite();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testResetField() {
|
|
||||||
int[][] mockGrid = {{1, 2}, {3, 4}};
|
|
||||||
when(facadeMock.getAktuellesPuzzle()).thenReturn(mockGrid);
|
|
||||||
|
|
||||||
SpielfeldGUI spielfeldGUIMock = mock(SpielfeldGUI.class);
|
|
||||||
gameView.spielfeldGUI = spielfeldGUIMock;
|
|
||||||
|
|
||||||
gameView.resetField();
|
|
||||||
|
|
||||||
verify(spielfeldGUIMock, times(1)).updateGrid(mockGrid);
|
|
||||||
assertEquals("Time: 0s", gameView.timeLabel.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testTimerUpdatesTimeLabel() {
|
|
||||||
when(facadeMock.getElapsedTimeSoFar()).thenReturn(42L);
|
|
||||||
|
|
||||||
Timer timer = gameView.timer;
|
|
||||||
assertNotNull(timer);
|
|
||||||
|
|
||||||
timer.getActionListeners()[0].actionPerformed(null);
|
|
||||||
|
|
||||||
JLabel timeLabel = gameView.timeLabel;
|
|
||||||
assertEquals("Time: 42s", timeLabel.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testRandomPuzzleLoading() throws Exception {
|
|
||||||
doNothing().when(facadeMock).ladeSpielfeld(anyString());
|
|
||||||
|
|
||||||
gameView.btnRandom.doClick();
|
|
||||||
|
|
||||||
verify(facadeMock, atLeastOnce()).ladeSpielfeld(anyString());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testContainsCell() {
|
|
||||||
List<int[]> blackCells = List.of(new int[]{1, 1}, new int[]{2, 2});
|
|
||||||
assertTrue(gameView.containsCell(blackCells, "1,1"));
|
|
||||||
assertFalse(gameView.containsCell(blackCells, "3,3"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
package de.deversmann.gui;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
class SpielfeldGUITest {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testUpdateGrid() {
|
|
||||||
SpielfeldGUI gui = new SpielfeldGUI(2, 2);
|
|
||||||
|
|
||||||
int[][] grid = {
|
|
||||||
{1, 2},
|
|
||||||
{3, 4}
|
|
||||||
};
|
|
||||||
gui.updateGrid(grid);
|
|
||||||
|
|
||||||
assertNotNull(gui.getBlackCells());
|
|
||||||
assertEquals(0, gui.getBlackCells().size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testSetCellBlack() {
|
|
||||||
SpielfeldGUI gui = new SpielfeldGUI(2, 2);
|
|
||||||
|
|
||||||
gui.setCellBlack(0, 1);
|
|
||||||
assertEquals(1, gui.getBlackCells().size());
|
|
||||||
assertArrayEquals(new int[]{0, 1}, gui.getBlackCells().get(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void testMarkCellAsError() {
|
|
||||||
SpielfeldGUI gui = new SpielfeldGUI(2, 2);
|
|
||||||
|
|
||||||
gui.markCellAsError(0, 1);
|
|
||||||
|
|
||||||
// Fehlerhafte Zelle wird rot markiert (Border)
|
|
||||||
assertNotNull(gui.getBlackCells());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue