Par MARCO : Ajout du FileManager + Génération de grille

This commit is contained in:
Moncef STITI 2024-04-11 21:50:08 +02:00
parent 8750448693
commit 627617656f
8 changed files with 284 additions and 62 deletions

View File

@ -1,5 +1,10 @@
/**
* Interface containing definition to showDialog box.
* @version 1.0
* @author Moncef STITI
* @author Marco ORFAO
*/
public interface DialogManager {
void showDialog();
}

84
src/FileManager.java Normal file
View File

@ -0,0 +1,84 @@
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.BufferedWriter;
import java.io.BufferedReader;
import java.io.FileWriter;
import java.io.FileReader;
import java.io.IOException;
/**
* Classe pour gérer les opérations de sauvegarde et de chargement de grille.
* @author Moncef STITI
* @author Marco ORFAO
* @version 1.0
*/
public class FileManager {
/**
* Méthode pour sauvegarder une grille dans un fichier.
* @param grille La grille à sauvegarder
*/
public static void sauvegarderGrille(Grille grille) {
// Création d'un sélecteur de fichier
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Enregistrer la grille");
fileChooser.setFileFilter(new FileNameExtensionFilter("Fichiers de grille (.gri)", "gri"));
int userSelection = fileChooser.showSaveDialog(null);
if (userSelection == JFileChooser.APPROVE_OPTION) {
// Obtention du nom de fichier choisi par l'utilisateur
String nomFichier = fileChooser.getSelectedFile().getAbsolutePath();
// Vérification et ajout de l'extension .gri si nécessaire
if (!nomFichier.endsWith(".gri")) {
nomFichier += ".gri";
}
try (BufferedWriter writer = new BufferedWriter(new FileWriter(nomFichier))) {
// Écriture des valeurs de la grille dans le fichier
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
int valeur = grille.getValeur(i, j);
writer.write(valeur == 0 ? "0" : String.valueOf(valeur));
}
writer.newLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* Méthode pour charger une grille à partir d'un fichier.
* @return La grille chargée depuis le fichier
*/
public static Grille chargerGrille() {
// Création d'un sélecteur de fichier
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogTitle("Charger une grille");
fileChooser.setFileFilter(new FileNameExtensionFilter("Fichiers de grille (.gri)", "gri"));
int userSelection = fileChooser.showOpenDialog(null);
if (userSelection == JFileChooser.APPROVE_OPTION) {
// Obtention du nom de fichier choisi par l'utilisateur
String nomFichier = fileChooser.getSelectedFile().getAbsolutePath();
try (BufferedReader reader = new BufferedReader(new FileReader(nomFichier))) {
Grille grille = new Grille();
String ligne;
int row = 0;
// Lecture des lignes du fichier et remplissage de la grille
while ((ligne = reader.readLine()) != null && row < 9) {
for (int col = 0; col < 9 && col < ligne.length(); col++) {
char caractere = ligne.charAt(col);
if (caractere != ' ') {
int valeur = Character.getNumericValue(caractere);
grille.remplir_case(row, col, valeur);
}
}
row++;
}
return grille;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

View File

@ -1,76 +1,52 @@
public class Grille {
private int[] grille = null;
private int[][] grille;
public Grille(){
this.grille = new int[81];
int x;
for (x=0 ; x < 81 ; x++) {
this.grille[x]=0; //remplie la grille de "0" -> "0" est un marqueur signifiant que la case est vide
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 case_vide(int position){
if (this.grille[position] == 0) {
return true;
} else {
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;
}
}
public boolean est_valide(int position, int nbr){
/* check si le numéro se répète sur la colonne */
int colonne = position%9;
int id_test = colonne;
while (id_test != (72+colonne)) {
if ((this.grille[id_test]==nbr) && (id_test != position)) {
return false;
}
id_test += 9;
}
/* check si le numéro se répète sur la ligne */
int ligne = position/9;
id_test = ligne * 9;
while (id_test != ((ligne +1)*9)) {
if ((this.grille[id_test]==nbr) && (id_test != position)) {
return false;
}
id_test += 1;
}
/* check si le numéro se répète dans le carré auquel il appartient */
int Vcase = ligne/3; // permet de connaître la position du carré sur un axe vertical
int Hcase = colonne/3; // permet de connaître la position du carré sur un axe horizontal
int x,y;
for (x=0; x<3 ;x++) {
for (y=0; y<3 ;y++) {
id_test = Vcase*27+(y+Hcase*3)+(x*9);
if ((this.grille[id_test]==nbr) && (id_test != position)) {
// 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 position,int nbr){
if ((nbr > 0) && (nbr < 10)){
this.grille[position] = nbr;
} else {
System.out.println("veuillez choisir un nombre entre 1 et 9");
}
public void remplir_case(int row, int col, int num) {
grille[row][col] = num;
}
/*public static void main(String[] args){
Grille grille = new Grille();
grille.remplir_case(3,59);
System.out.println(grille.case_vide(3));
}*/
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 getValeur(int row, int col) {
return grille[row][col];
}
}

15
src/GrilleView.java Normal file
View File

@ -0,0 +1,15 @@
import javax.swing.*;
import java.awt.*;
public class GrilleView extends JFrame {
private Grille grille;
public GrilleView(Grille grille) {
this.grille = grille;
initUI();
}
private void initUI() {
// EN COURS
}
}

View File

@ -1,8 +1,6 @@
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Listener for button clicks in the menu.
* It performs different actions based on the button clicked.

View File

@ -15,9 +15,13 @@ public class PlayButtonClickListener implements ActionListener {
// Handle different button actions based on their text
if (buttonText.equals("Générer une grille")) {
System.out.println("Générer une grille");
Grille nouvelleGrille = new Grille();
SudokuGenerator sudokuGenerator = new SudokuGenerator(nouvelleGrille);
Grille grilleGeneree = sudokuGenerator.genererGrille(); // Générer la grille
FileManager.sauvegarderGrille(grilleGeneree);
} else if (buttonText.equals("Charger une grille")) {
System.out.println("Chargement de la grille");
Grille grille = FileManager.chargerGrille();
GrilleView test = new GrilleView(grille);
} else if (buttonText.equals("Retour au menu principal")) {
if (window.getContentPane().getComponent(0) instanceof PlayMenuView) {
PlayMenuView playMenuView = (PlayMenuView) window.getContentPane().getComponent(0);

100
src/SudokuGenerator.java Normal file
View File

@ -0,0 +1,100 @@
import java.util.Random;
public class SudokuGenerator {
private int nombreCasesVides = 40;
private Grille grille;
public SudokuGenerator(Grille grille) {
this.grille = grille;
}
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.getValeur(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.getValeur(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);
}
}
}

40
src/SudokuSolver.java Normal file
View File

@ -0,0 +1,40 @@
/**
* 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
}
}