fix mixedsolver

This commit is contained in:
2025-02-02 22:56:14 +01:00
parent 71666a3883
commit edfc5733db

View File

@@ -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<Cell> findCellsToBacktrack(MultiDoku doku, int maxPossibilities) {
List<Cell> cells = new ArrayList<>();
for (Cell cell : doku.getCells()) {
if (!cell.isMutable() || !cell.isEmpty())
continue;
List<Integer> 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<Integer> 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<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) {
int maxPossibilities = 2;
Cell backtrackCell = null;
while (backtrackCell == null) {
backtrackCell = findCellToBacktrack(doku, maxPossibilities);
maxPossibilities++;
}
// on fait du backtracking
List<Integer> 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<Cell> 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<Integer> 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;
}
}