Highscore Eintrag für Name hinzugefügt

continueCode
Vickvick2002 2025-01-05 16:22:30 +01:00
parent eb30f5cd13
commit f7868e042f
4 changed files with 153 additions and 96 deletions

View File

@ -9,8 +9,6 @@ import PR2.HitoriSpiel.Utils.Setup;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.io.FileWriter;
import java.io.IOException;
public class GameBoard extends JPanel { public class GameBoard extends JPanel {
private final HitoriBoard board; private final HitoriBoard board;
@ -25,11 +23,8 @@ public class GameBoard extends JPanel {
this.board = board; this.board = board;
setLayout(new BorderLayout()); setLayout(new BorderLayout());
// Timer-Label oben hinzufügen // Timer-Label hinzufügen
timerLabel = new JLabel("Zeit: 0 Sekunden"); initializeTimerLabel();
timerLabel.setHorizontalAlignment(SwingConstants.CENTER);
Setup.styleLabel(timerLabel);
add(timerLabel, BorderLayout.NORTH);
// Timer starten // Timer starten
startTimer(); startTimer();
@ -43,6 +38,13 @@ public class GameBoard extends JPanel {
add(controlPanel, BorderLayout.SOUTH); add(controlPanel, BorderLayout.SOUTH);
} }
private void initializeTimerLabel() {
timerLabel = new JLabel("Zeit: 0 Sekunden");
timerLabel.setHorizontalAlignment(SwingConstants.CENTER);
Setup.styleLabel(timerLabel);
add(timerLabel, BorderLayout.NORTH);
}
private void startTimer() { private void startTimer() {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
timer = new Timer(1000, e -> { timer = new Timer(1000, e -> {
@ -61,13 +63,25 @@ public class GameBoard extends JPanel {
private JPanel createControlPanel() { private JPanel createControlPanel() {
JPanel controlPanel = new JPanel(); JPanel controlPanel = new JPanel();
controlPanel.add(createResetButton());
controlPanel.add(createUndoButton());
controlPanel.add(createRedoButton());
controlPanel.add(createValidateButton());
controlPanel.add(createPauseButton());
return controlPanel;
}
private JButton createResetButton() {
JButton resetButton = Setup.createGameBoardButton("Zurücksetzen", 150, 30); JButton resetButton = Setup.createGameBoardButton("Zurücksetzen", 150, 30);
resetButton.addActionListener(e -> { resetButton.addActionListener(e -> {
saveStateForUndo(); saveStateForUndo();
resetBoard(); resetBoard();
//refreshBoard();
}); });
return resetButton;
}
private JButton createUndoButton() {
JButton undoButton = Setup.createGameBoardButton("Undo", 80, 30); JButton undoButton = Setup.createGameBoardButton("Undo", 80, 30);
undoButton.addActionListener(e -> { undoButton.addActionListener(e -> {
int[][] previousState = stateManager.undo(board.getNumbers()); int[][] previousState = stateManager.undo(board.getNumbers());
@ -78,49 +92,64 @@ public class GameBoard extends JPanel {
JOptionPane.showMessageDialog(this, "Kein Zustand zum Zurücksetzen vorhanden.", "Undo", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(this, "Kein Zustand zum Zurücksetzen vorhanden.", "Undo", JOptionPane.INFORMATION_MESSAGE);
} }
}); });
return undoButton;
}
private JButton createRedoButton() {
JButton redoButton = Setup.createGameBoardButton("Redo", 80, 30); JButton redoButton = Setup.createGameBoardButton("Redo", 80, 30);
redoButton.addActionListener(e -> { redoButton.addActionListener(e -> {
int[][] nextState = stateManager.redo(board.getNumbers()); int[][] nextState = stateManager.redo(board.getNumbers());
if (nextState != null) { if (nextState != null) {
board.setNumbers(nextState); board.setNumbers(nextState);
refreshBoard(); updateBoard();
} else { } else {
JOptionPane.showMessageDialog(this, "Kein Zustand zum Wiederholen vorhanden.", "Redo", JOptionPane.INFORMATION_MESSAGE); JOptionPane.showMessageDialog(this, "Kein Zustand zum Wiederholen vorhanden.", "Redo", JOptionPane.INFORMATION_MESSAGE);
} }
}); });
return redoButton;
}
private JButton createValidateButton() {
JButton validateButton = Setup.createGameBoardButton("Lösen", 80, 30); JButton validateButton = Setup.createGameBoardButton("Lösen", 80, 30);
validateButton.addActionListener(e -> { validateButton.addActionListener(e -> {
if (validateCurrentBoard()) { if (validateCurrentBoard()) {
stopTimer(); stopTimer();
JOptionPane.showMessageDialog(this, "Das Spielfeld ist korrekt gelöst!", "Erfolg", JOptionPane.INFORMATION_MESSAGE); handleHighscore();
} else { } else {
JOptionPane.showMessageDialog(this, "Das Spielfeld enthält Fehler!", "Fehler", JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(this, "Das Spielfeld enthält Fehler!", "Fehler", JOptionPane.ERROR_MESSAGE);
} }
}); });
return validateButton;
}
private JButton createPauseButton() {
JButton pauseButton = Setup.createGameBoardButton("Pause", 80, 30); JButton pauseButton = Setup.createGameBoardButton("Pause", 80, 30);
pauseButton.addActionListener(e -> { pauseButton.addActionListener(e -> {
stopTimer(); stopTimer();
showPauseMenu(); showPauseMenu();
}); });
return pauseButton;
controlPanel.add(resetButton);
controlPanel.add(undoButton);
controlPanel.add(redoButton);
controlPanel.add(validateButton);
controlPanel.add(pauseButton);
return controlPanel;
} }
public boolean validateCurrentBoard() { public boolean validateCurrentBoard() {
HitoriValidator validator = new HitoriValidator(board); HitoriValidator validator = new HitoriValidator(board);
return validator.validateBoard(board.getSolutionCoordinates()); return validator.validateBoard(board.getSolutionCoordinates());
} }
private void handleHighscore() {
int elapsedTime = (int) ((System.currentTimeMillis() - startTime) / 1000);
String boardName = board.getBoardName();
HighscoreManager manager = new HighscoreManager();
boolean isNewHighscore = manager.isNewHighscore(elapsedTime, boardName);
if (isNewHighscore) {
addHighscore(elapsedTime, boardName);
} else {
JOptionPane.showMessageDialog(this, "Das Spielfeld ist korrekt gelöst!", "Erfolg", JOptionPane.INFORMATION_MESSAGE);
}
}
private void showPauseMenu() { private void showPauseMenu() {
PauseMenu pauseMenu = new PauseMenu( PauseMenu pauseMenu = new PauseMenu(
(JFrame) SwingUtilities.getWindowAncestor(this), (JFrame) SwingUtilities.getWindowAncestor(this),
@ -146,30 +175,27 @@ public class GameBoard extends JPanel {
System.err.println("Ungültige Zelle! Der Zustand kann nicht geändert werden."); System.err.println("Ungültige Zelle! Der Zustand kann nicht geändert werden.");
return; return;
} }
if (cell.getState() == HitoriCell.CellState.GRAY) { switch (cell.getState()) {
cell.setState(HitoriCell.CellState.BLACK); case GRAY -> cell.setState(HitoriCell.CellState.BLACK);
} else if (cell.getState() == HitoriCell.CellState.BLACK) { case BLACK -> cell.setState(HitoriCell.CellState.WHITE);
cell.setState(HitoriCell.CellState.WHITE); case WHITE -> cell.setState(HitoriCell.CellState.GRAY);
} else {
cell.setState(HitoriCell.CellState.GRAY);
} }
} }
private void updateButtonState(JButton button, HitoriCell cell) { private void updateButtonState(JButton button, HitoriCell cell) {
switch (cell.getState()) { switch (cell.getState()) {
case GRAY: case GRAY -> {
button.setBackground(Color.LIGHT_GRAY); button.setBackground(Color.LIGHT_GRAY);
button.setText(String.valueOf(cell.getNumber())); button.setText(String.valueOf(cell.getNumber()));
break; }
case BLACK: case BLACK -> {
button.setBackground(Color.BLACK); button.setBackground(Color.BLACK);
button.setForeground(Color.WHITE); button.setForeground(Color.WHITE);
break; }
case WHITE: case WHITE -> {
button.setBackground(Color.WHITE); button.setBackground(Color.WHITE);
button.setText(String.valueOf(cell.getNumber()));
button.setForeground(Color.BLACK); button.setForeground(Color.BLACK);
break; }
} }
} }
@ -177,25 +203,14 @@ public class GameBoard extends JPanel {
stateManager.saveState(board.getNumbers()); stateManager.saveState(board.getNumbers());
} }
private void addHighscore() { private void addHighscore(int elapsedTime, String boardName) {
String playerName = JOptionPane.showInputDialog(this, String playerName = JOptionPane.showInputDialog(this,
"Bitte geben Sie Ihren Namen ein:", "Neuer Highscore! Bitte Namen eingeben:",
"Highscore speichern", "Highscore speichern",
JOptionPane.PLAIN_MESSAGE); JOptionPane.PLAIN_MESSAGE);
if (playerName == null || playerName.trim().isEmpty()) { if (playerName == null || playerName.trim().isEmpty()) return;
JOptionPane.showMessageDialog(this,
"Highscore wurde nicht gespeichert. Kein Name eingegeben.",
"Info",
JOptionPane.INFORMATION_MESSAGE);
return;
}
int elapsedTime = (int) ((System.currentTimeMillis() - startTime) / 1000);
String boardName = board.getBoardName();
try {
HighscoreManager manager = new HighscoreManager(); HighscoreManager manager = new HighscoreManager();
manager.addHighscore(playerName, elapsedTime, boardName); manager.addHighscore(playerName, elapsedTime, boardName);
@ -203,14 +218,7 @@ public class GameBoard extends JPanel {
"Highscore erfolgreich gespeichert!", "Highscore erfolgreich gespeichert!",
"Erfolg", "Erfolg",
JOptionPane.INFORMATION_MESSAGE); JOptionPane.INFORMATION_MESSAGE);
} catch (Exception e) {
JOptionPane.showMessageDialog(this,
"Fehler beim Speichern des Highscores: " + e.getMessage(),
"Fehler",
JOptionPane.ERROR_MESSAGE);
} }
}
private void returnToMainMenu() { private void returnToMainMenu() {
/// Eltern-Frame abrufen /// Eltern-Frame abrufen
@ -240,10 +248,8 @@ public class GameBoard extends JPanel {
if (centerComponent != null) { if (centerComponent != null) {
remove(centerComponent); remove(centerComponent);
} }
// Neues Spielfeld hinzufügen // Neues Spielfeld hinzufügen
add(createGamePanel(), BorderLayout.CENTER); add(createGamePanel(), BorderLayout.CENTER);
// Kontroll-Buttons (SOUTH) entfernen und neu hinzufügen // Kontroll-Buttons (SOUTH) entfernen und neu hinzufügen
Component southComponent = layout.getLayoutComponent(BorderLayout.SOUTH); Component southComponent = layout.getLayoutComponent(BorderLayout.SOUTH);
if (southComponent != null) { if (southComponent != null) {
@ -251,7 +257,6 @@ public class GameBoard extends JPanel {
} }
add(createControlPanel(), BorderLayout.SOUTH); add(createControlPanel(), BorderLayout.SOUTH);
} }
// Oberfläche aktualisieren // Oberfläche aktualisieren
revalidate(); revalidate();
repaint(); repaint();

View File

@ -6,7 +6,9 @@ import PR2.HitoriSpiel.Utils.Setup;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
// aktueller Stand // aktueller Stand
public class HighscoreDialog extends JDialog { public class HighscoreDialog extends JDialog {
@ -16,11 +18,11 @@ public class HighscoreDialog extends JDialog {
public HighscoreDialog(JFrame parentFrame) { public HighscoreDialog(JFrame parentFrame) {
super(parentFrame, "Highscoreliste", true); super(parentFrame, "Highscoreliste", true);
this.highscoreManager = new HighscoreManager(); setSize(600, 400);
setLayout(new BorderLayout());
setSize(500, 400);
setLocationRelativeTo(parentFrame); setLocationRelativeTo(parentFrame);
this.highscoreManager = new HighscoreManager();
setLayout(new BorderLayout());
Setup.stylePanel((JPanel) getContentPane()); // Hintergrundfarbe setzen Setup.stylePanel((JPanel) getContentPane()); // Hintergrundfarbe setzen
JLabel titleLabel = new JLabel("Highscores", SwingConstants.CENTER); JLabel titleLabel = new JLabel("Highscores", SwingConstants.CENTER);
@ -28,7 +30,7 @@ public class HighscoreDialog extends JDialog {
Setup.styleLabel(titleLabel); // Schriftstil setzen Setup.styleLabel(titleLabel); // Schriftstil setzen
add(titleLabel, BorderLayout.NORTH); add(titleLabel, BorderLayout.NORTH);
String[] columnNames = {"Name", "Punkte", "Spielfeld"}; String[] columnNames = {"Platz", "Name", "Zeit (Sek.)", "Spielfeld"};
tableModel = new DefaultTableModel(columnNames, 0); tableModel = new DefaultTableModel(columnNames, 0);
JTable highscoreTable = new JTable(tableModel); JTable highscoreTable = new JTable(tableModel);
highscoreTable.setFillsViewportHeight(true); highscoreTable.setFillsViewportHeight(true);
@ -36,14 +38,34 @@ public class HighscoreDialog extends JDialog {
JScrollPane scrollPane = new JScrollPane(highscoreTable); JScrollPane scrollPane = new JScrollPane(highscoreTable);
add(scrollPane, BorderLayout.CENTER); add(scrollPane, BorderLayout.CENTER);
// Schließen-Button
JButton closeButton = Setup.createButton("Schließen", 120, 40);
closeButton.setFont(new Font(closeButton.getFont().getName(), closeButton.getFont().getStyle(), 14)); // Schriftgröße ändern
closeButton.addActionListener(e -> dispose());
JPanel buttonPanel = new JPanel(); JPanel buttonPanel = new JPanel();
Setup.stylePanel(buttonPanel); // Hintergrundstil setzen
// Schließen-Button
JButton closeButton = Setup.createButton("Schließen", 200, 40);
closeButton.setFont(new Font(closeButton.getFont().getName(), closeButton.getFont().getStyle(), 18)); // Schriftgröße ändern
closeButton.addActionListener(e -> dispose());
buttonPanel.add(closeButton); buttonPanel.add(closeButton);
// Button zum Löschen aller Einträge
JButton clearButton = Setup.createButton("Einträge löschen", 200, 40);
clearButton.setFont(new Font(closeButton.getFont().getName(), closeButton.getFont().getStyle(), 18));
clearButton.addActionListener(e -> {
int confirmation = JOptionPane.showConfirmDialog(
this,
"Möchten Sie wirklich alle Highscores löschen?",
"Highscores löschen",
JOptionPane.YES_NO_OPTION
);
if (confirmation == JOptionPane.YES_OPTION) {
highscoreManager.clearHighscores();
loadHighscores(); // Tabelle aktualisieren
JOptionPane.showMessageDialog(this, "Alle Highscores wurden gelöscht.");
}
});
buttonPanel.add(clearButton);
Setup.stylePanel(buttonPanel); // Hintergrundstil setzen
add(buttonPanel, BorderLayout.SOUTH); add(buttonPanel, BorderLayout.SOUTH);
// Highscores laden // Highscores laden
@ -54,13 +76,17 @@ public class HighscoreDialog extends JDialog {
tableModel.setRowCount(0); // Tabelle zurücksetzen tableModel.setRowCount(0); // Tabelle zurücksetzen
List<HighscoreManager.Highscore> highscores = highscoreManager.getHighscores(); List<HighscoreManager.Highscore> highscores = highscoreManager.getHighscores();
highscores.stream() highscores.sort(Comparator.comparingInt(HighscoreManager.Highscore::getScore)); // Sortierung: Kürzeste Zeit zuerst
.sorted((a, b) -> Integer.compare(b.getScore(), a.getScore())) // Sortierung: Höchste Punkte zuerst
.forEach(highscore -> tableModel.addRow(new Object[]{ int rank = 1; // Platznummer
highscore.getPlayerName(), for (HighscoreManager.Highscore highscore : highscores) {
highscore.getScore(), tableModel.addRow(new Object[]{
highscore.getBoardName() rank++, // Platznummer hochzählen
})); highscore.getPlayerName(), // Name des Spielers
highscore.getScore(), // Zeit in Sekunden
highscore.getBoardName() // Name des Spielfelds
});
}
} }
public void refreshHighscores() { public void refreshHighscores() {

View File

@ -19,17 +19,47 @@ public class HighscoreManager {
} }
// Highscore hinzufügen // Highscore hinzufügen
public synchronized void addHighscore(String playerName, int score, String boardName) { public synchronized void addHighscore(String playerName, int time, String boardName) {
fileLock.lock(); fileLock.lock();
try { try {
highscoreList.add(new Highscore(playerName, score, boardName)); // Prüfe, ob es bereits Highscores für das Spielfeld gibt
highscoreList.sort(Comparator.comparingInt(Highscore::getScore).reversed()); // Sortierung absteigend boolean isShorterTime = highscoreList.stream()
.filter(highscore -> highscore.getBoardName().equals(boardName))
.allMatch(highscore -> time < highscore.getScore());
if (isShorterTime) {
// Entferne alle Highscores für das Spielfeld, die länger oder gleich sind
highscoreList.removeIf(highscore -> highscore.getBoardName().equals(boardName));
// Füge den neuen Highscore hinzu
highscoreList.add(new Highscore(playerName, time, boardName));
// Sortiere die Liste
highscoreList.sort(Comparator.comparingInt(Highscore::getScore)); // Kürzeste Zeit zuerst
saveHighscores(); saveHighscores();
} else {
System.out.println("Neuer Highscore ist nicht kürzer als die bestehenden Einträge.");
}
} finally { } finally {
fileLock.unlock(); fileLock.unlock();
} }
} }
// Neue Methode: Überprüfung, ob ein neuer Highscore erreicht wurde
public boolean isNewHighscore(int elapsedTime, String boardName) {
List<Highscore> highscores = getHighscores();
// Prüfen, ob das Board bereits einen Highscore-Eintrag hat
for (Highscore highscore : highscores) {
if (highscore.getBoardName().equals(boardName)) {
return elapsedTime < highscore.getScore(); // Neuer Highscore, wenn Zeit besser ist
}
}
// Wenn das Board keinen Highscore hat, ist dies der erste Eintrag
return true;
}
// Highscores laden // Highscores laden
private void loadHighscores() { private void loadHighscores() {
fileLock.lock(); fileLock.lock();
@ -68,17 +98,15 @@ public class HighscoreManager {
// Highscores abrufen // Highscores abrufen
public List<Highscore> getHighscores() { public List<Highscore> getHighscores() {
return Collections.unmodifiableList(highscoreList); return new ArrayList<>(highscoreList); // Modifizierbare Kopie zurückgeben
} }
// Alte Highscores bereinigen // Löscht alle Highscores
public void cleanOldHighscores(int maxEntries) { public void clearHighscores() {
fileLock.lock(); fileLock.lock();
try { try {
if (highscoreList.size() > maxEntries) { highscoreList.clear(); // Liste leeren
highscoreList.subList(maxEntries, highscoreList.size()).clear(); saveHighscores(); // Datei aktualisieren
saveHighscores();
}
} finally { } finally {
fileLock.unlock(); fileLock.unlock();
} }
@ -107,7 +135,7 @@ public class HighscoreManager {
public String getBoardName() { public String getBoardName() {
return boardName; return boardName;
} }
} }
} }

View File

@ -1,3 +1 @@
Name, Zeit (Sekunden), Spielfeld ame, Zeit (Sekunden), Spielfeld
NameTest, 123 Sekunden, Hitori4x4_leicht.csv