From a74bf42e59281e99c832e3820faee3fb2d13bd85 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 30 Jan 2025 18:05:18 +0100 Subject: [PATCH] refactor solvers --- app/src/main/java/gui/menu/SudokuView.java | 44 ++-- .../main/java/sudoku/io/ConsoleInterface.java | 15 +- .../sudoku/solver/BacktrackingSolver.java | 49 +++++ .../main/java/sudoku/solver/HumanSolver.java | 55 +++++ .../main/java/sudoku/solver/MixedSolver.java | 82 +++++++ .../main/java/sudoku/solver/RandomSolver.java | 63 ++++++ app/src/main/java/sudoku/solver/Solver.java | 205 +----------------- .../main/java/sudoku/solver/StupidSolver.java | 1 - .../java/sudoku/structure/SudokuFactory.java | 17 +- .../java/sudoku/SudokuSerializerTest.java | 11 +- .../test/java/sudoku/solver/SolverTest.java | 6 +- 11 files changed, 299 insertions(+), 249 deletions(-) create mode 100644 app/src/main/java/sudoku/solver/BacktrackingSolver.java create mode 100644 app/src/main/java/sudoku/solver/HumanSolver.java create mode 100644 app/src/main/java/sudoku/solver/MixedSolver.java create mode 100644 app/src/main/java/sudoku/solver/RandomSolver.java diff --git a/app/src/main/java/gui/menu/SudokuView.java b/app/src/main/java/gui/menu/SudokuView.java index 8614d2c..d75f736 100644 --- a/app/src/main/java/gui/menu/SudokuView.java +++ b/app/src/main/java/gui/menu/SudokuView.java @@ -1,12 +1,14 @@ package gui.menu; -import java.util.Random; import java.util.concurrent.CancellationException; import gui.SudokuRenderer; import imgui.ImGui; import imgui.ImGuiStyle; import sudoku.io.SudokuSerializer; +import sudoku.solver.BacktrackingSolver; +import sudoku.solver.HumanSolver; +import sudoku.solver.MixedSolver; import sudoku.solver.Solver; import sudoku.structure.MultiDoku; @@ -66,41 +68,29 @@ public class SudokuView extends BaseView { 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() { if (ImGui.beginPopup("solve")) { if (ImGui.button("Résoudre avec backtrace")) { - resolveThread = new Thread(() -> { - try { - Random rand = new Random(); - Solver.randomSolve(doku, rand); - } catch (CancellationException e) { - System.out.println("The user is bored !"); - } - stopResolve(); - }); + startSolve(new BacktrackingSolver()); ImGui.closeCurrentPopup(); } if (ImGui.button("Résoudre avec déduction")) { - resolveThread = new Thread(() -> { - try { - Solver.humanSolve(doku); - } catch (CancellationException e) { - System.out.println("The user is bored !"); - } - stopResolve(); - }); + startSolve(new HumanSolver()); ImGui.closeCurrentPopup(); } if (ImGui.button("Résoudre avec déduction et backtrace")) { - resolveThread = new Thread(() -> { - try { - Random rand = new Random(); - Solver.mixedSolve(doku, rand); - } catch (CancellationException e) { - System.out.println("The user is bored !"); - } - stopResolve(); - }); + startSolve(new MixedSolver()); ImGui.closeCurrentPopup(); } ImGui.endPopup(); diff --git a/app/src/main/java/sudoku/io/ConsoleInterface.java b/app/src/main/java/sudoku/io/ConsoleInterface.java index 6f7890b..82c62b5 100644 --- a/app/src/main/java/sudoku/io/ConsoleInterface.java +++ b/app/src/main/java/sudoku/io/ConsoleInterface.java @@ -1,17 +1,16 @@ package sudoku.io; -import sudoku.constraint.*; -import sudoku.solver.Solver; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +import sudoku.constraint.Constraint; +import sudoku.solver.RandomSolver; import sudoku.structure.Difficulty; import sudoku.structure.MultiDoku; import sudoku.structure.Sudoku; import sudoku.structure.SudokuFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Random; -import java.util.Scanner; - public class ConsoleInterface { public Scanner reader = new Scanner(System.in); @@ -133,7 +132,7 @@ public class ConsoleInterface { } private void generateFullDoku(MultiDoku doku) { - Solver.randomSolve(doku, new Random()); + new RandomSolver().solve(doku); } } diff --git a/app/src/main/java/sudoku/solver/BacktrackingSolver.java b/app/src/main/java/sudoku/solver/BacktrackingSolver.java new file mode 100644 index 0000000..750a8aa --- /dev/null +++ b/app/src/main/java/sudoku/solver/BacktrackingSolver.java @@ -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 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; + } + +} diff --git a/app/src/main/java/sudoku/solver/HumanSolver.java b/app/src/main/java/sudoku/solver/HumanSolver.java new file mode 100644 index 0000000..589d932 --- /dev/null +++ b/app/src/main/java/sudoku/solver/HumanSolver.java @@ -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 cellsToFill = doku.getEmptyCells(); + if (cellsToFill.isEmpty()) { + return false; + } + + for (Cell cellToFill : cellsToFill) { + + List possibleSymbols = cellToFill.getPossibleSymbols(); + if (possibleSymbols.size() != 1) { + continue; + } + + cellToFill.setSymbolIndex(possibleSymbols.getFirst()); + + return this.solve(doku); + } + + return doku.isSolved(); + } + +} diff --git a/app/src/main/java/sudoku/solver/MixedSolver.java b/app/src/main/java/sudoku/solver/MixedSolver.java new file mode 100644 index 0000000..60ffeaf --- /dev/null +++ b/app/src/main/java/sudoku/solver/MixedSolver.java @@ -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 cellsToFill = doku.getEmptyCells(); + if (cellsToFill.isEmpty()) { + return false; + } + + // Règles de déduction + for (Cell cellToFill : cellsToFill) { + + List 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 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; + } + +} diff --git a/app/src/main/java/sudoku/solver/RandomSolver.java b/app/src/main/java/sudoku/solver/RandomSolver.java new file mode 100644 index 0000000..275d928 --- /dev/null +++ b/app/src/main/java/sudoku/solver/RandomSolver.java @@ -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 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; + } + +} diff --git a/app/src/main/java/sudoku/solver/Solver.java b/app/src/main/java/sudoku/solver/Solver.java index 1bb55c5..8ea6bde 100644 --- a/app/src/main/java/sudoku/solver/Solver.java +++ b/app/src/main/java/sudoku/solver/Solver.java @@ -1,236 +1,47 @@ package sudoku.solver; import java.util.List; -import java.util.Random; -import java.util.concurrent.CancellationException; -import java.util.logging.Level; import java.util.logging.Logger; -import sudoku.io.SudokuPrinter; import sudoku.structure.Cell; 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. */ - private static final Logger logger = Logger.getLogger("SolverLogger"); + public static final Logger logger = Logger.getLogger("SolverLogger"); - /** - * 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"); + boolean solve(MultiDoku doku); - 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 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. * * @param doku MultiDoku, MultiDoku dont on veut le nombre de solutions. * @return int, nombre de solutions possibles. */ - public static int countSolution(MultiDoku doku) { + default int countSolution(MultiDoku doku) { int result = 0; - if (doku.isSolved()) { return 1; } Cell cellToFill = doku.getFirstEmptyCell(); - assert(cellToFill != null); + assert (cellToFill != null); List possibleSymbols = cellToFill.getPossibleSymbols(); for (int symbol : possibleSymbols) { doku.getStateManager().pushState(); cellToFill.setSymbolIndex(symbol); - if (Solver.solve(doku)) { + if (solve(doku)) { result++; } doku.getStateManager().popState(); } - 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 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 cellsToFill = doku.getEmptyCells(); - if (cellsToFill.isEmpty()) { - return false; - } - - for (Cell cellToFill : cellsToFill) { - - List 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 cellsToFill = doku.getEmptyCells(); - if (cellsToFill.isEmpty()) { - return false; - } - - //Règles de déduction - for (Cell cellToFill : cellsToFill) { - - List 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 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; - } } diff --git a/app/src/main/java/sudoku/solver/StupidSolver.java b/app/src/main/java/sudoku/solver/StupidSolver.java index 82c2200..8fed0b8 100644 --- a/app/src/main/java/sudoku/solver/StupidSolver.java +++ b/app/src/main/java/sudoku/solver/StupidSolver.java @@ -2,7 +2,6 @@ package sudoku.solver; import java.util.concurrent.CancellationException; -import sudoku.structure.Coordinate; import sudoku.structure.MultiDoku; import sudoku.structure.Sudoku; diff --git a/app/src/main/java/sudoku/structure/SudokuFactory.java b/app/src/main/java/sudoku/structure/SudokuFactory.java index 0375426..77cac97 100644 --- a/app/src/main/java/sudoku/structure/SudokuFactory.java +++ b/app/src/main/java/sudoku/structure/SudokuFactory.java @@ -9,9 +9,9 @@ import java.util.List; import java.util.Map; import java.util.Random; -import sudoku.io.SudokuSerializer; - import sudoku.constraint.Constraint; +import sudoku.io.SudokuSerializer; +import sudoku.solver.RandomSolver; import sudoku.solver.Solver; 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. * @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()) { throw new Exception(); @@ -134,9 +134,9 @@ public class SudokuFactory { int oldSymbol = cellToEmpty.empty(); - int nbDokuSultions = Solver.countSolution(doku); + int nbDokuSultions = solver.countSolution(doku); if (nbDokuSultions == 1) { - if (newDokuFromFilledOne(doku, --nbCellsToEmpty)) { + if (newDokuFromFilledOne(doku, --nbCellsToEmpty, solver)) { return true; } } @@ -145,7 +145,7 @@ public class SudokuFactory { 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 { - Solver.randomSolve(doku, random); + Solver solver = new RandomSolver(); + solver.solve(doku); int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); - boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty); + boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver); if (!successfull) { throw new Exception("Canno't create this doku with this difficulty"); } diff --git a/app/src/test/java/sudoku/SudokuSerializerTest.java b/app/src/test/java/sudoku/SudokuSerializerTest.java index 7317fe3..d39bf79 100644 --- a/app/src/test/java/sudoku/SudokuSerializerTest.java +++ b/app/src/test/java/sudoku/SudokuSerializerTest.java @@ -10,7 +10,7 @@ import org.json.JSONObject; import org.junit.jupiter.api.Test; import sudoku.io.SudokuSerializer; -import sudoku.solver.Solver; +import sudoku.solver.RandomSolver; import sudoku.structure.MultiDoku; import sudoku.structure.SudokuFactory; @@ -19,7 +19,7 @@ public class SudokuSerializerTest { void testSerializeWithSize(int blockWidth, int blockHeight) { var sudoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight, SudokuFactory.DEFAULT_CONSTRAINTS); - Solver.randomSolve(sudoku, new Random()); + new RandomSolver().solve(sudoku); JSONObject data = SudokuSerializer.serializeSudoku(sudoku); MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data); assertTrue(data.toString().equals(SudokuSerializer.serializeSudoku(multiDoku).toString())); @@ -28,14 +28,15 @@ public class SudokuSerializerTest { void testSaveWithSize(int blockWidth, int blockHeight) { MultiDoku doku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight, SudokuFactory.DEFAULT_CONSTRAINTS); - Solver.randomSolve(doku, new Random()); + new RandomSolver().solve(doku); String savePath = SudokuSerializer.saveMultiDoku(doku); MultiDoku otherDoku = null; try { otherDoku = SudokuFactory.fromfile(savePath); 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 File fileToDelete = new File(savePath); fileToDelete.delete(); @@ -47,7 +48,7 @@ public class SudokuSerializerTest { void testSerializeX(int size) { var sudoku = SudokuFactory.createBasicXShapedMultidoku(size, SudokuFactory.DEFAULT_CONSTRAINTS); - Solver.randomSolve(sudoku, new Random()); + new RandomSolver().solve(sudoku); JSONObject data = SudokuSerializer.serializeSudoku(sudoku); MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data); diff --git a/app/src/test/java/sudoku/solver/SolverTest.java b/app/src/test/java/sudoku/solver/SolverTest.java index 0363da2..6b64c55 100644 --- a/app/src/test/java/sudoku/solver/SolverTest.java +++ b/app/src/test/java/sudoku/solver/SolverTest.java @@ -57,7 +57,7 @@ class SolverTest { assert (dokuResult.isSolved()); - Solver.randomSolve(dokuToTest, rand); + new RandomSolver().solve(dokuToTest); System.out.println("\n****************************\nDoku solved"); SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); @@ -89,13 +89,13 @@ class SolverTest { 5, ns, ns, ns, 3, 1, 0, ns, ns); sudokuToTest2.setImmutableCellsSymbol(immutableCells2); - boolean isSolved = Solver.randomSolve(dokuToTest2, rand); + boolean isSolved = new RandomSolver().solve(dokuToTest2); assert (!isSolved); MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS); - Solver.randomSolve(dokuToTest3, rand); + new RandomSolver().solve(dokuToTest3); SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3); }