feat: add history
This commit is contained in:
@@ -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);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
if (this.solve(doku)) {
|
if (this.solve(doku)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,6 +47,7 @@ public class HumanSolver implements Solver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
|
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
|
||||||
|
addStep(cellToFill, steps);
|
||||||
|
|
||||||
return this.solve(doku);
|
return this.solve(doku);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,6 +49,7 @@ public class MixedSolver implements Solver{
|
|||||||
|
|
||||||
if (possibleSymbols.size() == 1) {
|
if (possibleSymbols.size() == 1) {
|
||||||
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
|
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
|
||||||
|
addStep(cellToFill, steps);
|
||||||
if (this.solve(doku)) {
|
if (this.solve(doku)) {
|
||||||
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);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
if (this.solve(doku)) {
|
if (this.solve(doku)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
possibleSymbols.remove(nextPossibleSymbolIndex);
|
possibleSymbols.remove(nextPossibleSymbolIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
if (this.solve(doku)) {
|
if (this.solve(doku)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
||||||
|
addStep(cellToFill, steps);
|
||||||
possibleSymbols.remove(nextPossibleSymbolIndex);
|
possibleSymbols.remove(nextPossibleSymbolIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
23
app/src/main/java/sudoku/solver/SolverStep.java
Normal file
23
app/src/main/java/sudoku/solver/SolverStep.java
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user