Update der main mit den von mir veränderten Daten nach Teamgespräch #2
|
@ -2,6 +2,7 @@ package de.deversmann;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println("Hello, World!");
|
de.deversmann.gui.HitoriApp app = new de.deversmann.gui.HitoriApp();
|
||||||
|
app.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,72 +4,17 @@ import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class HighscoreManager {
|
public class HighscoreManager {
|
||||||
private final Map<String, List<HighscoreEntry>> highscoreMap;
|
private List<Integer> highscores
|
||||||
|
|
||||||
public HighscoreManager() {
|
public HighscoreManager() {
|
||||||
highscoreMap = new HashMap<>();
|
this.highscores = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addHighscore(String spielfeld, String name, long zeit, int fehler) {
|
public void addHighscore(int score) {
|
||||||
HighscoreEntry entry = new HighscoreEntry(name, zeit, fehler);
|
highscores.add(score);
|
||||||
highscoreMap.computeIfAbsent(spielfeld, k -> new ArrayList<>()).add(entry);
|
|
||||||
saveHighscores();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<HighscoreEntry> getHighscores(String spielfeld) {
|
public List<Integer> getHighscores() {
|
||||||
return highscoreMap.getOrDefault(spielfeld, new ArrayList<>());
|
return new ArrayList<>(highscores);
|
||||||
}
|
|
||||||
|
|
||||||
public double getDurchschnittszeit(String spielfeld) {
|
|
||||||
List<HighscoreEntry> highscores = getHighscores(spielfeld);
|
|
||||||
return highscores.stream().mapToLong(HighscoreEntry::getZeit).average().orElse(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void saveHighscores() {
|
|
||||||
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("highscores.dat"))) {
|
|
||||||
oos.writeObject(highscoreMap);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println("Fehler beim Speichern der Highscores: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void loadHighscores() {
|
|
||||||
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("highscores.dat"))) {
|
|
||||||
Map<String, List<HighscoreEntry>> loadedMap = (Map<String, List<HighscoreEntry>>) ois.readObject();
|
|
||||||
highscoreMap.clear();
|
|
||||||
highscoreMap.putAll(loadedMap);
|
|
||||||
} catch (IOException | ClassNotFoundException e) {
|
|
||||||
System.err.println("Fehler beim Laden der Highscores: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,41 +1,37 @@
|
||||||
package de.deversmann.domain;
|
package de.deversmann.domain;
|
||||||
|
|
||||||
public class Zeiterfassung {
|
public class Zeiterfassung {
|
||||||
private long startzeit;
|
|
||||||
private long endzeit;
|
private long startTime;
|
||||||
private boolean laufen;
|
private long endTime;
|
||||||
|
private boolean isRunning;
|
||||||
|
|
||||||
|
public Zeiterfassung() {
|
||||||
|
this.isRunning = false;
|
||||||
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
this.startzeit = System.currentTimeMillis();
|
if (!isRunning) {
|
||||||
this.laufen= true;
|
startTime = System.currentTimeMillis();
|
||||||
|
isRunning = true;
|
||||||
|
System.out.println("Zeiterfassung gestartet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
this.endzeit = System.currentTimeMillis();
|
if (isRunning) {
|
||||||
this.laufen= false;
|
endTime = System.currentTimeMillis();
|
||||||
|
isRunning = false;
|
||||||
|
System.out.println("Zeiterfassung gestoppt, diff=" + getElapsedTimeInSeconds() + "s");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getElapsedTimeMillis() {
|
public long getElapsedTimeInSeconds() {
|
||||||
long endTime = laufen ? System.currentTimeMillis() : endzeit;
|
if (isRunning) {
|
||||||
return endTime - startzeit;
|
long current = System.currentTimeMillis();
|
||||||
}
|
return (current - startTime) / 1000;
|
||||||
|
} else {
|
||||||
public void reset() {
|
return (endTime - startTime) / 1000;
|
||||||
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,4 +1,235 @@
|
||||||
package de.deversmann.gui;
|
package de.deversmann.gui;
|
||||||
|
|
||||||
public class GameView {
|
import de.deversmann.facade.Facade;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class GameView extends JFrame {
|
||||||
|
|
||||||
|
private final Facade facade;
|
||||||
|
private SpielfeldGUI spielfeldGUI;
|
||||||
|
|
||||||
|
private JComboBox<String> cbSpielfelder;
|
||||||
|
private JButton btnLoad;
|
||||||
|
private JButton btnRandom;
|
||||||
|
private JButton btnCheckSolution;
|
||||||
|
private JButton btnShowSolution;
|
||||||
|
private JButton btnReset;
|
||||||
|
private JLabel timeLabel;
|
||||||
|
private 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetField() {
|
||||||
|
var feld = facade.getAktuellesPuzzle();
|
||||||
|
if (feld != null) {
|
||||||
|
spielfeldGUI.updateGrid(feld);
|
||||||
|
timeLabel.setText("Time: 0s");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,18 @@
|
||||||
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,97 +1,136 @@
|
||||||
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 {
|
public class SpielfeldGUI extends JPanel {
|
||||||
|
|
||||||
private JFrame frame;
|
private JLabel[][] grid;
|
||||||
private JPanel spielfeldPanel;
|
private Set<String> errorCells = new HashSet<>();
|
||||||
private JLabel timerLabel;
|
|
||||||
private Timer guiTimer;
|
|
||||||
private Spielfeld spielfeld;
|
|
||||||
private Zeiterfassung timer;
|
|
||||||
|
|
||||||
public SpielfeldGUI() {
|
public SpielfeldGUI(int rows, int cols) {
|
||||||
// Initialisiere Domain-Klassen
|
setLayout(new GridLayout(rows, cols));
|
||||||
spielfeld = new Spielfeld();
|
grid = new JLabel[rows][cols];
|
||||||
timer = new Zeiterfassung();
|
|
||||||
|
|
||||||
// Erstelle das Hauptfenster
|
for (int r = 0; r < rows; r++) {
|
||||||
frame = new JFrame("Hitori Spielfeld");
|
for (int c = 0; c < cols; c++) {
|
||||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
JLabel label = createCellLabel("-", r, c);
|
||||||
frame.setSize(800, 600);
|
grid[r][c] = label;
|
||||||
frame.setLayout(new BorderLayout());
|
add(label);
|
||||||
|
}
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void starteTimer() {
|
public void updateGrid(int[][] feld) {
|
||||||
timer.start();
|
if (feld == null) {
|
||||||
guiTimer.start();
|
return;
|
||||||
|
}
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void stoppeTimer() {
|
public void setAllNonBlackToWhite() {
|
||||||
timer.stop();
|
if (grid == null) return;
|
||||||
guiTimer.stop();
|
for (int r = 0; r < grid.length; r++) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ladeSpielfeldMitAuswahl() {
|
public void markCellAsError(int row, int col) {
|
||||||
|
if (!isValidCell(row, col)) return;
|
||||||
|
errorCells.add(row + "," + col);
|
||||||
|
grid[row][col].setBorder(BorderFactory.createLineBorder(Color.RED, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void zeigeSpielfeld() {
|
public void clearErrorMark(int row, int col) {
|
||||||
|
errorCells.remove(row + "," + col);
|
||||||
|
if (!isValidCell(row, col)) return;
|
||||||
|
grid[row][col].setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void feldAktion(int x, int y, JButton button) {
|
public List<int[]> getBlackCells() {
|
||||||
String aktuellerZustand = spielfeld.getZustand(x, y);
|
List<int[]> black = new ArrayList<>();
|
||||||
String neuerZustand = switch (aktuellerZustand) {
|
if (grid == null) return black;
|
||||||
case "grau" -> "schwarz";
|
|
||||||
case "schwarz" -> "weiß";
|
for (int r = 0; r < grid.length; r++) {
|
||||||
default -> "grau";
|
for (int c = 0; c < grid[r].length; c++) {
|
||||||
};
|
JLabel lbl = grid[r][c];
|
||||||
spielfeld.setzeZustand(x, y, neuerZustand);
|
if (lbl != null && lbl.getBackground().equals(Color.BLACK)) {
|
||||||
button.setBackground(switch (neuerZustand) {
|
black.add(new int[]{r, c});
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
private void toggleColor(JLabel label, int row, int col) {
|
||||||
SwingUtilities.invokeLater(SpielfeldGUI::new);
|
if (label.getBackground().equals(Color.GRAY) || label.getBackground().equals(Color.WHITE)) {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue