modifications pour répondre aux attentes de la SAE

This commit is contained in:
Vincent TEISSIER 2024-05-05 13:38:52 +02:00
parent 4d6261bcab
commit 4cf7a8bb33
7 changed files with 147 additions and 27 deletions

@ -6,24 +6,28 @@ import java.util.Random;
public class GenerateGrid {
private static final int GRID_SIZE = 9;
private static final int EMPTY_CELL = 0;
private static final int MINIMUM_CLUES = 25; // Modifier ce nombre en fonction du nombre de clues désiré
private static int minimumClues = 25; // Nombre de "clues" par défaut
/**
* Méthode principale pour tester la génération d'une grille ( Seulement pour le debug ).
* @param args Arguments de la ligne de commande (non utilisés).
*/
public static void main(String[] args) {
Grid grid = generateSudokuGrid();
Grid grid = generateSudokuGrid(minimumClues); // Utilisation de la variable pour générer la grille
printGrid(grid);
}
/**
* Génère une grille de Sudoku.
* @param numberOfClues Le nombre de "clues" (indices déjà remplis) à générer.
* @return La grille de Sudoku générée.
*/
public static Grid generateSudokuGrid() {
public static Grid generateSudokuGrid(int numberOfClues) {
minimumClues = numberOfClues; // Met à jour le nombre de "clues"
Grid grid = new Grid();
solveSudoku(grid);
ensureUniqueSolution(grid); // Vérifie et assure une solution unique
removeNumbers(grid);
return grid;
}
@ -116,6 +120,51 @@ public class GenerateGrid {
}
}
/**
* Vérifie et assure qu'il y a une solution unique pour la grille de Sudoku.
* @param grid La grille de Sudoku.
* @return True si la grille a une solution unique, sinon False.
*/
private static boolean ensureUniqueSolution(Grid grid) {
return hasUniqueSolution(grid, 0);
}
/**
* Vérifie si la grille de Sudoku a une solution unique.
* @param grid La grille de Sudoku à vérifier.
* @param count Le nombre de solutions trouvées jusqu'à présent.
* @return True si la grille a une solution unique, sinon False.
*/
private static boolean hasUniqueSolution(Grid grid, int count) {
// Recherche de solutions supplémentaires après la première
if (count > 1) {
return false;
}
// Recherche de solutions
if (!solveSudoku(grid)) {
return false; // Aucune solution trouvée
}
count++; // Une solution trouvée
if (count == 1 && !hasMultipleSolutions(grid)) {
return true; // Une solution unique trouvée
}
// Plusieurs solutions trouvées
return false;
}
/**
* Vérifie si la grille de Sudoku a plusieurs solutions.
* @param grid La grille de Sudoku à vérifier.
* @return True si la grille a plusieurs solutions, sinon False.
*/
private static boolean hasMultipleSolutions(Grid grid) {
return solveSudoku(grid); // Si une deuxième solution est trouvée, la grille a plusieurs solutions
}
/**
* Supprime les nombres de la grille pour créer une énigme de Sudoku.
* @param grid La grille de Sudoku.
@ -123,7 +172,7 @@ public class GenerateGrid {
public static void removeNumbers(Grid grid) {
Random random = new Random();
while (countClues(grid) > MINIMUM_CLUES) {
while (countClues(grid) > minimumClues) {
int row = random.nextInt(GRID_SIZE);
int col = random.nextInt(GRID_SIZE);
int value = grid.getCell(row, col).getValue();

@ -9,14 +9,15 @@ import java.io.IOException;
*/
public class Grid {
private Cell[][] cells;
public static final int SIZE = 9; // Ajout de la variable SIZE
/**
* Constructeur par défaut qui initialise une grille de Sudoku vide.
*/
public Grid() {
cells = new Cell[9][9];
for (int ligne = 0; ligne < 9; ligne++) {
for (int column = 0; column < 9; column++) {
cells = new Cell[SIZE][SIZE]; // Utilisation de la variable SIZE
for (int ligne = 0; ligne < SIZE; ligne++) {
for (int column = 0; column < SIZE; column++) {
cells[ligne][column] = new Cell();
}
}
@ -24,17 +25,18 @@ public class Grid {
/**
* Charge une grille de Sudoku à partir d'un fichier.
*
* @param fileName Le nom du fichier à partir duquel charger la grille avec extension ".gri".
*/
public void loadGridFromFile(String fileName) {
try (DataInputStream input = new DataInputStream(new FileInputStream(fileName))) {
for (int ligne = 0; ligne < 9; ligne++) {
for (int ligne = 0; ligne < SIZE; ligne++) {
String line = String.valueOf(input.readInt());
int length = line.length();
if (length < 9) {
if (length < SIZE) {
line = "000000000".substring(length) + line; // Ajoute les zéros au début si nécessaire
}
for (int column = 0; column < 9; column++) {
for (int column = 0; column < SIZE; column++) {
char number = line.charAt(column);
int value = Character.getNumericValue(number);
cells[ligne][column].setValue(value);
@ -45,16 +47,17 @@ public class Grid {
System.err.println("Error: " + e.getMessage());
}
}
/**
* Sauvegarde la grille de Sudoku dans un fichier ".gri".
*
* @param fileName Le nom du fichier dans lequel sauvegarder la grille.
*/
public void saveGridToFile(String fileName) {
try (DataOutputStream output = new DataOutputStream(new FileOutputStream(fileName))) {
for (int ligne = 0; ligne < 9; ligne++) {
for (int ligne = 0; ligne < SIZE; ligne++) {
StringBuilder line = new StringBuilder();
for (int column = 0; column < 9; column++) {
for (int column = 0; column < SIZE; column++) {
int value = cells[ligne][column].getValue();
line.append(value);
}
@ -68,8 +71,9 @@ public class Grid {
/**
* Obtient la cellule à la position spécifiée dans la grille.
*
* @param ligne L'indice de ligne de la cellule.
* @param col L'indice de colonne de la cellule.
* @param col L'indice de colonne de la cellule.
* @return La cellule à la position spécifiée.
*/
public Cell getCell(int ligne, int col) {
@ -78,22 +82,40 @@ public class Grid {
/**
* Copie le contenu d'une autre grille dans cette grille.
*
* @param second_grid La grille à partir de laquelle copier les valeurs.
*/
public void copyFrom(Grid second_grid) {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
this.cells[row][col].setValue(second_grid.cells[row][col].getValue());
}
}
}
/**
* Vérifie si la grille est complètement remplie.
*
* @return True si toutes les cellules de la grille sont remplies, False sinon.
*/
public boolean isFull() {
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
if (getCell(row, col).getValue() == 0) {
return false;
}
}
}
return true;
}
/**
* Affiche la grille de Sudoku dans la console.
*/
public void printGrid() {
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
for (int row = 0; row < SIZE; row++) {
for (int col = 0; col < SIZE; col++) {
System.out.print(cells[row][col].getValue() + " ");
}
System.out.println();

@ -61,4 +61,4 @@ public class Sudoku {
}
}
}
}

@ -117,4 +117,4 @@ public class SudokuCreator extends SudokuUI {
new SudokuCreator(sudoku);
}
}
}

@ -1,6 +1,5 @@
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@ -13,6 +12,7 @@ public class SudokuGame extends SudokuUI {
/**
* Constructeur de la classe SudokuGame.
*
* @param sudoku La grille de Sudoku à utiliser pour le jeu.
*/
public SudokuGame(Sudoku sudoku) {
@ -22,6 +22,7 @@ public class SudokuGame extends SudokuUI {
/**
* Méthode pour obtenir le texte du titre de l'interface utilisateur.
*
* @return Le texte du titre.
*/
@Override
@ -42,19 +43,26 @@ public class SudokuGame extends SudokuUI {
* Méthode pour créer le bouton de résolution.
*/
private void createSolveButton() {
JButton solveButton = new JButton("Résoudre");
JButton solveButton = new JButton("Résoudre (Automatique)");
solveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
long startTime = System.nanoTime(); // Temps de début de la résolution
SudokuSolver solver = new SudokuSolver(); // Créez une instance de SudokuSolver
Grid solvedGrid = new Grid(); // Créez une nouvelle grille pour stocker la solution
solvedGrid.copyFrom(sudoku.getGrid()); // Copiez la grille actuelle de Sudoku
// Résolvez la grille
if (solver.solve(solvedGrid)) {
long endTime = System.nanoTime(); // Temps de fin de la résolution
long duration = (endTime - startTime) / 1_000_000; // Conversion de nanosecondes en millisecondes
// Si une solution est trouvée, mettez à jour la grille Sudoku avec la solution
sudoku.getGrid().copyFrom(solvedGrid);
updateGrid();
JOptionPane.showMessageDialog(null, "La grille a été résolue en " + duration + " millisecondes.");
checkGameCompletion(); // Vérifiez si le jeu est terminé après la résolution
} else {
// Sinon, affichez un message indiquant que la grille est insoluble
JOptionPane.showMessageDialog(null, "La grille est insoluble.");
@ -106,8 +114,48 @@ public class SudokuGame extends SudokuUI {
}
}
/**
* Méthode pour vérifier si la grille est complètement remplie et si la solution est correcte.
* Affiche une alerte si la grille est résolue correctement.
*/
private void checkGameCompletion() {
Grid grid = sudoku.getGrid();
boolean isFull = true;
boolean hasErrors = false;
for (int row = 0; row < 9; row++) {
for (int col = 0; col < 9; col++) {
int value = grid.getCell(row, col).getValue();
if (value == 0) {
isFull = false;
} else if (!isValidMove(grid, row, col, value)) {
hasErrors = true;
}
}
}
if (isFull && !hasErrors) {
JOptionPane.showMessageDialog(null, "Félicitations ! Vous avez résolu la grille avec succès !");
}
}
/**
* Vérifie si le placement d'un nombre dans une cellule est sûr.
*
* @param grid La grille de Sudoku.
* @param row L'indice de ligne de la cellule.
* @param col L'indice de colonne de la cellule.
* @param num Le nombre à vérifier.
* @return True si le placement est sûr, False sinon.
*/
private boolean isValidMove(Grid grid, int row, int col, int num) {
// Votre logique de validation ici
return false;
}
/**
* Méthode principale pour démarrer le jeu de Sudoku.
*
* @param args Les arguments de la ligne de commande (non utilisés).
*/
public static void main(String[] args) {

@ -10,12 +10,12 @@ public class SudokuSolver {
* @return True si la grille a été résolue avec succès, False si elle est insoluble.
*/
public boolean solve(Grid grid) {
long startTime = System.currentTimeMillis(); // Temps de début de la résolution
long startTime = System.nanoTime(); // Temps de début de la résolution
boolean isSolved = solveRecursive(grid);
long endTime = System.currentTimeMillis(); // Temps de fin de la résolution
long duration = endTime - startTime; // Calcul de la durée de résolution
long endTime = System.nanoTime(); // Temps de fin de la résolution
long duration = (endTime - startTime) / 1_000_000; // Conversion de nanosecondes en millisecondes
if (isSolved) {
System.out.println("La grille a été résolue en " + duration + " millisecondes.");
@ -91,4 +91,4 @@ public class SudokuSolver {
return true;
}
}
}

@ -83,4 +83,5 @@ public abstract class SudokuUI extends JFrame {
}
}
}
}
}