2 Commits

Author SHA1 Message Date
2595af2d48 doc solver
All checks were successful
Linux arm64 / Build (push) Successful in 44s
2025-02-02 22:56:19 +01:00
edfc5733db fix mixedsolver 2025-02-02 22:56:14 +01:00
2 changed files with 55 additions and 32 deletions

View File

@@ -1,5 +1,6 @@
package sudoku.solver; package sudoku.solver;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
@@ -8,17 +9,22 @@ import sudoku.structure.MultiDoku;
public class MixedSolver implements Solver { public class MixedSolver implements Solver {
private Cell findCellToBacktrack(MultiDoku doku, int maxPossibilities) { private List<Cell> findCellsToBacktrack(MultiDoku doku, int maxPossibilities) {
List<Cell> cells = new ArrayList<>();
for (Cell cell : doku.getCells()) { for (Cell cell : doku.getCells()) {
if (!cell.isMutable() || !cell.isEmpty()) if (!cell.isMutable() || !cell.isEmpty())
continue; continue;
List<Integer> possibleSymbols = cell.getPossibleSymbols(); List<Integer> possibleSymbols = cell.getPossibleSymbols();
if (possibleSymbols.size() == maxPossibilities) { if (possibleSymbols.size() == maxPossibilities) {
return cell; cells.add(cell);
} }
// une cellule nous empêche de continuer
if (possibleSymbols.size() == 0)
return null;
} }
return null; return cells;
} }
/** /**
@@ -34,41 +40,51 @@ public class MixedSolver implements Solver {
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
} }
while (!doku.isSolved()) { if (doku.isSolved())
boolean filledCell = false; return true;
for (Cell cell : doku.getCells()) {
if (!cell.isMutable() || !cell.isEmpty())
continue;
List<Integer> possibleSymbols = cell.getPossibleSymbols(); if (findCellsToBacktrack(doku, 0) == null)
if (possibleSymbols.size() == 1) { return false;
cell.setSymbolIndex(possibleSymbols.getFirst());
addStep(cell, steps); for (Cell cell : doku.getCells()) {
filledCell = true; if (!cell.isMutable() || !cell.isEmpty())
} continue;
List<Integer> possibleSymbols = cell.getPossibleSymbols();
if (possibleSymbols.size() == 1) {
cell.setSymbolIndex(possibleSymbols.getFirst());
addStep(cell, steps);
if (solve(doku, steps))
return true;
cell.setSymbolIndex(Cell.NOSYMBOL);
addStep(cell, steps);
return false;
} }
// on ne peut plus remplir de cases, on tente de backtrack }
if (!filledCell) { // on ne peut plus remplir de cases, on tente de backtrack
int maxPossibilities = 2; int maxPossibilities = 2;
Cell backtrackCell = null; List<Cell> backtrackCells = new ArrayList<>();
while (backtrackCell == null) { while (backtrackCells.isEmpty()) {
backtrackCell = findCellToBacktrack(doku, maxPossibilities); backtrackCells = findCellsToBacktrack(doku, maxPossibilities);
maxPossibilities++; if (backtrackCells == null || maxPossibilities > doku.getSubGrid(0).getSize())
} return false;
// on fait du backtracking maxPossibilities++;
List<Integer> possibilities = backtrackCell.getPossibleSymbols(); }
for (int symbol : possibilities) { // on fait du backtracking
doku.getStateManager().pushState(); for (Cell backtrackCell : backtrackCells) {
backtrackCell.setSymbolIndex(symbol); List<Integer> possibilities = backtrackCell.getPossibleSymbols();
if (solve(doku, steps)) for (int symbol : possibilities) {
return true; backtrackCell.setSymbolIndex(symbol);
doku.getStateManager().popState(); addStep(backtrackCell, steps);
} if (solve(doku, steps))
return true;
} }
backtrackCell.setSymbolIndex(Cell.NOSYMBOL);
addStep(backtrackCell, steps);
} }
return true; return false;
} }
} }

View File

@@ -52,6 +52,13 @@ public interface Solver {
return result; return result;
} }
/**
* Méthode utilisée en interne afin de rajouter une étape si l'utilisateur le
* souhaite (steps non null)
*
* @param cell la cellule qui a été modifiée
* @param steps la liste d'étape à mettre à jour
*/
default void addStep(Cell cell, List<SolverStep> steps) { default void addStep(Cell cell, List<SolverStep> steps) {
if (steps == null) if (steps == null)
return; return;