diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java index 6ae2412..d329401 100644 --- a/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java +++ b/Hitori/src/main/java/PR2/HitoriSpiel/GUI/HighscoreDialog.java @@ -3,11 +3,13 @@ package PR2.HitoriSpiel.GUI; import PR2.HitoriSpiel.Utils.HighscoreManager; import PR2.HitoriSpiel.Utils.Setup; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.*; import java.awt.*; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; // aktueller Stand @@ -18,11 +20,11 @@ public class HighscoreDialog extends JDialog { public HighscoreDialog(JFrame parentFrame) { super(parentFrame, "Highscoreliste", true); - setSize(600, 400); - setLocationRelativeTo(parentFrame); - this.highscoreManager = new HighscoreManager(); + setLayout(new BorderLayout()); + setSize(700, 400); + setLocationRelativeTo(parentFrame); Setup.stylePanel((JPanel) getContentPane()); // Hintergrundfarbe setzen JLabel titleLabel = new JLabel("Highscores", SwingConstants.CENTER); @@ -30,11 +32,28 @@ public class HighscoreDialog extends JDialog { Setup.styleLabel(titleLabel); // Schriftstil setzen add(titleLabel, BorderLayout.NORTH); - String[] columnNames = {"Platz", "Name", "Zeit (Sek.)", "Spielfeld"}; + String[] columnNames = {"Platz", "Name", "Zeit (Sek.)", "Spielfeld", "Durchschnittszeit des Spielfelds"}; tableModel = new DefaultTableModel(columnNames, 0); JTable highscoreTable = new JTable(tableModel); highscoreTable.setFillsViewportHeight(true); highscoreTable.setEnabled(false); // Tabelle nur zur Anzeige + + // Renderer, um Text in der Mitte der Zellen zu platzieren + DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer(); + centerRenderer.setHorizontalAlignment(SwingConstants.CENTER); + + for (int i = 0; i < highscoreTable.getColumnCount(); i++) { + highscoreTable.getColumnModel().getColumn(i).setCellRenderer(centerRenderer); + } + + // Automatische Spaltenbreitenanpassung und individuelle Breiten setzen + highscoreTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + highscoreTable.getColumnModel().getColumn(0).setPreferredWidth(50); // Platz + highscoreTable.getColumnModel().getColumn(1).setPreferredWidth(150); // Name + highscoreTable.getColumnModel().getColumn(2).setPreferredWidth(100); // Punkte + highscoreTable.getColumnModel().getColumn(3).setPreferredWidth(150); // Spielfeld + highscoreTable.getColumnModel().getColumn(4).setPreferredWidth(230); // Durchschnittszeit + JScrollPane scrollPane = new JScrollPane(highscoreTable); add(scrollPane, BorderLayout.CENTER); @@ -59,7 +78,7 @@ public class HighscoreDialog extends JDialog { if (confirmation == JOptionPane.YES_OPTION) { highscoreManager.clearHighscores(); - loadHighscores(); // Tabelle aktualisieren + loadHighscoresWithAverages(); // Tabelle aktualisieren JOptionPane.showMessageDialog(this, "Alle Highscores wurden gelöscht."); } }); @@ -69,27 +88,28 @@ public class HighscoreDialog extends JDialog { add(buttonPanel, BorderLayout.SOUTH); // Highscores laden - loadHighscores(); + loadHighscoresWithAverages(); } - private void loadHighscores() { + private void loadHighscoresWithAverages() { tableModel.setRowCount(0); // Tabelle zurücksetzen - List highscores = highscoreManager.getHighscores(); + List highscores = highscoreManager.getSortedHighscores(); + Map averageTimes = highscoreManager.getAverageTimesByBoard(); - highscores.sort(Comparator.comparingInt(HighscoreManager.Highscore::getScore)); // Sortierung: Kürzeste Zeit zuerst - - int rank = 1; // Platznummer + int rank = 1; for (HighscoreManager.Highscore highscore : highscores) { + double averageTime = averageTimes.getOrDefault(highscore.getBoardName(), 0.0); tableModel.addRow(new Object[]{ - rank++, // Platznummer hochzählen - highscore.getPlayerName(), // Name des Spielers - highscore.getScore(), // Zeit in Sekunden - highscore.getBoardName() // Name des Spielfelds + rank++, // Platzierung + highscore.getPlayerName(), // Name + highscore.getScore(), // Punkte + highscore.getBoardName(), // Spielfeld + String.format("%.2f", averageTime) // Durchschnittszeit }); } } public void refreshHighscores() { - loadHighscores(); + loadHighscoresWithAverages(); } } diff --git a/Hitori/src/main/java/PR2/HitoriSpiel/Utils/HighscoreManager.java b/Hitori/src/main/java/PR2/HitoriSpiel/Utils/HighscoreManager.java index 5f8ea85..129b39b 100644 --- a/Hitori/src/main/java/PR2/HitoriSpiel/Utils/HighscoreManager.java +++ b/Hitori/src/main/java/PR2/HitoriSpiel/Utils/HighscoreManager.java @@ -1,15 +1,12 @@ package PR2.HitoriSpiel.Utils; import java.io.*; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.List; +import java.util.*; import java.util.concurrent.locks.ReentrantLock; public class HighscoreManager { - private static final String HIGHSCORE_FILE = "highscores.txt"; + private static final String HIGHSCORE_FILE = "Files/highscores.txt"; private static final ReentrantLock fileLock = new ReentrantLock(); // Highscore-Datenstruktur private final List highscoreList = new ArrayList<>(); @@ -47,7 +44,7 @@ public class HighscoreManager { // Neue Methode: Überprüfung, ob ein neuer Highscore erreicht wurde public boolean isNewHighscore(int elapsedTime, String boardName) { - List highscores = getHighscores(); + List highscores = getSortedHighscores(); // Prüfen, ob das Board bereits einen Highscore-Eintrag hat for (Highscore highscore : highscores) { @@ -63,16 +60,25 @@ public class HighscoreManager { // Highscores laden private void loadHighscores() { fileLock.lock(); - try (BufferedReader reader = new BufferedReader(new FileReader(HIGHSCORE_FILE))) { - String line; - while ((line = reader.readLine()) != null) { - String[] parts = line.split(","); - if (parts.length == 3) { // Name, Punkte, Spielfeld - highscoreList.add(new Highscore(parts[0], Integer.parseInt(parts[1]), parts[2])); + try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(HIGHSCORE_FILE)) { + if (inputStream == null) { + System.out.println("Datei highscores.txt nicht im Classpath gefunden."); + return; + } + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { + highscoreList.clear(); // Liste zurücksetzen + String line; + while ((line = reader.readLine()) != null) { + String[] parts = line.split(","); + if (parts.length == 3) { // Name, Punkte, Spielfeld + String playerName = parts[0].trim(); + int score = Integer.parseInt(parts[1].trim()); + String boardName = parts[2].trim(); + highscoreList.add(new Highscore(playerName, score, boardName)); + } } } - } catch (FileNotFoundException e) { - System.out.println("Highscore-Datei nicht gefunden. Sie wird nach dem ersten Speichern erstellt."); } catch (IOException | NumberFormatException e) { System.err.println("Fehler beim Laden der Highscores: " + e.getMessage()); } finally { @@ -96,11 +102,40 @@ public class HighscoreManager { } } - // Highscores abrufen - public List getHighscores() { - return new ArrayList<>(highscoreList); // Modifizierbare Kopie zurückgeben + // Highscores abrufen (sortiert nach kürzester Zeit) + public List getSortedHighscores() { + fileLock.lock(); + try { + highscoreList.sort(Comparator.comparingInt(Highscore::getScore)); // Kürzeste Zeit zuerst + return new ArrayList<>(highscoreList); // Kopie der Liste zurückgeben + } finally { + fileLock.unlock(); + } } - + + // Durchschnittszeit für jedes Spielfeld berechnen + public Map getAverageTimesByBoard() { + fileLock.lock(); + try { + Map> boardScores = new HashMap<>(); + + for (Highscore highscore : highscoreList) { + boardScores.computeIfAbsent(highscore.getBoardName(), k -> new ArrayList<>()).add(highscore.getScore()); + } + + Map averageTimes = new HashMap<>(); + for (Map.Entry> entry : boardScores.entrySet()) { + List scores = entry.getValue(); + double average = scores.stream().mapToInt(Integer::intValue).average().orElse(0.0); + averageTimes.put(entry.getKey(), average); + } + + return averageTimes; + } finally { + fileLock.unlock(); + } + } + // Löscht alle Highscores public void clearHighscores() { fileLock.lock(); diff --git a/Hitori/src/main/resources/Files/highscores.txt b/Hitori/src/main/resources/Files/highscores.txt index 9d2c76f..04dafb5 100644 --- a/Hitori/src/main/resources/Files/highscores.txt +++ b/Hitori/src/main/resources/Files/highscores.txt @@ -1 +1,3 @@ -ame, Zeit (Sekunden), Spielfeld +NameTest,123,Hitori4x4 +Test,456,Hitori4x4 +Ioana,234,Hitori8x8 \ No newline at end of file