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 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; } } }