package sudoku;

import java.util.List;

public class ResolveurBacktraceSimple implements Resolveur {

    private final Sudoku sudoku;

    public ResolveurBacktraceSimple(Sudoku sudoku) {
        this.sudoku = sudoku;
    }

    @Override
    public boolean resoudre(Sudoku s, boolean afficherEtape) {
        EtatResolution etat = new EtatResolution(0, 0);
        return resoudre(s, afficherEtape, etat);
    }

    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
    }

    private void afficherEtapeResolution(Sudoku s, int compteur, int compteurGeneral) {
        System.out.println("Sudoku, Etape " + compteur + " (Tentative " + compteurGeneral + ")");
        System.out.println(s.getGrille().toString());
    }

    private static class EtatResolution {
        int compteur;
        int compteurGeneral;

        EtatResolution(int compteur, int compteurGeneral) {
            this.compteur = compteur;
            this.compteurGeneral = compteurGeneral;
        }
    }
}