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 {
|
public interface DialogManager {
|
||||||
void showDialog();
|
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 {
|
public class Grille {
|
||||||
private int[] grille = null;
|
private int[][] grille;
|
||||||
|
|
||||||
public Grille(){
|
public Grille() {
|
||||||
this.grille = new int[81];
|
grille = new int[9][9];
|
||||||
int x;
|
// Initialiser la grille avec des zéros pour représenter des cases vides
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
for (x=0 ; x < 81 ; x++) {
|
for (int j = 0; j < 9; j++) {
|
||||||
this.grille[x]=0; //remplie la grille de "0" -> "0" est un marqueur signifiant que la case est vide
|
grille[i][j] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean case_vide(int position){
|
public boolean est_valide(int row, int col, int num) {
|
||||||
if (this.grille[position] == 0) {
|
// Vérifier si le nombre est présent dans la même ligne ou colonne
|
||||||
return true;
|
for (int i = 0; i < 9; i++) {
|
||||||
} else {
|
if (grille[row][i] == num || grille[i][col] == num) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean est_valide(int position, int nbr){
|
// Vérifier si le nombre est présent dans le carré 3x3
|
||||||
|
int startRow = row - row % 3;
|
||||||
/* check si le numéro se répète sur la colonne */
|
int startCol = col - col % 3;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
int colonne = position%9;
|
for (int j = 0; j < 3; j++) {
|
||||||
int id_test = colonne;
|
if (grille[i + startRow][j + startCol] == num) {
|
||||||
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)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remplir_case(int position,int nbr){
|
public void remplir_case(int row, int col, int num) {
|
||||||
if ((nbr > 0) && (nbr < 10)){
|
grille[row][col] = num;
|
||||||
this.grille[position] = nbr;
|
|
||||||
} else {
|
|
||||||
System.out.println("veuillez choisir un nombre entre 1 et 9");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public static void main(String[] args){
|
public boolean case_vide(int row, int col) {
|
||||||
Grille grille = new Grille();
|
return grille[row][col] == 0;
|
||||||
grille.remplir_case(3,59);
|
}
|
||||||
System.out.println(grille.case_vide(3));
|
|
||||||
}*/
|
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
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.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener for button clicks in the menu.
|
* Listener for button clicks in the menu.
|
||||||
* It performs different actions based on the button clicked.
|
* 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
|
// Handle different button actions based on their text
|
||||||
if (buttonText.equals("Générer une grille")) {
|
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")) {
|
} 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")) {
|
} else if (buttonText.equals("Retour au menu principal")) {
|
||||||
if (window.getContentPane().getComponent(0) instanceof PlayMenuView) {
|
if (window.getContentPane().getComponent(0) instanceof PlayMenuView) {
|
||||||
PlayMenuView playMenuView = (PlayMenuView) window.getContentPane().getComponent(0);
|
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