Par MARCO : Ajout du FileManager + Génération de grille
This commit is contained in:
parent
8750448693
commit
627617656f
@ -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
84
src/FileManager.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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
|
||||
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 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];
|
||||
}
|
||||
}
|
||||
|
||||
/*public static void main(String[] args){
|
||||
Grille grille = new Grille();
|
||||
grille.remplir_case(3,59);
|
||||
System.out.println(grille.case_vide(3));
|
||||
}*/
|
||||
}
|
||||
|
15
src/GrilleView.java
Normal file
15
src/GrilleView.java
Normal 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
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
@ -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
100
src/SudokuGenerator.java
Normal 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
40
src/SudokuSolver.java
Normal 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
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user