Compare commits

...

3 Commits

6 changed files with 346 additions and 28 deletions

View File

@ -0,0 +1,43 @@
package PR2.HitoriSpiel.Domain;
import java.util.List;
/**
* Represents the Hitori game board.
*/
public class HitoriBoard {
private final HitoriCell[][] board;
private final List<String> solutionCoordinates;
public HitoriBoard(int[][] numbers, List<String> solutionCoordinates) {
this.board = new HitoriCell[numbers.length][numbers[0].length];
this.solutionCoordinates = solutionCoordinates;
initializeBoard(numbers);
}
private void initializeBoard(int[][] numbers){
for (int i = 0; i < numbers.length; i++) {
for (int j = 0; j < numbers[i].length; j++) {
board[i][j] = new HitoriCell(numbers[i][j]);
}
}
}
public HitoriCell getCell(int row, int col) {
return board[row][col];
}
public int getSize(){
return board.length;
}
//Board zurücksetzen zu dem Anfangszustand
public void resetBoard(){
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j].setState(HitoriCell.CellState.GRAY);
}
}
}
}

View File

@ -0,0 +1,32 @@
package PR2.HitoriSpiel.Domain;
/**
* Represents a single cell on the Hitori board.
*/
public class HitoriCell {
public enum CellState {
GRAY, WHITE, BLACK
}
private final int number;
private CellState state;
public HitoriCell(int number) {
this.number = number;
this.state = CellState.GRAY;
}
public int getNumber() {
return number;
}
public CellState getState() {
return state;
}
public void setState(CellState state) {
this.state = state;
}
}

View File

@ -0,0 +1,27 @@
package PR2.HitoriSpiel.Domain;
import java.io.*;
import java.util.*;
/**
* Utility class to load the solution from a CSV file.
*/
public class HitoriSolutionLoader {
/**
* Loads solution coordinates from a CSV file.
* @param filePath The path to the CSV file containing solution coordinates.
* @return A list of "row,column" formatted solution coordinates.
* @throws IOException If the file cannot be read.
*/
public static List<String> loadSolution(String filePath) throws IOException {
List<String> solutionCoordinates = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
solutionCoordinates.add(line.trim());
}
}
return solutionCoordinates;
}
}

View File

@ -0,0 +1,46 @@
package PR2.HitoriSpiel.Domain;
import java.util.List;
/**
* Validates the Hitori board against the solution.
*/
public class HitoriValidator {
private final HitoriBoard board;
public HitoriValidator(HitoriBoard board) {
this.board = board;
}
/**
* Validates the current board against the solution.
* @param solutionCoordinates The coordinates of the correct black cells in "row,column" format.
* @return true if the current board matches the solution, false otherwise.
*/
public boolean validateBoard(List<String> solutionCoordinates) {
for (String coordinate : solutionCoordinates) {
String[] parts = coordinate.split(",");
int row = Integer.parseInt(parts[0]);
int col = Integer.parseInt(parts[1]);
if (board.getCell(row,col).getState() != HitoriCell.CellState.BLACK){
return false;
}
}
for (int i = 0; i < board.getSize(); i++) {
for (int j = 0; j < board.getSize(); j++) {
if (board.getCell(i,j).getState() == HitoriCell.CellState.BLACK &&
!solutionCoordinates.contains(i + "," + j)) {
return false;
}
}
}
return true;
}
}

View File

@ -1,52 +1,139 @@
package PR2.HitoriSpiel.GUI;
package GUI;
import domain.HitoriBoard;
import persistent.BoardLoader;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.InputStream;
import java.util.List;
public class StartMenu extends JPanel {
public class StartMenu extends JFrame {
private JPanel mainPanel;
public StartMenu() {
setTitle("Hitori - Hauptmenü");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 400);
mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = GridBagConstraints.RELATIVE;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.anchor = GridBagConstraints.CENTER; // Buttons zentrieren
JLabel titleLabel = new JLabel("Willkommen im Hitori-Spiel!");
titleLabel.setFont(new Font("Arial", Font.BOLD, 16));
titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
mainPanel.add(titleLabel, gbc);
public StartMenu(JFrame parentFrame) {
// Layout auf FlowLayout setzen
this.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10)); // Zentriert mit Abständen
// Buttons erstellen
JButton continueButton = createButton("Spiel fortsetzen", 200, 30);
JButton selectBoardButton = createButton("Spielfeld aussuchen", 200, 30);
JButton randomBoardButton = createButton("Zufälliges Spielfeld", 200, 30);
JButton highscorelistButton = createButton("Highscoreliste anzeigen", 200, 30);
JButton highscorelistButton = createButton("Highscoreliste anschauen", 200, 30);
JButton exitButton = createButton("Spiel beenden", 200, 30);
// Namen für AssertJ-Swing setzen
continueButton.setName("continueButton");
selectBoardButton.setName("selectBoardButton");
randomBoardButton.setName("randomBoardButton");
highscorelistButton.setName("highscorelistButton");
exitButton.setName("exitButton");
// ActionListener hinzufügen
continueButton.addActionListener(e -> showMessage("Spiel fortsetzen wird implementiert."));
selectBoardButton.addActionListener(e -> showMessage("Spielfeld auswählen wird implementiert."));
randomBoardButton.addActionListener(e -> showMessage("Zufälliges Spielfeld wird gestartet."));
highscorelistButton.addActionListener(e -> showMessage("Highscore-Liste wird angezeigt."));
mainPanel.add(continueButton, gbc);
mainPanel.add(selectBoardButton, gbc);
mainPanel.add(randomBoardButton, gbc);
mainPanel.add(highscorelistButton, gbc);
mainPanel.add(exitButton, gbc);
continueButton.addActionListener(e -> continueGame());
selectBoardButton.addActionListener(e -> selectBoard());
randomBoardButton.addActionListener(e -> randomBoard());
highscorelistButton.addActionListener(e -> highscorelist());
exitButton.addActionListener(e -> System.exit(0));
// Buttons zum Panel hinzufügen
this.add(continueButton);
this.add(selectBoardButton);
this.add(randomBoardButton);
this.add(highscorelistButton);
this.add(exitButton);
add(mainPanel);
setVisible(true);
setLocationRelativeTo(null);
}
// Methode zum Anzeigen von Nachrichten
private void showMessage(String message) {
JOptionPane.showMessageDialog(this, message, "Info", JOptionPane.INFORMATION_MESSAGE);
private void continueGame() {
// TODO: Logik zum Fortsetzen des Spiels implementieren
JOptionPane.showMessageDialog(this, "Spiel fortsetzen wurde angeklickt");
}
// Methode zum Erstellen von Buttons mit fester Größe
private void selectBoard() {
// Lade die Liste der Spielfeld-Dateien
List<String> boardFileNames = BoardLoader.loadBoardsAsList();
if (boardFileNames.isEmpty()) {
JOptionPane.showMessageDialog(this, "Keine Spielfelder gefunden.", "Information", JOptionPane.INFORMATION_MESSAGE);
return;
}
// Erstelle die JComboBox
JComboBox<String> boardSelector = new JComboBox<>(boardFileNames.toArray(new String[0]));
boardSelector.setPreferredSize(new Dimension(250, 30)); // Größe der ComboBox anpassen
JPanel selectionPanel = new JPanel(new BorderLayout());
selectionPanel.add(new JLabel("Wähle ein Spielfeld:"), BorderLayout.NORTH);
selectionPanel.add(boardSelector, BorderLayout.CENTER);
// Zeige das Auswahlfenster
int option = JOptionPane.showConfirmDialog(
this,
selectionPanel,
"Spielfeld auswählen",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
);
// Aktion, wenn der Benutzer auf OK klickt
if (option == JOptionPane.OK_OPTION) {
String selectedFile = (String) boardSelector.getSelectedItem();
if (selectedFile != null) {
try {
InputStream inputStream = BoardLoader.class.getResourceAsStream("/persistent/Hitori_Spielfelder/" + selectedFile);
if (inputStream == null) {
throw new Exception("Ressourcendatei nicht gefunden: /persistent/Hitori_Spielfelder/" + selectedFile);
}
// Lade das ausgewählte Spielfeld
int[][] boardData = BoardLoader.loadBoard("/persistent/Hitori_Spielfelder/" + selectedFile);
loadGameBoard(boardData); // Zeige das Spielfeld an
} catch (Exception ex) {
JOptionPane.showMessageDialog(this, "Fehler beim Laden des Spielfelds: " + ex.getMessage(), "Fehler", JOptionPane.ERROR_MESSAGE);
}
}
}
}
private void randomBoard() {
// TODO: Logik zum Auswählen eines zufälligen Spielfeldes implementieren
JOptionPane.showMessageDialog(this, "Zufälliges Spielfeld wurde angeklickt");
}
private void highscorelist() {
// TODO: Logik zur Anzeige der Highscoreliste implementieren
JOptionPane.showMessageDialog(this, "Highscoreliste wurde angeklickt");
}
// Hilfsmethoden
private JButton createButton(String text, int width, int height) {
JButton button = new JButton(text);
button.setPreferredSize(new Dimension(width, height)); // Feste Größe setzen
button.setPreferredSize(new Dimension(width, height));
return button;
}
private void loadGameBoard(int[][] boardData) {
// Neues Panel für das Spielfeld
mainPanel.removeAll();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(new GameBoard(new HitoriBoard(boardData, List.of())), BorderLayout.CENTER);
mainPanel.revalidate();
mainPanel.repaint();
}
}

View File

@ -0,0 +1,83 @@
7,1,2,9,12,15,8,11,11,9,11,14,13,6,3
2,3,8,1,2,11,10,9,5,8,14,3,12,13,15
4,14,13,9,4,15,9,10,12,6,5,3,11,5,12
15,9,5,6,10,15,1,15,8,3,5,4,6,2,8
5,11,7,9,15,1,4,3,8,1,9,2,10,13,2
15,15,10,3,1,14,8,12,11,1,9,8,2,7,2
10,7,7,12,9,3,15,2,5,2,10,5,1,7,4
3,8,9,14,1,6,12,4,15,2,13,11,5,10,11
8,6,7,15,11,4,5,11,2,10,3,13,8,12,9
2,2,3,3,4,13,5,6,5,11,5,15,8,9,12
2,15,15,11,13,7,6,5,3,13,8,10,5,1,11
12,5,11,13,13,2,2,8,8,4,10,9,3,2,5
1,13,8,2,1,7,11,4,9,15,4,12,9,3,10
13,10,12,5,15,3,2,7,13,14,12,12,9,11,6
7,12,4,8,14,10,13,13,7,4,2,6,15,15,11
//Lösung
1,4
1,6
1,8
1,11
2,1
2,3
2,9
2,12
2,14
3,5
3,7
3,11
3,15
4,1
4,3
4,6
4,9
4,13
5,4
5,10
5,15
6,2
6,5
6,7
6,9
6,11
6,13
7,1
7,3
7,6
7,8
7,12
7,14
8,5
8,9
8,15
9,3
9,8
9,13
10,1
10,4
10,7
10,9
10,11
11,3
11,10
11,13
11,15
12,2
12,5
12,7
12,9
12,11
12,14
13,1
13,6
13,8
13,13
14,3
14,5
14,9
14,12
15,1
15,7
15,10
15,14
Can't render this file because it has a wrong number of fields in line 17.