Files
Sudoku/app/src/main/java/sudoku/ResolveurBacktraceSimple.java

111 lines
4.3 KiB
Java

package sudoku;
import java.util.List;
import sudoku.core.Console;
/**
* Implémentation d'un résolveur de Sudoku utilisant l'algorithme de
* backtracking.
* Cette classe fournit une solution pour résoudre les grilles de Sudoku
* en testant systématiquement toutes les possibilités valides.
*/
public class ResolveurBacktraceSimple implements Resolveur {
/**
* Constructeur par défaut du résolveur backtracking.
* Initialise un nouveau résolveur sans état initial.
*/
public ResolveurBacktraceSimple() {
// Constructeur par défaut
}
/**
* Méthode permettant de résoudre un sudoku en utilisant la méthode de
* backtracking
*
* @param s : sudoku à résoudre
* @param afficherEtape : afficher les étapes de la résolution
* @return true si le sudoku est résolvable, false sinon
*/
@Override
public boolean resoudre(Sudoku s, boolean afficherEtape) {
EtatResolution etat = new EtatResolution(0, 0);
boolean solved = resoudre(s, afficherEtape, etat);
if (!solved) {
Console.errorln("Ce Sudoku n'a pas de solution");
}
return solved;
}
/**
* Méthode récursive permettant de résoudre un sudoku, utilisant la méthode de
* backtracking.
*
* @param s : sudoku à résoudre
* @param afficherEtape : afficher les étapes de la résolution
* @param etat : état de la résolution
* @return true si le sudoku est résolvable, false sinon
*/
private boolean resoudre(Sudoku s, boolean afficherEtape, EtatResolution etat) {
Grille g = s.getGrille();
List<Symbole> symboles = g.getSymbolesPossibles();
for (int i = 0; i < g.getTaille(); i++) { // Parcours des lignes
for (int j = 0; j < g.getTaille(); j++) { // Parcours des colonnes
Case c = g.getCase(i, j); // Récupération de la case
if (c.getSymbole() == null) { // Si la case est vide
for (Symbole symbole : symboles) { // Parcours des symboles possibles
c.setSymbole(symbole); // Affectation du symbole
etat.compteurGeneral++; // Incrémenter le compteur général
if (afficherEtape) {
afficherEtapeResolution(s, etat.compteur, etat.compteurGeneral);
}
if (s.estValide(c)) { // Si la grille est valide
etat.compteur++;
if (resoudre(s, afficherEtape, etat)) { // Résolution récursive
return true; // Si la grille est résolue
}
etat.compteur--;
}
c.setSymbole(null); // Réinitialisation de la case
}
return false; // Si aucun symbole ne convient
}
}
}
return true; // Si la grille est déjà résolue
}
/**
* Méthode permettant d'afficher le sudoku à chaque étape de sa résolution
*
* @param s : sudoku
* @param compteur : compteur de l'étape en cours
* @param compteurGeneral : compteur général de la résolution du sudoku (nombre
* total de tentatives)
*/
private void afficherEtapeResolution(Sudoku s, int compteur, int compteurGeneral) {
System.out.println("Sudoku, Etape " + compteur + " (Tentative " + compteurGeneral + ")");
System.out.println(s.getGrille().toString());
}
/**
* Classe interne permettant de stocker l'état de la résolution
*/
private static class EtatResolution {
int compteur;
int compteurGeneral;
/**
* Méthode permettant de fixer l'état de la résolution
*
* @param compteur : compteur de l'étape en cours
* @param compteurGeneral : compteur général de la résolution du sudoku (nombre
* total de tentatives)
*/
EtatResolution(int compteur, int compteurGeneral) {
this.compteur = compteur;
this.compteurGeneral = compteurGeneral;
}
}
}