2 Commits

Author SHA1 Message Date
91c645e34f fix steps
All checks were successful
Linux arm64 / Build (push) Successful in 43s
2025-02-01 23:00:36 +01:00
78bdefebe5 feat: add history 2025-02-01 22:54:02 +01:00
7 changed files with 64 additions and 21 deletions

View File

@@ -1,5 +1,7 @@
package gui.menu; package gui.menu;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import gui.widget.SudokuRenderer; import gui.widget.SudokuRenderer;
@@ -11,6 +13,7 @@ import sudoku.solver.HintHelper;
import sudoku.solver.HumanSolver; import sudoku.solver.HumanSolver;
import sudoku.solver.MixedSolver; import sudoku.solver.MixedSolver;
import sudoku.solver.Solver; import sudoku.solver.Solver;
import sudoku.solver.SolverStep;
import sudoku.solver.HintHelper.Hint; import sudoku.solver.HintHelper.Hint;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
@@ -90,8 +93,9 @@ public class SudokuView extends BaseView {
private void startSolve(Solver solver) { private void startSolve(Solver solver) {
resolveThread = new Thread(() -> { resolveThread = new Thread(() -> {
List<SolverStep> steps = new ArrayList<>();
try { try {
unresolved = !solver.solve(this.doku); unresolved = !solver.solve(this.doku, steps);
} catch (CancellationException e) { } catch (CancellationException e) {
System.out.println("The user is bored !"); System.out.println("The user is bored !");
} }

View File

@@ -15,7 +15,7 @@ public class BacktrackingSolver implements Solver {
* @return boolean, valant true si le MultiDoku est résolu, false sinon. * @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/ */
@Override @Override
public boolean solve(MultiDoku doku) { public boolean solve(MultiDoku doku, List<SolverStep> steps) {
if (Thread.interrupted()) if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
@@ -34,14 +34,14 @@ public class BacktrackingSolver implements Solver {
} }
for (int symbol : possibleSymbols) { for (int symbol : possibleSymbols) {
cellToFill.setSymbolIndex(symbol); cellToFill.setSymbolIndex(symbol);
if (this.solve(doku)) { addStep(cellToFill, steps);
if (this.solve(doku, steps)) {
return true; return true;
} else { } else {
cellToFill.setSymbolIndex(Cell.NOSYMBOL); cellToFill.setSymbolIndex(Cell.NOSYMBOL);
addStep(cellToFill, steps);
} }
} }
return false; return false;
} }

View File

@@ -19,7 +19,7 @@ public class HumanSolver implements Solver {
* @return boolean, valant true si le MultiDoku est résolu, false sinon. * @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/ */
@Override @Override
public boolean solve(MultiDoku doku) { public boolean solve(MultiDoku doku, List<SolverStep> steps) {
if (Thread.interrupted()) if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver"); throw new CancellationException("User wants to stop the solver");
@@ -28,7 +28,7 @@ public class HumanSolver implements Solver {
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku, '\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(), sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(), sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(),
Symbols.Numbers)); Symbols.Numbers));
if (doku.isSolved()) { if (doku.isSolved()) {
return true; return true;
@@ -47,8 +47,9 @@ public class HumanSolver implements Solver {
} }
cellToFill.setSymbolIndex(possibleSymbols.getFirst()); cellToFill.setSymbolIndex(possibleSymbols.getFirst());
addStep(cellToFill, steps);
return this.solve(doku); return this.solve(doku, steps);
} }
return doku.isSolved(); return doku.isSolved();

View File

@@ -11,17 +11,17 @@ import sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import sudoku.structure.Sudoku;
public class MixedSolver implements Solver{ public class MixedSolver implements Solver {
/** /**
* Résout le MultiDoku passé en paramètre, avec règles de déduction et * Résout le MultiDoku passé en paramètre, avec règles de déduction et
* backtracking. * backtracking.
* *
* @param doku MultiDoku, MultiDoku à résoudre. * @param doku MultiDoku, MultiDoku à résoudre.
* @return boolean, valant true si le MultiDoku est résolu, false sinon. * @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/ */
@Override @Override
public boolean solve(MultiDoku doku) { public boolean solve(MultiDoku doku, List<SolverStep> steps) {
Random rand = new Random(); Random rand = new Random();
if (Thread.interrupted()) { if (Thread.interrupted()) {
@@ -49,7 +49,8 @@ public class MixedSolver implements Solver{
if (possibleSymbols.size() == 1) { if (possibleSymbols.size() == 1) {
cellToFill.setSymbolIndex(possibleSymbols.getFirst()); cellToFill.setSymbolIndex(possibleSymbols.getFirst());
if (this.solve(doku)) { addStep(cellToFill, steps);
if (this.solve(doku, steps)) {
return true; return true;
} }
} }
@@ -59,10 +60,12 @@ public class MixedSolver implements Solver{
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex); int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol); cellToFill.setSymbolIndex(nextSymbol);
if (this.solve(doku)) { addStep(cellToFill, steps);
if (this.solve(doku, steps)) {
return true; return true;
} }
cellToFill.setSymbolIndex(Cell.NOSYMBOL); cellToFill.setSymbolIndex(Cell.NOSYMBOL);
addStep(cellToFill, steps);
possibleSymbols.remove(nextPossibleSymbolIndex); possibleSymbols.remove(nextPossibleSymbolIndex);
} }

View File

@@ -13,7 +13,7 @@ import sudoku.structure.Sudoku;
public class RandomSolver implements Solver { public class RandomSolver implements Solver {
/** /**
* Résout, si possible, le multidoku passé en paramètre * Résout, si possible, le multidoku passé en paramètre
* en testant toutes les possibilités, de manière aléatoire, avec un algorithme * en testant toutes les possibilités, de manière aléatoire, avec un algorithme
* de backtracking. * de backtracking.
@@ -21,8 +21,8 @@ public class RandomSolver implements Solver {
* @param doku Multidoku, à résoudre * @param doku Multidoku, à résoudre
* @return boolean, true s'il est résolu ou false s'il ne l'est pas. * @return boolean, true s'il est résolu ou false s'il ne l'est pas.
*/ */
@Override @Override
public boolean solve(MultiDoku doku) { public boolean solve(MultiDoku doku, List<SolverStep> steps) {
Random rand = new Random(); Random rand = new Random();
if (Thread.interrupted()) if (Thread.interrupted())
@@ -51,10 +51,12 @@ public class RandomSolver implements Solver {
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex); int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol); cellToFill.setSymbolIndex(nextSymbol);
if (this.solve(doku)) { addStep(cellToFill, steps);
if (this.solve(doku, steps)) {
return true; return true;
} }
cellToFill.setSymbolIndex(Cell.NOSYMBOL); cellToFill.setSymbolIndex(Cell.NOSYMBOL);
addStep(cellToFill, steps);
possibleSymbols.remove(nextPossibleSymbolIndex); possibleSymbols.remove(nextPossibleSymbolIndex);
} }

View File

@@ -8,14 +8,18 @@ import sudoku.structure.MultiDoku;
public interface Solver { public interface Solver {
/** /**
* Log du Solver, qui garde trace des actions réalisées. * Log du Solver, qui garde trace des actions réalisées.
*/ */
public static final Logger logger = Logger.getLogger("SolverLogger"); public static final Logger logger = Logger.getLogger("SolverLogger");
boolean solve(MultiDoku doku); boolean solve(MultiDoku doku, List<SolverStep> solverSteps);
/** default boolean solve(MultiDoku doku) {
return solve(doku, null);
}
/**
* Compte le nombre de solutions possibles au MultiDoku passé en paramètres. * Compte le nombre de solutions possibles au MultiDoku passé en paramètres.
* *
* @param doku MultiDoku, MultiDoku dont on veut le nombre de solutions. * @param doku MultiDoku, MultiDoku dont on veut le nombre de solutions.
@@ -44,4 +48,10 @@ public interface Solver {
return result; return result;
} }
default void addStep(Cell cell, List<SolverStep> steps) {
if (steps == null)
return;
steps.add(new SolverStep(cell));
}
} }

View File

@@ -0,0 +1,23 @@
package sudoku.solver;
import sudoku.structure.Cell;
public class SolverStep {
private final Cell cell;
private final int newValue;
public SolverStep(Cell cell) {
this.cell = cell;
this.newValue = cell.getSymbolIndex();
}
public int getNewValue() {
return newValue;
}
public Cell getCell() {
return cell;
}
}