feat: implement multidoku resolution with shared constraints (without case propagation)

This commit is contained in:
2025-02-07 18:25:02 +01:00
parent dd21b9a13a
commit bf9bfc8323
3 changed files with 216 additions and 47 deletions

View File

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