refactor solvers
All checks were successful
Linux arm64 / Build (push) Successful in 42s

This commit is contained in:
2025-01-30 18:05:18 +01:00
parent 1f92c49f3c
commit a74bf42e59
11 changed files with 299 additions and 249 deletions

View File

@@ -1,12 +1,14 @@
package gui.menu; package gui.menu;
import java.util.Random;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import gui.SudokuRenderer; import gui.SudokuRenderer;
import imgui.ImGui; import imgui.ImGui;
import imgui.ImGuiStyle; import imgui.ImGuiStyle;
import sudoku.io.SudokuSerializer; import sudoku.io.SudokuSerializer;
import sudoku.solver.BacktrackingSolver;
import sudoku.solver.HumanSolver;
import sudoku.solver.MixedSolver;
import sudoku.solver.Solver; import sudoku.solver.Solver;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
@@ -66,41 +68,29 @@ public class SudokuView extends BaseView {
stopResolve(); stopResolve();
} }
private void startSolve(Solver solver) {
resolveThread = new Thread(() -> {
try {
solver.solve(this.doku);
} catch (CancellationException e) {
System.out.println("The user is bored !");
}
stopResolve();
});
}
private void renderSolvePopup() { private void renderSolvePopup() {
if (ImGui.beginPopup("solve")) { if (ImGui.beginPopup("solve")) {
if (ImGui.button("Résoudre avec backtrace")) { if (ImGui.button("Résoudre avec backtrace")) {
resolveThread = new Thread(() -> { startSolve(new BacktrackingSolver());
try {
Random rand = new Random();
Solver.randomSolve(doku, rand);
} catch (CancellationException e) {
System.out.println("The user is bored !");
}
stopResolve();
});
ImGui.closeCurrentPopup(); ImGui.closeCurrentPopup();
} }
if (ImGui.button("Résoudre avec déduction")) { if (ImGui.button("Résoudre avec déduction")) {
resolveThread = new Thread(() -> { startSolve(new HumanSolver());
try {
Solver.humanSolve(doku);
} catch (CancellationException e) {
System.out.println("The user is bored !");
}
stopResolve();
});
ImGui.closeCurrentPopup(); ImGui.closeCurrentPopup();
} }
if (ImGui.button("Résoudre avec déduction et backtrace")) { if (ImGui.button("Résoudre avec déduction et backtrace")) {
resolveThread = new Thread(() -> { startSolve(new MixedSolver());
try {
Random rand = new Random();
Solver.mixedSolve(doku, rand);
} catch (CancellationException e) {
System.out.println("The user is bored !");
}
stopResolve();
});
ImGui.closeCurrentPopup(); ImGui.closeCurrentPopup();
} }
ImGui.endPopup(); ImGui.endPopup();

View File

@@ -1,17 +1,16 @@
package sudoku.io; package sudoku.io;
import sudoku.constraint.*; import java.util.ArrayList;
import sudoku.solver.Solver; import java.util.List;
import java.util.Scanner;
import sudoku.constraint.Constraint;
import sudoku.solver.RandomSolver;
import sudoku.structure.Difficulty; import sudoku.structure.Difficulty;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import sudoku.structure.Sudoku;
import sudoku.structure.SudokuFactory; import sudoku.structure.SudokuFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class ConsoleInterface { public class ConsoleInterface {
public Scanner reader = new Scanner(System.in); public Scanner reader = new Scanner(System.in);
@@ -133,7 +132,7 @@ public class ConsoleInterface {
} }
private void generateFullDoku(MultiDoku doku) { private void generateFullDoku(MultiDoku doku) {
Solver.randomSolve(doku, new Random()); new RandomSolver().solve(doku);
} }
} }

View File

@@ -0,0 +1,49 @@
package sudoku.solver;
import java.util.List;
import java.util.concurrent.CancellationException;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
public class BacktrackingSolver implements Solver {
/**
* Résout le MultiDoku passé en paramètre, avec backtracking.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
@Override
public boolean solve(MultiDoku doku) {
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
if (doku.isSolved()) {
return true;
}
Cell cellToFill = doku.getFirstEmptyCell();
if (cellToFill == null) {
return false;
}
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.isEmpty()) {
return false;
}
for (int symbol : possibleSymbols) {
cellToFill.setSymbolIndex(symbol);
if (this.solve(doku)) {
return true;
} else {
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
}
}
return false;
}
}

View File

@@ -0,0 +1,55 @@
package sudoku.solver;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class HumanSolver implements Solver {
/**
* Résout le MultiDoku passé en paramètre, avec règles de déduction.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
@Override
public boolean solve(MultiDoku doku) {
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth()));
if (doku.isSolved()) {
return true;
}
List<Cell> cellsToFill = doku.getEmptyCells();
if (cellsToFill.isEmpty()) {
return false;
}
for (Cell cellToFill : cellsToFill) {
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.size() != 1) {
continue;
}
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
return this.solve(doku);
}
return doku.isSolved();
}
}

View File

@@ -0,0 +1,82 @@
package sudoku.solver;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class MixedSolver implements Solver{
/**
* Résout le MultiDoku passé en paramètre, avec règles de déduction et
* backtracking.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @param rand Random, pour tester aléatoirement les symboles, lors du
* backtracking.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
@Override
public boolean solve(MultiDoku doku) {
Random rand = new Random();
if (Thread.interrupted()) {
throw new CancellationException("User wants to stop the solver");
}
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(
sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth()));
if (doku.isSolved()) {
return true;
}
List<Cell> cellsToFill = doku.getEmptyCells();
if (cellsToFill.isEmpty()) {
return false;
}
// Règles de déduction
for (Cell cellToFill : cellsToFill) {
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.size() != 1) {
continue;
}
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
return this.solve(doku);
}
// Si ça ne marche pas
// On fait du backtracking
Cell cellToFill = doku.getRandomEmptyCell(rand);
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
while (!possibleSymbols.isEmpty()) {
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol);
if (this.solve(doku)) {
return true;
}
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
possibleSymbols.remove(nextPossibleSymbolIndex);
}
return false;
}
}

View File

@@ -0,0 +1,63 @@
package sudoku.solver;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class RandomSolver implements Solver {
/**
* Résout, si possible, le multidoku passé en paramètre
* en testant toutes les possibilités, de manière aléatoire, avec un algorithme
* de backtracking.
*
* @param doku Multidoku, à résoudre
* @param rand Random, pour tester aléatoirement les symboles
* @return boolean, true s'il est résolu ou false s'il ne l'est pas.
*/
@Override
public boolean solve(MultiDoku doku) {
Random rand = new Random();
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth()));
if (doku.isSolved()) {
return true;
}
Cell cellToFill = doku.getFirstEmptyCell();
if (cellToFill == null) {
return false;
}
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
while (!possibleSymbols.isEmpty()) {
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol);
if (this.solve(doku)) {
return true;
}
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
possibleSymbols.remove(nextPossibleSymbolIndex);
}
return false;
}
}

View File

@@ -1,236 +1,47 @@
package sudoku.solver; package sudoku.solver;
import java.util.List; import java.util.List;
import java.util.Random;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import sudoku.io.SudokuPrinter;
import sudoku.structure.Cell; import sudoku.structure.Cell;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku;
public class 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.
*/ */
private static final Logger logger = Logger.getLogger("SolverLogger"); public static final Logger logger = Logger.getLogger("SolverLogger");
/** boolean solve(MultiDoku doku);
* Résout, si possible, le multidoku passé en paramètre
* en testant toutes les possibilités, de manière aléatoire, avec un algorithme
* de backtracking.
*
* @param doku Multidoku, à résoudre
* @param rand Random, pour tester aléatoirement les symboles
* @return boolean, true s'il est résolu ou false s'il ne l'est pas.
*/
public static boolean randomSolve(MultiDoku doku, Random rand) {
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0); /**
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth()));
if (doku.isSolved()) {
return true;
}
Cell cellToFill = doku.getFirstEmptyCell();
if (cellToFill == null) {
return false;
}
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
while (!possibleSymbols.isEmpty()) {
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol);
if (Solver.randomSolve(doku, rand)) {
return true;
}
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
possibleSymbols.remove(nextPossibleSymbolIndex);
}
return false;
}
/**
* 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.
* @return int, nombre de solutions possibles. * @return int, nombre de solutions possibles.
*/ */
public static int countSolution(MultiDoku doku) { default int countSolution(MultiDoku doku) {
int result = 0; int result = 0;
if (doku.isSolved()) { if (doku.isSolved()) {
return 1; return 1;
} }
Cell cellToFill = doku.getFirstEmptyCell(); Cell cellToFill = doku.getFirstEmptyCell();
assert(cellToFill != null); assert (cellToFill != null);
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols(); List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
for (int symbol : possibleSymbols) { for (int symbol : possibleSymbols) {
doku.getStateManager().pushState(); doku.getStateManager().pushState();
cellToFill.setSymbolIndex(symbol); cellToFill.setSymbolIndex(symbol);
if (Solver.solve(doku)) { if (solve(doku)) {
result++; result++;
} }
doku.getStateManager().popState(); doku.getStateManager().popState();
} }
return result; return result;
} }
/**
* Résout le MultiDoku passé en paramètre, avec backtracking.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
public static boolean solve(MultiDoku doku) {
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
if (doku.isSolved()) {
return true;
}
Cell cellToFill = doku.getFirstEmptyCell();
if (cellToFill == null) {
return false;
}
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.isEmpty()) {
return false;
}
for (int symbol : possibleSymbols) {
cellToFill.setSymbolIndex(symbol);
if (Solver.solve(doku)) {
return true;
} else {
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
}
}
return false;
}
/**
* Résout le MultiDoku passé en paramètre, avec règles de déduction.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
public static boolean humanSolve(MultiDoku doku) {
if (Thread.interrupted())
throw new CancellationException("User wants to stop the solver");
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth()));
if (doku.isSolved()) {
return true;
}
List<Cell> cellsToFill = doku.getEmptyCells();
if (cellsToFill.isEmpty()) {
return false;
}
for (Cell cellToFill : cellsToFill) {
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.size() != 1) {
continue;
}
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
return Solver.humanSolve(doku);
}
return doku.isSolved();
}
/**
* Résout le MultiDoku passé en paramètre, avec règles de déduction et backtracking.
*
* @param doku MultiDoku, MultiDoku à résoudre.
* @param rand Random, pour tester aléatoirement les symboles, lors du backtracking.
* @return boolean, valant true si le MultiDoku est résolu, false sinon.
*/
public static boolean mixedSolve(MultiDoku doku, Random rand) {
if (Thread.interrupted()) {
throw new CancellationException("User wants to stop the solver");
}
Sudoku sudoku = doku.getSubGrid(0);
logger.log(Level.FINE,
'\n' + SudokuPrinter.toStringRectangleSudoku(
sudoku,
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(),
sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth())
);
if (doku.isSolved()) {
return true;
}
List<Cell> cellsToFill = doku.getEmptyCells();
if (cellsToFill.isEmpty()) {
return false;
}
//Règles de déduction
for (Cell cellToFill : cellsToFill) {
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
if (possibleSymbols.size() != 1) {
continue;
}
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
return Solver.mixedSolve(doku, rand);
}
//Si ça ne marche pas
//On fait du backtracking
Cell cellToFill = doku.getRandomEmptyCell(rand);
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
while (!possibleSymbols.isEmpty()) {
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
cellToFill.setSymbolIndex(nextSymbol);
if (Solver.mixedSolve(doku, rand)) {
return true;
}
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
possibleSymbols.remove(nextPossibleSymbolIndex);
}
return false;
}
} }

View File

@@ -2,7 +2,6 @@ package sudoku.solver;
import java.util.concurrent.CancellationException; import java.util.concurrent.CancellationException;
import sudoku.structure.Coordinate;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.Sudoku; import sudoku.structure.Sudoku;

View File

@@ -9,9 +9,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
import sudoku.io.SudokuSerializer;
import sudoku.constraint.Constraint; import sudoku.constraint.Constraint;
import sudoku.io.SudokuSerializer;
import sudoku.solver.RandomSolver;
import sudoku.solver.Solver; import sudoku.solver.Solver;
public class SudokuFactory { public class SudokuFactory {
@@ -116,7 +116,7 @@ public class SudokuFactory {
* @return boolean, valant true si un MultiDoku de difficulté donnée peut être créée, false sinon. * @return boolean, valant true si un MultiDoku de difficulté donnée peut être créée, false sinon.
* @throws Exception si la difficulté n'est pas compatible avec la taille du MultiDoku. * @throws Exception si la difficulté n'est pas compatible avec la taille du MultiDoku.
*/ */
public static boolean newDokuFromFilledOne(MultiDoku doku, int nbCellsToEmpty) throws Exception { public static boolean newDokuFromFilledOne(MultiDoku doku, int nbCellsToEmpty, Solver solver) throws Exception {
if (nbCellsToEmpty >= doku.getCells().size()) { if (nbCellsToEmpty >= doku.getCells().size()) {
throw new Exception(); throw new Exception();
@@ -134,9 +134,9 @@ public class SudokuFactory {
int oldSymbol = cellToEmpty.empty(); int oldSymbol = cellToEmpty.empty();
int nbDokuSultions = Solver.countSolution(doku); int nbDokuSultions = solver.countSolution(doku);
if (nbDokuSultions == 1) { if (nbDokuSultions == 1) {
if (newDokuFromFilledOne(doku, --nbCellsToEmpty)) { if (newDokuFromFilledOne(doku, --nbCellsToEmpty, solver)) {
return true; return true;
} }
} }
@@ -145,7 +145,7 @@ public class SudokuFactory {
cellsThatCanBeEmptied.remove(cellToEmpty); cellsThatCanBeEmptied.remove(cellToEmpty);
} }
return newDokuFromFilledOne(doku, --nbCellsToEmpty); return newDokuFromFilledOne(doku, --nbCellsToEmpty, solver);
} }
/** /**
@@ -272,9 +272,10 @@ public class SudokuFactory {
} }
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception { public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
Solver.randomSolve(doku, random); Solver solver = new RandomSolver();
solver.solve(doku);
int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells());
boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty); boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver);
if (!successfull) { if (!successfull) {
throw new Exception("Canno't create this doku with this difficulty"); throw new Exception("Canno't create this doku with this difficulty");
} }

View File

@@ -10,7 +10,7 @@ import org.json.JSONObject;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import sudoku.io.SudokuSerializer; import sudoku.io.SudokuSerializer;
import sudoku.solver.Solver; import sudoku.solver.RandomSolver;
import sudoku.structure.MultiDoku; import sudoku.structure.MultiDoku;
import sudoku.structure.SudokuFactory; import sudoku.structure.SudokuFactory;
@@ -19,7 +19,7 @@ public class SudokuSerializerTest {
void testSerializeWithSize(int blockWidth, int blockHeight) { void testSerializeWithSize(int blockWidth, int blockHeight) {
var sudoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight, var sudoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
SudokuFactory.DEFAULT_CONSTRAINTS); SudokuFactory.DEFAULT_CONSTRAINTS);
Solver.randomSolve(sudoku, new Random()); new RandomSolver().solve(sudoku);
JSONObject data = SudokuSerializer.serializeSudoku(sudoku); JSONObject data = SudokuSerializer.serializeSudoku(sudoku);
MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data); MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data);
assertTrue(data.toString().equals(SudokuSerializer.serializeSudoku(multiDoku).toString())); assertTrue(data.toString().equals(SudokuSerializer.serializeSudoku(multiDoku).toString()));
@@ -28,14 +28,15 @@ public class SudokuSerializerTest {
void testSaveWithSize(int blockWidth, int blockHeight) { void testSaveWithSize(int blockWidth, int blockHeight) {
MultiDoku doku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight, MultiDoku doku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
SudokuFactory.DEFAULT_CONSTRAINTS); SudokuFactory.DEFAULT_CONSTRAINTS);
Solver.randomSolve(doku, new Random()); new RandomSolver().solve(doku);
String savePath = SudokuSerializer.saveMultiDoku(doku); String savePath = SudokuSerializer.saveMultiDoku(doku);
MultiDoku otherDoku = null; MultiDoku otherDoku = null;
try { try {
otherDoku = SudokuFactory.fromfile(savePath); otherDoku = SudokuFactory.fromfile(savePath);
assert (otherDoku != null); assert (otherDoku != null);
assertEquals(SudokuSerializer.serializeSudoku(doku).toString(), SudokuSerializer.serializeSudoku(otherDoku).toString()); assertEquals(SudokuSerializer.serializeSudoku(doku).toString(),
SudokuSerializer.serializeSudoku(otherDoku).toString());
// clean file after test // clean file after test
File fileToDelete = new File(savePath); File fileToDelete = new File(savePath);
fileToDelete.delete(); fileToDelete.delete();
@@ -47,7 +48,7 @@ public class SudokuSerializerTest {
void testSerializeX(int size) { void testSerializeX(int size) {
var sudoku = SudokuFactory.createBasicXShapedMultidoku(size, SudokuFactory.DEFAULT_CONSTRAINTS); var sudoku = SudokuFactory.createBasicXShapedMultidoku(size, SudokuFactory.DEFAULT_CONSTRAINTS);
Solver.randomSolve(sudoku, new Random()); new RandomSolver().solve(sudoku);
JSONObject data = SudokuSerializer.serializeSudoku(sudoku); JSONObject data = SudokuSerializer.serializeSudoku(sudoku);
MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data); MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data);

View File

@@ -57,7 +57,7 @@ class SolverTest {
assert (dokuResult.isSolved()); assert (dokuResult.isSolved());
Solver.randomSolve(dokuToTest, rand); new RandomSolver().solve(dokuToTest);
System.out.println("\n****************************\nDoku solved"); System.out.println("\n****************************\nDoku solved");
SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3);
@@ -89,13 +89,13 @@ class SolverTest {
5, ns, ns, ns, 3, 1, 0, ns, ns); 5, ns, ns, ns, 3, 1, 0, ns, ns);
sudokuToTest2.setImmutableCellsSymbol(immutableCells2); sudokuToTest2.setImmutableCellsSymbol(immutableCells2);
boolean isSolved = Solver.randomSolve(dokuToTest2, rand); boolean isSolved = new RandomSolver().solve(dokuToTest2);
assert (!isSolved); assert (!isSolved);
MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS); MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
Solver.randomSolve(dokuToTest3, rand); new RandomSolver().solve(dokuToTest3);
SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3); SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3);
} }