diff --git a/app/src/main/java/sudoku/Multidoku.java b/app/src/main/java/sudoku/Multidoku.java index 1b3eeae..f8cfd1a 100644 --- a/app/src/main/java/sudoku/Multidoku.java +++ b/app/src/main/java/sudoku/Multidoku.java @@ -162,4 +162,69 @@ public class Multidoku { return true; } + + public boolean resoudreMultidoku(boolean afficherEtape) { + // Pour chaque sudoku (dans l'ordre des placements) + for (SudokuPlacement sp : placements) { + Sudoku s = sp.getSudoku(); + // Propagation des valeurs partagées avant de résoudre ce sudoku + for (List sharedGroup : casesPartagees) { + // On parcourt le groupe pour trouver, le cas échéant, une valeur de référence + Symbole valeurReference = null; + boolean sudokuContientUneCasePartagee = false; + for (Case c : sharedGroup) { + if (belongsToSudoku(c, s)) { + sudokuContientUneCasePartagee = true; + } + if (c.getSymbole() != null) { + if (valeurReference == null) { + valeurReference = c.getSymbole(); + } else if (!c.getSymbole().equals(valeurReference)) { + System.out.println("Conflit de valeurs dans un groupe partagé avant résolution."); + return false; + } + } + } + // Si le sudoku contient une case partagée et qu'une valeur a été définie, on la + // propage + if (valeurReference != null && sudokuContientUneCasePartagee) { + for (Case c : sharedGroup) { + if (belongsToSudoku(c, s) && c.getSymbole() == null) { + c.setSymbole(valeurReference); + } + } + } + } + // Résolution du sudoku courant par backtracking + ResolveurBacktraceSimple resolver = new ResolveurBacktraceSimple(s); + if (!resolver.resoudre(s, afficherEtape)) { + System.out.println("Échec de la résolution pour un sudoku."); + return false; + } + } + // Vérification finale des contraintes partagées + if (!verifierContraintesPartagees()) { + System.out.println("Les contraintes partagées ne sont pas respectées !"); + return false; + } + return true; + } + + /** + * Méthode utilitaire qui vérifie si une case fait partie du sudoku donné. + * On parcourt la grille du sudoku et on compare les instances. + */ + private boolean belongsToSudoku(Case c, Sudoku s) { + Grille g = s.getGrille(); + int taille = g.getTaille(); + for (int i = 0; i < taille; i++) { + for (int j = 0; j < taille; j++) { + if (g.getCase(i, j) == c) { + return true; + } + } + } + return false; + } + } diff --git a/app/src/test/java/sudoku/TestMultidoku.java b/app/src/test/java/sudoku/TestMultidoku.java index 979694e..6474661 100644 --- a/app/src/test/java/sudoku/TestMultidoku.java +++ b/app/src/test/java/sudoku/TestMultidoku.java @@ -1,60 +1,73 @@ -package sudoku; +// package sudoku; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +// import java.util.ArrayList; +// import java.util.Arrays; +// import java.util.List; -import org.junit.jupiter.api.Test; +// import org.junit.jupiter.api.Test; -public class TestMultidoku { +// public class TestMultidoku { - @Test - public void testMultidoku() { - Multidoku multidoku = new Multidoku(); - Sudoku s1 = new Sudoku(9); - Sudoku s2 = new Sudoku(9); +// @Test +// public void testMultidoku() { +// Multidoku multidoku = new Multidoku(); +// Sudoku s1 = new Sudoku(9); +// Sudoku s2 = new Sudoku(9); - // Placer sudoku1 en haut à gauche (offset (0,0)) - multidoku.ajouterSudoku(s1, 0, 0); - // Placer sudoku2 de façon à ce que sa case (0,0) se retrouve en (8,8) de la - // grille globale - multidoku.ajouterSudoku(s2, 8, 8); +// // Placer sudoku1 en haut à gauche (offset (0,0)) +// multidoku.ajouterSudoku(s1, 0, 0); +// // Placer sudoku2 de façon à ce que sa case (0,0) se retrouve en (8,8) de la +// // grille globale +// multidoku.ajouterSudoku(s2, 8, 8); - // Créer un lien entre la case (8,8) de s1 et (0,0) de s2 - List casesPartagees = Arrays.asList( - s1.getGrille().getCase(8, 8), - s2.getGrille().getCase(0, 0)); - multidoku.ajouterCasesPartagees(casesPartagees); +// // Créer un lien entre la case (8,8) de s1 et (0,0) de s2 +// List casesPartagees = Arrays.asList( +// s1.getGrille().getCase(8, 8), +// s2.getGrille().getCase(0, 0)); +// multidoku.ajouterCasesPartagees(casesPartagees); - multidoku.ajouterContraintePartagee(new ContrainteCasePartagee(casesPartagees)); +// multidoku.ajouterContraintePartagee(new ContrainteCasePartagee(casesPartagees)); - ArrayList symboles = new ArrayList<>(); - for (int i = 10; i <= 19; i++) { - symboles.add(Symbole.of(i)); - } +// ArrayList symboles = new ArrayList<>(); +// for (int i = 10; i <= 19; i++) { +// symboles.add(Symbole.of(i)); +// } - s1.getGrille().setSymbolesPossibles(symboles); - List sudokus = Arrays.asList(s1, s2); - for (Sudoku sudoku : sudokus) { - sudoku.getGrille().setSymbolesPossibles(symboles); - sudoku.ajouterContrainte(new ContrainteLigne()); - sudoku.ajouterContrainte(new ContrainteColonne()); - sudoku.ajouterContrainte(new ContrainteBloc()); - sudoku.getGrille().creerBlocCarre(); +// s1.getGrille().setSymbolesPossibles(symboles); +// List sudokus = Arrays.asList(s1, s2); +// for (Sudoku sudoku : sudokus) { +// sudoku.getGrille().setSymbolesPossibles(symboles); +// sudoku.ajouterContrainte(new ContrainteLigne()); +// sudoku.ajouterContrainte(new ContrainteColonne()); +// sudoku.ajouterContrainte(new ContrainteBloc()); +// sudoku.getGrille().creerBlocCarre(); - for (int i = 0; i < sudoku.getGrille().getTaille(); i++) { - sudoku.getGrille().setCase(i, i, symboles.get(i)); - } - } +// } - System.out.println("Sudoku 1 :"); - System.out.println(s1.getGrille().toString()); +// for (int i = 0; i < s1.getGrille().getTaille(); i++) { +// s1.getGrille().setCase(i, i, symboles.get(i)); +// } - System.out.println("Sudoku 2 :"); - System.out.println(s2.getGrille().toString()); +// System.out.println("Sudoku 1 :"); +// System.out.println(s1.getGrille().toString()); - System.out.println("\nAffichage Multidoku combiné :"); - // TODO: Afficher le Multidoku combiné - System.out.println(multidoku.toStringCombined()); - } -} +// System.out.println("Sudoku 2 :"); +// System.out.println(s2.getGrille().toString()); + +// System.out.println("\nAffichage Multidoku combiné :"); +// System.out.println(multidoku.toStringCombined()); + +// if (multidoku.resoudreMultidoku(false)) { +// System.out.println("Multidoku résolu !"); +// System.out.println(multidoku.toStringCombined()); +// } else { +// System.out.println("Échec de la résolution du multidoku."); +// } + +// System.out.println("Sudoku 1 résolu :"); +// System.out.println(s1.getGrille().toString()); + +// System.out.println("Sudoku 2 résolu :"); +// System.out.println(s2.getGrille().toString()); +// } +// } diff --git a/app/src/test/java/sudoku/TestMultidokuBloc.java b/app/src/test/java/sudoku/TestMultidokuBloc.java new file mode 100644 index 0000000..549a398 --- /dev/null +++ b/app/src/test/java/sudoku/TestMultidokuBloc.java @@ -0,0 +1,91 @@ +package sudoku; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class TestMultidokuBloc { + + @Test + public void testMultidokuBloc() { + Multidoku multidoku = new Multidoku(); + Sudoku s1 = new Sudoku(9); + Sudoku s2 = new Sudoku(9); + + // Placer sudoku1 en haut à gauche (offset (0,0)) + multidoku.ajouterSudoku(s1, 0, 0); + + // Placer sudoku2 de façon à ce que sa case (0,0) se retrouve en (6,6) de la + // grille globale + multidoku.ajouterSudoku(s2, 6, 6); + + // Créer un lien entre la case (6,6) de s1 et (0,0) de s2 + List casesPartagees = Arrays.asList( + s1.getGrille().getCase(6, 6), + s1.getGrille().getCase(6, 7), + s1.getGrille().getCase(6, 8), + s1.getGrille().getCase(7, 6), + s1.getGrille().getCase(7, 7), + s1.getGrille().getCase(7, 8), + s1.getGrille().getCase(8, 6), + s1.getGrille().getCase(8, 7), + s1.getGrille().getCase(8, 8), + + s2.getGrille().getCase(0, 0), + s2.getGrille().getCase(0, 1), + s2.getGrille().getCase(0, 2), + s2.getGrille().getCase(1, 0), + s2.getGrille().getCase(1, 1), + s2.getGrille().getCase(1, 2), + s2.getGrille().getCase(2, 0), + s2.getGrille().getCase(2, 1), + s2.getGrille().getCase(2, 2)); + multidoku.ajouterCasesPartagees(casesPartagees); + + multidoku.ajouterContraintePartagee(new ContrainteCasePartagee(casesPartagees)); + + ArrayList symboles = new ArrayList<>(); + for (int i = 10; i <= 19; i++) { + symboles.add(Symbole.of(i)); + } + + s1.getGrille().setSymbolesPossibles(symboles); + List sudokus = Arrays.asList(s1, s2); + for (Sudoku sudoku : sudokus) { + sudoku.getGrille().setSymbolesPossibles(symboles); + sudoku.ajouterContrainte(new ContrainteLigne()); + sudoku.ajouterContrainte(new ContrainteColonne()); + sudoku.ajouterContrainte(new ContrainteBloc()); + sudoku.getGrille().creerBlocCarre(); + + } + + for (int i = 0; i < s1.getGrille().getTaille(); i++) { + s1.getGrille().setCase(i, i, symboles.get(i)); + } + + System.out.println("Sudoku 1 :"); + System.out.println(s1.getGrille().toString()); + + System.out.println("Sudoku 2 :"); + System.out.println(s2.getGrille().toString()); + + System.out.println("\nAffichage Multidoku combiné :"); + System.out.println(multidoku.toStringCombined()); + + if (multidoku.resoudreMultidoku(false)) { + System.out.println("Multidoku résolu :"); + System.out.println(multidoku.toStringCombined()); + } else { + System.out.println("Multidoku non résolu"); + } + + System.out.println("Sudoku 1 résolu :"); + System.out.println(s1.getGrille().toString()); + + System.out.println("Sudoku 2 résolu :"); + System.out.println(s2.getGrille().toString()); + } +}