diff --git a/app/src/main/java/sudoku/solver/MixedSolver.java b/app/src/main/java/sudoku/solver/MixedSolver.java index e2ad05a..402e0d2 100644 --- a/app/src/main/java/sudoku/solver/MixedSolver.java +++ b/app/src/main/java/sudoku/solver/MixedSolver.java @@ -1,5 +1,6 @@ package sudoku.solver; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.CancellationException; @@ -8,17 +9,22 @@ import sudoku.structure.MultiDoku; public class MixedSolver implements Solver { - private Cell findCellToBacktrack(MultiDoku doku, int maxPossibilities) { + private List findCellsToBacktrack(MultiDoku doku, int maxPossibilities) { + List cells = new ArrayList<>(); for (Cell cell : doku.getCells()) { if (!cell.isMutable() || !cell.isEmpty()) continue; List possibleSymbols = cell.getPossibleSymbols(); 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"); } - while (!doku.isSolved()) { - boolean filledCell = false; - for (Cell cell : doku.getCells()) { - if (!cell.isMutable() || !cell.isEmpty()) - continue; + if (doku.isSolved()) + return true; - List possibleSymbols = cell.getPossibleSymbols(); - if (possibleSymbols.size() == 1) { - cell.setSymbolIndex(possibleSymbols.getFirst()); - addStep(cell, steps); - filledCell = true; - } + if (findCellsToBacktrack(doku, 0) == null) + return false; + + for (Cell cell : doku.getCells()) { + if (!cell.isMutable() || !cell.isEmpty()) + continue; + + List 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) { - int maxPossibilities = 2; - Cell backtrackCell = null; - while (backtrackCell == null) { - backtrackCell = findCellToBacktrack(doku, maxPossibilities); - maxPossibilities++; - } - // on fait du backtracking - List possibilities = backtrackCell.getPossibleSymbols(); - for (int symbol : possibilities) { - doku.getStateManager().pushState(); - backtrackCell.setSymbolIndex(symbol); - if (solve(doku, steps)) - return true; - doku.getStateManager().popState(); - } + } + // on ne peut plus remplir de cases, on tente de backtrack + int maxPossibilities = 2; + List backtrackCells = new ArrayList<>(); + while (backtrackCells.isEmpty()) { + backtrackCells = findCellsToBacktrack(doku, maxPossibilities); + if (backtrackCells == null || maxPossibilities > doku.getSubGrid(0).getSize()) + return false; + maxPossibilities++; + } + // on fait du backtracking + for (Cell backtrackCell : backtrackCells) { + List possibilities = backtrackCell.getPossibleSymbols(); + for (int symbol : possibilities) { + backtrackCell.setSymbolIndex(symbol); + addStep(backtrackCell, steps); + if (solve(doku, steps)) + return true; } + backtrackCell.setSymbolIndex(Cell.NOSYMBOL); + addStep(backtrackCell, steps); } - return true; + return false; } }