From ff2448dc8605b69a46b44ba9360003ef7d593a01 Mon Sep 17 00:00:00 2001 From: stiti Date: Tue, 16 Apr 2024 22:39:23 +0200 Subject: [PATCH] =?UTF-8?q?PeerWorking=20:=20Correction=20de=20bugs=20+=20?= =?UTF-8?q?Refonte=20totale=20du=20syst=C3=A8me=20de=20cr=C3=A9ation=20de?= =?UTF-8?q?=20grille?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/.DS_Store | Bin 0 -> 6148 bytes src/FileManager.java | 88 ------------- src/GridMakeUserInterfaceView.java | 75 +++++++++++ src/GridMakerCase.java | 61 +++++++++ src/GridMakerChecker.java | 137 +++++++++++++++++++++ src/GridMakerGrid.java | 122 ++++++++++++++++++ src/GridMakerHowToCreateController.java | 30 +++++ src/GridMakerHowToCreateDialogManager.java | 21 ++++ src/GridMakerHowToCreateView.java | 52 ++++++++ src/GridMakerImport.java | 87 +++++++++++++ src/GridMakerResetGrid.java | 48 ++++++++ src/GridMakerRules.java | 14 +++ src/GridMakerSaver.java | 84 +++++++++++++ src/Grille.java | 52 -------- src/GrilleButtonClickListener.java | 25 ---- src/GrilleView.java | 69 ----------- src/HomeView.java | 2 +- src/PlayButtonClickListener.java | 41 +----- src/PlayMenuView.java | 8 +- src/RulesSudoku.java | 8 +- src/SudokuGenerator.java | 99 --------------- src/SudokuSolver.java | 40 ------ src/Window.java | 6 + 23 files changed, 750 insertions(+), 419 deletions(-) create mode 100644 src/.DS_Store delete mode 100644 src/FileManager.java create mode 100755 src/GridMakeUserInterfaceView.java create mode 100755 src/GridMakerCase.java create mode 100755 src/GridMakerChecker.java create mode 100755 src/GridMakerGrid.java create mode 100755 src/GridMakerHowToCreateController.java create mode 100644 src/GridMakerHowToCreateDialogManager.java create mode 100644 src/GridMakerHowToCreateView.java create mode 100755 src/GridMakerImport.java create mode 100755 src/GridMakerResetGrid.java create mode 100755 src/GridMakerRules.java create mode 100755 src/GridMakerSaver.java delete mode 100644 src/Grille.java delete mode 100644 src/GrilleButtonClickListener.java delete mode 100644 src/GrilleView.java delete mode 100644 src/SudokuGenerator.java delete mode 100644 src/SudokuSolver.java diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0= 0 && num <= 9) { + setCellValue(num); + } + } + } + + @Override + public void keyReleased(KeyEvent e) { + // Pas de traitement nécessaire + } + + @Override + public void keyTyped(KeyEvent e) { + // Pas de traitement nécessaire + } + + public void updateDisplay() { + actionButton.setText(displayText.isEmpty() ? "" : displayText); + revalidate(); + repaint(); + } + + public void setCellValue(int value) { + this.cellValue = value; + this.displayText = (value == 0) ? "" : String.valueOf(value); // Mettre à jour avec une chaîne vide si la valeur est 0 + updateDisplay(); + } + + public int getCellValue() { + return this.cellValue; + } +} diff --git a/src/GridMakerChecker.java b/src/GridMakerChecker.java new file mode 100755 index 0000000..ab454dd --- /dev/null +++ b/src/GridMakerChecker.java @@ -0,0 +1,137 @@ +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; + +/** + * La classe GridMakerChecker est utilisée pour vérifier la cohérence de la grille. + * Elle vérifie si les lignes, les colonnes et les régions de la grille respectent les règles du jeu. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerChecker implements ActionListener { + + private GridMakerGrid grid; + + /** + * Constructeur pour créer une instance de GridMakerChecker. + * @param grid La grille à vérifier + */ + public GridMakerChecker(GridMakerGrid grid) { + this.grid = grid; + } + + /** + * Méthode invoquée lorsqu'un bouton est cliqué. + * Lance la vérification de la grille. + * @param e L'événement d'action + */ + public void actionPerformed(ActionEvent e) { + checkGrid(); + } + + /** + * Vérifie si la grille est correcte. + * @return true si la grille est correcte, false sinon + */ + public boolean checkGrid() { + if (checkRows() || checkColumns() || checkRegions()) { + showMessage("Grille incorrecte !", "Deux mêmes chiffres sont présents dans la même ligne/colonne/région. Veuillez modifier votre grille !"); + return false; + } else { + showMessage("Grille cohérente !", "Votre grille est cohérente. Aucune erreur n'a été trouvée. Vous pouvez maintenant sauvegarder votre grille !"); + return true; + } + } + + /** + * Affiche un message d'information. + * @param title Le titre du message + * @param message Le contenu du message + */ + private void showMessage(String title, String message) { + JOptionPane.showMessageDialog(null, message, title, JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Vérifie les lignes de la grille. + * @return true si une ligne contient des doublons, false sinon + */ + private boolean checkRows() { + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + for (int j_prime = j + 1; j_prime < 9; j_prime++) { + if (grid.getCellValueAt(i, j) == grid.getCellValueAt(i, j_prime) && grid.getCellValueAt(i, j) != 0) { + return true; + } + } + } + } + return false; + } + + /** + * Vérifie les colonnes de la grille. + * @return true si une colonne contient des doublons, false sinon + */ + private boolean checkColumns() { + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + for (int i_prime = i + 1; i_prime < 9; i_prime++) { + if (grid.getCellValueAt(i, j) == grid.getCellValueAt(i_prime, j) && grid.getCellValueAt(i, j) != 0) { + return true; + } + } + } + } + return false; + } + + /** + * Vérifie les régions de la grille. + * @return true si une région contient des doublons, false sinon + */ + private boolean checkRegions() { + for (int i = 0; i < 9; i += 3) { + for (int j = 0; j < 9; j += 3) { + if (checkRegion(i, j)) { + return true; + } + } + } + return false; + } + + /** + * Vérifie une région de la grille. + * @param x La coordonnée x de la région + * @param y La coordonnée y de la région + * @return true si la région contient des doublons, false sinon + */ + private boolean checkRegion(int x, int y) { + int[] regionValues = new int[9]; + int index = 0; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + regionValues[index++] = grid.getCellValueAt(x + i, y + j); + } + } + + for (int i = 0; i < 9; i++) { + for (int j = i + 1; j < 9; j++) { + if (regionValues[i] == regionValues[j] && regionValues[i] != 0) { + return true; + } + } + } + return false; + } + + /** + * Vérifie si la grille est correcte. + * @return true si la grille est correcte, false sinon + */ + public boolean isCorrect() { + return checkGrid(); + } +} diff --git a/src/GridMakerGrid.java b/src/GridMakerGrid.java new file mode 100755 index 0000000..2b85681 --- /dev/null +++ b/src/GridMakerGrid.java @@ -0,0 +1,122 @@ +import javax.swing.*; +import java.awt.*; +import javax.swing.border.EmptyBorder; +import java.awt.Color; + + +/** + * A custom JPanel class representing a Sudoku grid. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerGrid extends JPanel { + + private int[][] gridValues = new int[9][9]; // Stores the values of each cell in the grid + private GridMakerCase[][] gridCases = new GridMakerCase[9][9]; // Represents the individual cells in the grid + private int[] exportedGrid = new int[9]; // Stores the grid values in an exportable format + + /** + * Constructs a new GridMakerGrid object and initializes the grid. + */ + public GridMakerGrid() { + setupGrid(); + setBackground(new Color(54, 91, 109)); // On change la couleur de fond (les cotés de la grille) + } + + /** + * Sets up the layout of the Sudoku grid. + */ + private void setupGrid() { + // Add padding around the panel + setBorder(new EmptyBorder(15, 15, 15, 15)); // Adjust the values as needed for desired padding + + setLayout(new GridLayout(3, 3)); // Set layout for the main grid panel + + // Create 9 zones of 3x3 + JPanel[][] zones = new JPanel[3][3]; + setLayout(new GridLayout(3, 3)); + + // Create individual zones and add them to the main grid panel + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + zones[i][j] = new JPanel(); + zones[i][j].setLayout(new GridLayout(3, 3)); + add(zones[i][j]); + } + } + + // Create and add cells to each zone + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 9; j++) { + int zoneRow = i / 3; + int zoneCol = j / 3; + gridCases[i][j] = new GridMakerCase(); + zones[zoneRow][zoneCol].add(gridCases[i][j]); + + // Add borders to cells based on their position in the grid + if ((i + 1) % 3 == 0 && (j + 1) % 3 == 0) { + gridCases[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 5, 5, Color.BLACK)); + } else if ((i + 1) % 3 == 0) { + gridCases[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 5, 1, Color.BLACK)); + } else if ((j + 1) % 3 == 0) { + gridCases[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 1, 5, Color.BLACK)); + } else { + gridCases[i][j].setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK)); + } + } + } + } + + /** + * Imports values to populate the Sudoku grid. + * + * @param values An array of integers representing the Sudoku grid values. + */ + public void importGrid(int[] values) { + for (int i = 0; i < 9; i++) { + int length = String.valueOf(values[i]).length(); + + for (int j = 0; j < 9 - length; j++) { + gridValues[i][j] = 0; + gridCases[i][j].setCellValue(gridValues[i][j]); + } + + String str = Integer.toString(values[i]); + for (int j = 9 - length, k = 0; j < 9; j++, k++) { + gridValues[i][j] = Character.getNumericValue(str.charAt(k)); + gridCases[i][j].setCellValue(gridValues[i][j]); + } + } + } + + /** + * Exports the current Sudoku grid values. + * + * @return An array of integers representing the current Sudoku grid values. + */ + public int[] exportGrid() { + for (int i = 0; i < 9; i++) { + StringBuilder temp = new StringBuilder(); + + for (int j = 0; j < 9; j++) { + temp.append(gridCases[i][j].getCellValue()); + } + + exportedGrid[i] = Integer.parseInt(temp.toString()); + } + + return exportedGrid; + } + + /** + * Retrieves the value of a cell in the Sudoku grid. + * + * @param row The row index of the cell. + * @param column The column index of the cell. + * @return The value of the cell at the specified row and column indices. + */ + public int getCellValueAt(int row, int column) { + return gridCases[row][column].getCellValue(); + } +} diff --git a/src/GridMakerHowToCreateController.java b/src/GridMakerHowToCreateController.java new file mode 100755 index 0000000..528e098 --- /dev/null +++ b/src/GridMakerHowToCreateController.java @@ -0,0 +1,30 @@ +import java.awt.event.*; + +/** + * La classe GridMakerHowToCreateController est un contrôleur qui gère l'affichage de la fenêtre de création de grille. + * Elle implémente l'interface ActionListener pour réagir aux événements de clic sur un bouton. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerHowToCreateController implements ActionListener { + private GridMakerHowToCreateDialogManager howToCreateGrid; + + /** + * Constructeur pour créer une instance de GridMakerHowToCreateController. + * Initialise le gestionnaire de dialogue pour la création de grille. + */ + public GridMakerHowToCreateController(){ + this.howToCreateGrid = new GridMakerHowToCreateDialogManager(); + } + + /** + * Méthode invoquée lorsqu'un événement d'action est déclenché, comme un clic sur un bouton. + * Affiche la fenêtre de dialogue pour expliquer comment créer une grille. + * @param e L'événement d'action + */ + @Override + public void actionPerformed(ActionEvent e) { + howToCreateGrid.showDialog(); // On appelle la méthode qui affiche la fenêtre de dialogue + } +} diff --git a/src/GridMakerHowToCreateDialogManager.java b/src/GridMakerHowToCreateDialogManager.java new file mode 100644 index 0000000..75bf957 --- /dev/null +++ b/src/GridMakerHowToCreateDialogManager.java @@ -0,0 +1,21 @@ +import javax.swing.JOptionPane; + +/** + * La classe GridMakerHowToCreateDialogManager est un gestionnaire de dialogue qui affiche des instructions + * sur la manière de créer une grille dans une boîte de dialogue. + * Elle implémente l'interface DialogManager. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerHowToCreateDialogManager implements DialogManager { + + /** + * Méthode pour afficher la boîte de dialogue avec les instructions de création de grille. + */ + @Override + public void showDialog() { + GridMakerHowToCreateView howToCreateGrid = new GridMakerHowToCreateView(); + JOptionPane.showMessageDialog(null, howToCreateGrid, "Comment créer une grille ?", JOptionPane.PLAIN_MESSAGE); + } +} diff --git a/src/GridMakerHowToCreateView.java b/src/GridMakerHowToCreateView.java new file mode 100644 index 0000000..4bb93a4 --- /dev/null +++ b/src/GridMakerHowToCreateView.java @@ -0,0 +1,52 @@ +import javax.swing.*; +import java.awt.*; + +/** + * La classe GridMakerHowToCreateView est une vue qui affiche les instructions pour créer une grille dans une boîte de dialogue. + * Elle hérite de JPanel pour servir de composant d'interface utilisateur. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerHowToCreateView extends JPanel { + private Dimension FRAME_SIZE = new Dimension(600, 500); + private Color BACKGROUND_COLOR = new Color(54, 91, 109); + + private String TITLE = "Comment créer une grille"; + private Color TITLE_COLOR = new Color(255, 255, 255); + private Font TITLE_FONT = new Font("Copperplate", Font.BOLD, 40); + + private String TEXT = "Comment créer une grille :\n\n 1. EXPLICATION \n\n 2. EXPLICATION\n\n 3. EXPLICATION.\n\n 4. EXPLICATION"; + private Color TEXT_COLOR = new Color(255, 255, 255); + private Font TEXT_FONT = new Font("Arial", Font.PLAIN, 20); + + /** + * Constructeur pour créer une instance de GridMakerHowToCreateView. + * Initialise les composants de la vue et les dispose selon un BorderLayout. + */ + public GridMakerHowToCreateView() { + BorderLayout borderLayout = new BorderLayout(); + this.setLayout(borderLayout); + this.setBackground(this.BACKGROUND_COLOR); // Définit la couleur d'arrière-plan du panneau + + JLabel titleLabel = new JLabel(this.TITLE); + titleLabel.setFont(this.TITLE_FONT); // Définit la police du titre + titleLabel.setForeground(this.TITLE_COLOR); // Définit la couleur du titre + + JTextArea textArea = new JTextArea(); + textArea.setText(this.TEXT); + textArea.setEditable(false); + textArea.setLineWrap(true); + textArea.setWrapStyleWord(true); + textArea.setFont(this.TEXT_FONT); // Définit la police du texte + textArea.setForeground(this.TEXT_COLOR); // Définit la couleur du texte + textArea.setBackground(this.BACKGROUND_COLOR); // Définit la couleur d'arrière-plan du texte + + JScrollPane scrollPane = new JScrollPane(textArea); + + this.add(titleLabel, BorderLayout.NORTH); // Ajoute le titre en haut du panneau + this.add(scrollPane, BorderLayout.CENTER); // Ajoute le texte avec barre de défilement au centre du panneau + + this.setPreferredSize(this.FRAME_SIZE); // Définit la taille préférée du panneau + } +} diff --git a/src/GridMakerImport.java b/src/GridMakerImport.java new file mode 100755 index 0000000..b17dc99 --- /dev/null +++ b/src/GridMakerImport.java @@ -0,0 +1,87 @@ +import java.awt.event.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.*; + +/** + * La classe GridMakerImport est utilisée pour importer une grille à partir d'un fichier. + * Elle implémente l'interface ActionListener pour réagir aux événements de clic sur un bouton. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerImport implements ActionListener { + + private JFrame previousFrame; + private GridMakerGrid grid; + private boolean accessible; + private File file; + private int[] importedValues = new int[9]; + + /** + * Constructeur pour créer une instance de GridMakerImport. + * @param frame La fenêtre précédente + * @param sudokuGrid La grille Sudoku + */ + public GridMakerImport(JFrame frame, GridMakerGrid sudokuGrid) { + this.previousFrame = frame; + this.grid = sudokuGrid; + } + + /** + * Méthode invoquée lorsqu'un événement d'action est déclenché, comme un clic sur un bouton. + * Importe la grille à partir du fichier sélectionné. + * @param e L'événement d'action + */ + public void actionPerformed(ActionEvent e) { + importGrid(); + if (accessible) { + grid.importGrid(importedValues); + } + } + + /** + * Affiche une boîte de dialogue de sélection de fichier et importe la grille à partir du fichier sélectionné. + */ + public void importGrid() { + JFileChooser fileChooser = new JFileChooser(); + FileNameExtensionFilter filter = new FileNameExtensionFilter("Grid files (*.gri)", "gri"); + fileChooser.setFileFilter(filter); + int returnVal = fileChooser.showOpenDialog(previousFrame); + if (returnVal == JFileChooser.APPROVE_OPTION) { + file = fileChooser.getSelectedFile(); + if (readFile()) { + accessible = true; + } else { + accessible = false; + } + } + } + + /** + * Lit les données à partir du fichier sélectionné et les stocke dans un tableau. + * @return true si la lecture est réussie, false sinon + */ + public boolean readFile() { + try { + FileInputStream fileInputStream = new FileInputStream(file); + DataInputStream dataInputStream = new DataInputStream(fileInputStream); + int incrementable = 0; + while (dataInputStream.available() > 0 && incrementable < 9) { + importedValues[incrementable] = dataInputStream.readInt(); + incrementable++; + } + dataInputStream.close(); + return true; + } catch (FileNotFoundException e) { + System.err.println("File not found."); + return false; + } catch (IOException e) { + System.err.println("IOException."); + return false; + } catch (NumberFormatException e) { + System.err.println("NumberFormatException."); + return false; + } + } +} diff --git a/src/GridMakerResetGrid.java b/src/GridMakerResetGrid.java new file mode 100755 index 0000000..2f8af60 --- /dev/null +++ b/src/GridMakerResetGrid.java @@ -0,0 +1,48 @@ +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * La classe GridMakerResetGrid ... à compléter + * + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ + +public class GridMakerResetGrid implements ActionListener { + + /** + * La grille à réinitialiser. + */ + private GridMakerGrid myGrid; + + /** + * Constructeur pour créer une instance de GridMakerResetGrid. + * @param grid Grille à réinitialiser + */ + public GridMakerResetGrid(GridMakerGrid grid) { + this.myGrid = grid; + } + + /** + * Lance la réinitialisation de la grille lors du clic sur le bouton Reset. + * @param e ActionEvent lié à la classe + */ + @Override + public void actionPerformed(ActionEvent e) { // TEMPORAIRE !! À MODIFIER DANS UN FICHIER SÉPARÉ + ResetGrid(); + } + + /** + * Cette méthode crée une grille vide. + */ + public void ResetGrid() { + int[] array = new int[9]; + + for (int i = 0; i < 9 ; i++) { + array[i] = 0; + } + + this.myGrid.importGrid(array); + } +} diff --git a/src/GridMakerRules.java b/src/GridMakerRules.java new file mode 100755 index 0000000..357a85d --- /dev/null +++ b/src/GridMakerRules.java @@ -0,0 +1,14 @@ +import java.awt.event.*; + +public class GridMakerRules implements ActionListener { + private RulesDialogManager rulesDialog; + + public GridMakerRules(){ + this.rulesDialog = new RulesDialogManager(); + } + + @Override + public void actionPerformed(ActionEvent e) { + rulesDialog.showDialog(); // On appelle la méthode qui affiche la fenêtre de dialogue + } +} diff --git a/src/GridMakerSaver.java b/src/GridMakerSaver.java new file mode 100755 index 0000000..6e62565 --- /dev/null +++ b/src/GridMakerSaver.java @@ -0,0 +1,84 @@ +import java.io.*; +import javax.swing.*; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +/** + * Cette classe implémente un gestionnaire d'enregistrement de grille de jeu. + * Elle permet à l'utilisateur de sauvegarder une grille de jeu dans un fichier spécifié. + * Les fichiers de grille sont sauvegardés avec l'extension ".gri". + * Cette classe écoute les événements d'action déclenchés par un composant d'interface utilisateur. + * @version 1.0 + * @author Moncef STITI + * @author Marco ORFAO + */ +public class GridMakerSaver implements ActionListener { + + private File selectedFile; // Le fichier sélectionné pour sauvegarde + private JFrame parentFrame; // La fenêtre parent + private GridMakerGrid grid; // La grille de jeu à sauvegarder + + /** + * Constructeur de la classe GridMakerSaver. + * @param parentFrame La fenêtre parent. + * @param grid La grille de jeu à sauvegarder. + */ + public GridMakerSaver(JFrame parentFrame, GridMakerGrid grid) { + this.parentFrame = parentFrame; + this.grid = grid; + } + + /** + * Méthode invoquée lorsqu'un événement d'action est déclenché. + * Elle vérifie si la grille est valide, puis la sauvegarde si c'est le cas. + * Sinon, elle affiche un message d'erreur. + * @param e L'événement d'action déclenché. + */ + public void actionPerformed(ActionEvent e) { + if (isValidGrid()) { + saveGrid(); + } else { + JOptionPane.showMessageDialog(parentFrame, "Format de grille non valide.", "Erreur", JOptionPane.ERROR_MESSAGE); + } + } + + /** + * Vérifie si la grille est valide en utilisant un test spécifique. + * @return true si la grille est valide, sinon false. + */ + private boolean isValidGrid() { + GridMakerChecker test = new GridMakerChecker(grid); + return test.isCorrect(); + } + + /** + * Sauvegarde la grille de jeu dans un fichier spécifié par l'utilisateur. + * Affiche un message de succès ou d'erreur selon le résultat de la sauvegarde. + */ + private void saveGrid() { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("Enregistrer la grille"); + FileNameExtensionFilter filter = new FileNameExtensionFilter("Fichiers de grille (*.gri)", "gri"); + fileChooser.setFileFilter(filter); + + int userSelection = fileChooser.showSaveDialog(parentFrame); + + if (userSelection == JFileChooser.APPROVE_OPTION) { + selectedFile = fileChooser.getSelectedFile(); // on stock le fichier choisie au cas ou + + try (FileOutputStream fileOutputStream = new FileOutputStream(selectedFile); + DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream)) { + + int[] gridData = grid.exportGrid(); + for (int i = 0; i < 9; i++) { + dataOutputStream.writeInt(gridData[i]); + } + + JOptionPane.showMessageDialog(parentFrame, "Grille sauvegardée avec succès !", "Succès", JOptionPane.INFORMATION_MESSAGE); + } catch (IOException ex) { + JOptionPane.showMessageDialog(parentFrame, "Erreur lors de la sauvegarde de la grille : " + ex.getMessage(), "Erreur", JOptionPane.ERROR_MESSAGE); + } + } + } +} diff --git a/src/Grille.java b/src/Grille.java deleted file mode 100644 index 602c4fc..0000000 --- a/src/Grille.java +++ /dev/null @@ -1,52 +0,0 @@ -public class Grille { - private int[][] grille; - - public Grille() { - grille = new int[9][9]; - // Initialiser la grille avec des zéros pour représenter des cases vides - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - grille[i][j] = 0; - } - } - } - - public boolean est_valide(int row, int col, int num) { - // Vérifier si le nombre est présent dans la même ligne ou colonne - for (int i = 0; i < 9; i++) { - if (grille[row][i] == num || grille[i][col] == num) { - return false; - } - } - - // Vérifier si le nombre est présent dans le carré 3x3 - int startRow = row - row % 3; - int startCol = col - col % 3; - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (grille[i + startRow][j + startCol] == num) { - return false; - } - } - } - - return true; - } - - public void remplir_case(int row, int col, int num) { - grille[row][col] = num; - } - - public boolean case_vide(int row, int col) { - return grille[row][col] == 0; - } - - public void vider_case(int row, int col) { - grille[row][col] = 0; - } - - public int getValue(int row, int col) { - return grille[row][col]; - } -} - diff --git a/src/GrilleButtonClickListener.java b/src/GrilleButtonClickListener.java deleted file mode 100644 index 4753467..0000000 --- a/src/GrilleButtonClickListener.java +++ /dev/null @@ -1,25 +0,0 @@ -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -public class GrilleButtonClickListener implements ActionListener { - private Window window; - - public GrilleButtonClickListener(Window window) { - this.window = window; - } - - @Override - public void actionPerformed(ActionEvent e) { - Button sourceButton = (Button) e.getSource(); - String buttonText = sourceButton.getText(); - - // Si le bouton "Retour au menu principal" est cliqué, on efface ce qui est présent et on met le menu jouer - if (buttonText.equals("Retour au menu principal")) { - if (window.getContentPane().getComponent(0) instanceof GrilleView) { - GrilleView grilleView = (GrilleView) window.getContentPane().getComponent(0); - grilleView.removeAllComponents(window); - window.changeMenu(new PlayMenuView(this.window)); // PAS BON CAR ON VA CRÉE UN MENU JOUER À CHAQUE FOIS AU LIEU DE RÉUTILISER L'ANCIEN - } - } - } -} diff --git a/src/GrilleView.java b/src/GrilleView.java deleted file mode 100644 index 513c088..0000000 --- a/src/GrilleView.java +++ /dev/null @@ -1,69 +0,0 @@ -import javax.swing.*; -import java.awt.*; - -public class GrilleView extends JPanel { - private final Font BUTTON_FONT = new Font("Copperplate", Font.BOLD, 24); - private final String[] BUTTON_TEXTS = {"Retour au menu principal"}; - private final Dimension BUTTON_SIZE = new Dimension(450, 60); - private Grille grille; - private Window window; - private JTextField[][] cases; - - public GrilleView(Grille grille, Window window) { - super(); - this.grille = grille; - this.window = window; - initialize(); - } - - private void initialize() { - // Définir le style de fond similaire à HomeView - this.setBackground(new Color(54, 91, 109)); - - // Définir le gestionnaire de disposition et créer le tableau de cases - this.setLayout(new BorderLayout()); - JPanel grillePanel = new JPanel(new GridLayout(9, 9)); - grillePanel.setBackground(new Color(54, 91, 109)); - this.add(grillePanel, BorderLayout.CENTER); - - this.cases = new JTextField[9][9]; - - // Créer les cases et les ajoutez à la grille - for (int row = 0; row < 9; row++) { - for (int col = 0; col < 9; col++) { - int valeur = this.grille.getValeur(row, col); - JTextField caseField = new JTextField(1); - if (valeur != 0) { - caseField.setText(Integer.toString(valeur)); - } - caseField.setHorizontalAlignment(JTextField.CENTER); - caseField.setEditable(false); - this.cases[row][col] = caseField; - grillePanel.add(caseField); - } - } - - // Ajouter un bouton "Retour au menu principal" en bas - Button retourButton = new Button(BUTTON_TEXTS[0], BUTTON_SIZE, BUTTON_FONT); - retourButton.addActionListener(new GrilleButtonClickListener(window)); - JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); - buttonPanel.setBackground(new Color(54, 91, 109)); - buttonPanel.add(retourButton); - this.add(buttonPanel, BorderLayout.SOUTH); - } - - public void addComponentsToWindow() { - window.getContentPane().add(this); - window.setPageTitle("Grille"); - window.pack(); - window.setLocationRelativeTo(null); - window.setVisible(true); - } - - // Method to remove all components from the window - public void removeAllComponents(Window window) { - window.remove(this); - window.revalidate(); - window.repaint(); - } -} diff --git a/src/HomeView.java b/src/HomeView.java index 7817678..9a428ad 100644 --- a/src/HomeView.java +++ b/src/HomeView.java @@ -64,7 +64,7 @@ public class HomeView extends JPanel { window.add(titlePanel, BorderLayout.NORTH); window.add(buttonPanel, BorderLayout.WEST); window.add(imageLabel, BorderLayout.EAST); - window.setPageTitle("Menu"); + window.setPageTitle("Menu principal"); FlowLayout controlPanelLayout = new FlowLayout(FlowLayout.RIGHT); JPanel controlPanel = new JPanel(controlPanelLayout); diff --git a/src/PlayButtonClickListener.java b/src/PlayButtonClickListener.java index f34d87b..8c01f44 100644 --- a/src/PlayButtonClickListener.java +++ b/src/PlayButtonClickListener.java @@ -16,47 +16,18 @@ public class PlayButtonClickListener implements ActionListener { String buttonText = sourceButton.getText(); if (buttonText.equals("Jouer sans grille")) { - Grille nouvelleGrille = new Grille(); - SudokuGenerator sudokuGenerator = new SudokuGenerator(nouvelleGrille,81); // 81 = générer une grille avec 81 espaces vides - Grille grilleGeneree = sudokuGenerator.genererGrille(); // Générer la grille - GrilleView grilleView1 = new GrilleView(grilleGeneree, window); // Créer la vue de la grille - window.changeMenu(grilleView1); // Modifier le menu pour afficher la grille générée + } else if (buttonText.equals("Générer une grille")) { - // Demander à l'utilisateur combien de cases vides ils souhaite sur sa grille - String input = JOptionPane.showInputDialog(window, "Combien de cases vides voulez-vous sur la grille ?", "Nombre de cases vides", JOptionPane.QUESTION_MESSAGE); - - // Vérifier si l'utilisateur a annulé la saisie ou a fermé la fenêtre de dialogue - if (input != null && !input.isEmpty()) { - int nombreChiffres = Integer.parseInt(input); - - // Vérifier que le nombre est compris entre 0 et 81 - if (nombreChiffres >= 0 && nombreChiffres <= 81) { - Grille nouvelleGrille = new Grille(); - SudokuGenerator sudokuGenerator = new SudokuGenerator(nouvelleGrille, nombreChiffres); - Grille grilleGeneree = sudokuGenerator.genererGrille(); // Générer la grille - - // Créer la vue de la grille - GrilleView grilleView1 = new GrilleView(grilleGeneree, window); - - // Modifier le menu pour afficher la grille générée - window.changeMenu(grilleView1); - } else { - JOptionPane.showMessageDialog(window, "Veuillez saisir un nombre entre 0 et 81.", "Erreur", JOptionPane.ERROR_MESSAGE); - } - } else { - // L'utilisateur a annulé la saisie ou fermé la fenêtre de dialogue, traitement en conséquence - } - } else if (buttonText.equals("Charger une grille")) { - Grille grille = FileManager.loadGrid(); - GrilleView grilleView = new GrilleView(grille, window); - window.changeMenu(grilleView); + Window.removeAllComponents(this.window); + new GridMakeUserInterfaceView(this.window); + } else if (buttonText.equals("Charger une grille")) { + } else if (buttonText.equals("Retour au menu principal")) { if (window.getContentPane().getComponent(0) instanceof PlayMenuView) { - PlayMenuView playMenuView = (PlayMenuView) window.getContentPane().getComponent(0); - playMenuView.removeAllComponents(window); + Window.removeAllComponents(window); HomeView homeView = new HomeView(window); } } diff --git a/src/PlayMenuView.java b/src/PlayMenuView.java index 9e4d713..6c5e4f4 100644 --- a/src/PlayMenuView.java +++ b/src/PlayMenuView.java @@ -50,6 +50,7 @@ public class PlayMenuView extends JPanel { // Method to add components to the window private void addComponentsToWindow(Window window) { // Layout + window.setPageTitle("Menu jouer"); setLayout(new BorderLayout()); setBackground(BACKGROUND_COLOR); @@ -62,11 +63,4 @@ public class PlayMenuView extends JPanel { // Add panel to the window window.add(this); } - - // Method to remove all components from the window - public void removeAllComponents(Window window) { - window.remove(this); - window.revalidate(); - window.repaint(); - } } diff --git a/src/RulesSudoku.java b/src/RulesSudoku.java index 8438516..b56c480 100644 --- a/src/RulesSudoku.java +++ b/src/RulesSudoku.java @@ -2,11 +2,13 @@ import javax.swing.*; import java.awt.*; public class RulesSudoku extends JPanel { + private Dimension FRAME_SIZE = new Dimension(400, 500); + private Color BACKGROUND_COLOR = new Color(54, 91, 109); public RulesSudoku() { BorderLayout gestionnaireBorderLayout = new BorderLayout(); this.setLayout(gestionnaireBorderLayout); - this.setBackground(new Color(54, 91, 109)); // Couleur d'arrière-plan du menu principal + this.setBackground(this.BACKGROUND_COLOR); // Couleur d'arrière-plan du menu principal JLabel titleLabel = new JLabel("Règles du Sudoku"); titleLabel.setFont(new Font("Copperplate", Font.BOLD, 40)); // Police du titre @@ -23,13 +25,13 @@ public class RulesSudoku extends JPanel { rulesTextArea.setWrapStyleWord(true); rulesTextArea.setFont(new Font("Arial", Font.PLAIN, 20)); // Police du texte des règles rulesTextArea.setForeground(Color.WHITE); // Couleur du texte des règles - rulesTextArea.setBackground(new Color(54, 91, 109)); // Couleur d'arrière-plan du texte des règles + rulesTextArea.setBackground(this.BACKGROUND_COLOR); // Couleur d'arrière-plan du texte des règles JScrollPane scrollPane = new JScrollPane(rulesTextArea); this.add(titleLabel, BorderLayout.NORTH); this.add(scrollPane, BorderLayout.CENTER); - this.setPreferredSize(new Dimension(400, 500)); // Taille de la fenêtre des règles + this.setPreferredSize(this.FRAME_SIZE); // Taille de la fenêtre des règles } } diff --git a/src/SudokuGenerator.java b/src/SudokuGenerator.java deleted file mode 100644 index a8fd26b..0000000 --- a/src/SudokuGenerator.java +++ /dev/null @@ -1,99 +0,0 @@ -import java.util.Random; - -public class SudokuGenerator { - private int nombreCasesVides; - private Grille grille; - - public SudokuGenerator(Grille grille, int nombreCasesVides) { - this.grille = grille; - this.nombreCasesVides = nombreCasesVides; - } - - public Grille genererGrille() { - remplirDiagonales(); // Remplir les diagonales pour assurer la validité initiale - // Remplir le reste de la grille de manière récursive - remplirGrille(0); - // Supprimer certains nombres pour obtenir une grille incomplète mais résolva ble - supprimerNombres(); - return grille; - } - - private void supprimerNombres() { - Random random = new Random(); - while (this.nombreCasesVides > 0) { - int row = random.nextInt(9); - int col = random.nextInt(9); - if (grille.case_vide(row, col)) { - continue; // La case est déjà vide, passer à la suivante - } - - int temp = grille.getValue(row, col); - grille.vider_case(row, col); - // Vérifier s'il existe une seule solution après avoir vidé la case - if (aUneSeuleSolution()) { - // Il y a encore une solution, la suppression est sûre - this.nombreCasesVides--; - } else { - // Il n'y a plus de solution, remettre le nombre dans la case - grille.remplir_case(row, col, temp); - } - } - } - - private boolean aUneSeuleSolution() { - Grille grilleTemp = new Grille(); - for (int i = 0; i < 9; i++) { - for (int j = 0; j < 9; j++) { - grilleTemp.remplir_case(i, j, grille.getValue(i, j)); - } - } - SudokuSolver solver = new SudokuSolver(); - return solver.resoudreSudoku(grilleTemp); - } - - // Méthode de remplissage de la grille et remplissage des diagonales... - private void remplirDiagonales() { - for (int i = 0; i < 9; i += 3) { - remplirCarre(i, i); - } - } - - private void remplirCarre(int row, int col) { - Random random = new Random(); - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - int num; - do { - num = random.nextInt(9) + 1; // Générer un nombre aléatoire entre 1 et 9 - } while (!grille.est_valide(row + i, col + j, num)); // Vérifier la validité du nombre - grille.remplir_case(row + i, col + j, num); - } - } - } - - private boolean remplirGrille(int position) { - if (position == 81) { - return true; // La grille est remplie - } - - int row = position / 9; - int col = position % 9; - - if (grille.case_vide(row, col)) { - for (int num = 1; num <= 9; num++) { - if (grille.est_valide(row, col, num)) { - grille.remplir_case(row, col, num); - - if (remplirGrille(position + 1)) { - return true; - } - - grille.vider_case(row, col); - } - } - return false; - } else { - return remplirGrille(position + 1); - } - } -} diff --git a/src/SudokuSolver.java b/src/SudokuSolver.java deleted file mode 100644 index 2d8755a..0000000 --- a/src/SudokuSolver.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Classe pour résoudre un Sudoku. - * @author Moncef STITI - * @author Marco ORFAO - * @version 1.0 - */ -public class SudokuSolver { - - /** - * Méthode pour résoudre un Sudoku en utilisant la récursivité. - * @param grille La grille de Sudoku à résoudre - * @return true si le Sudoku est résolu avec succès, false sinon - */ - public boolean resoudreSudoku(Grille grille) { - // Parcours de chaque case de la grille - for (int row = 0; row < 9; row++) { - for (int col = 0; col < 9; col++) { - // Vérification si la case est vide - if (grille.case_vide(row, col)) { - // Essayer chaque chiffre de 1 à 9 - for (int num = 1; num <= 9; num++) { - // Vérifier si le chiffre est valide dans cette case - if (grille.est_valide(row, col, num)) { - // Remplir la case avec le chiffre - grille.remplir_case(row, col, num); - // Appel récursif pour résoudre le reste du Sudoku - if (resoudreSudoku(grille)) { - return true; // Si le Sudoku est résolu, retourner true - } - // Si le Sudoku n'est pas résolu avec ce chiffre, vider la case et essayer un autre chiffre - grille.vider_case(row, col); - } - } - return false; // Si aucun chiffre ne convient, retourner false - } - } - } - return true; // Si toutes les cases sont remplies, le Sudoku est résolu - } -} diff --git a/src/Window.java b/src/Window.java index c88ccac..a3afb2c 100644 --- a/src/Window.java +++ b/src/Window.java @@ -51,4 +51,10 @@ public class Window extends JFrame { revalidate(); repaint(); } + + public static void removeAllComponents(Window window) { + window.getContentPane().removeAll(); + window.revalidate(); + window.repaint(); + } }