From 67da77af2e55ae29ac0a4221b4def3053fc571bc Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Thu, 30 Jan 2025 09:34:00 +0100 Subject: [PATCH] feat: add states --- app/src/main/java/sudoku/solver/Solver.java | 24 +++++------ .../main/java/sudoku/structure/MultiDoku.java | 13 +++--- .../java/sudoku/structure/StateManager.java | 41 +++++++++++++++++++ 3 files changed, 60 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/sudoku/structure/StateManager.java diff --git a/app/src/main/java/sudoku/solver/Solver.java b/app/src/main/java/sudoku/solver/Solver.java index 3a9d615..b2e45a1 100644 --- a/app/src/main/java/sudoku/solver/Solver.java +++ b/app/src/main/java/sudoku/solver/Solver.java @@ -68,10 +68,9 @@ public class Solver { * @param oldDoku MultiDoku, MultiDoku dont on veut le nombre de solutions. * @return int, nombre de solutions possibles. */ - public static int countSolution(MultiDoku oldDoku) { + public static int countSolution(MultiDoku doku) { int result = 0; - MultiDoku doku = oldDoku.clone(); if (doku.isSolved()) { return 1; @@ -83,11 +82,12 @@ public class Solver { List possibleSymbols = cellToFill.getPossibleSymbols(); for (int symbol : possibleSymbols) { + doku.getStateManager().pushState(); cellToFill.setSymbolIndex(symbol); - if (Solver.solve(doku) != null) { + if (Solver.solve(doku)) { result++; } - cellToFill.setSymbolIndex(Cell.NOSYMBOL); + doku.getStateManager().popState(); } return result; @@ -98,37 +98,35 @@ public class Solver { * @param doku MultiDoku, MultiDoku à résoudre. * @return boolean, valant true si le MultiDoku est résolu, false sinon. */ - public static MultiDoku solve(MultiDoku oldDoku) { + public static boolean solve(MultiDoku doku) { if (Thread.interrupted()) throw new CancellationException("User wants to stop the solver"); - MultiDoku doku = oldDoku.clone(); - if (doku.isSolved()) { - return doku; + return true; } Cell cellToFill = doku.getFirstEmptyCell(); if (cellToFill == null) { - return null; + return false; } List possibleSymbols = cellToFill.getPossibleSymbols(); if (possibleSymbols.isEmpty()) { - return null; + return false; } for (int symbol : possibleSymbols) { cellToFill.setSymbolIndex(symbol); - if (Solver.solve(doku) != null) { - return doku; + if (Solver.solve(doku)) { + return true; } else { cellToFill.setSymbolIndex(Cell.NOSYMBOL); } } - return null; + return false; } /** diff --git a/app/src/main/java/sudoku/structure/MultiDoku.java b/app/src/main/java/sudoku/structure/MultiDoku.java index 5eeca5a..37b4976 100644 --- a/app/src/main/java/sudoku/structure/MultiDoku.java +++ b/app/src/main/java/sudoku/structure/MultiDoku.java @@ -19,13 +19,11 @@ public class MultiDoku { */ private final List subGrids; + private final StateManager stateManager; + public MultiDoku(List subGrids) { this.subGrids = subGrids; - } - - public MultiDoku clone() { - // TODO: ahhhhhhhhhhhhhhhhhhhhhhh - return SudokuSerializer.deserializeSudoku(SudokuSerializer.serializeSudoku(this)); + this.stateManager = new StateManager(this); } /** @@ -167,4 +165,9 @@ public class MultiDoku { filledCell.setImmutable(); } } + + public StateManager getStateManager() { + return stateManager; + } + } diff --git a/app/src/main/java/sudoku/structure/StateManager.java b/app/src/main/java/sudoku/structure/StateManager.java new file mode 100644 index 0000000..8ea9feb --- /dev/null +++ b/app/src/main/java/sudoku/structure/StateManager.java @@ -0,0 +1,41 @@ +package sudoku.structure; + +import java.util.HashMap; +import java.util.Map; +import java.util.Stack; + +//TODO: doc +public class StateManager { + + private final Stack> states; + private final MultiDoku doku; + + public StateManager(MultiDoku doku) { + this.states = new Stack<>(); + this.doku = doku; + } + + public void pushState() { + states.add(new HashMap<>()); + saveState(); + } + + public void popState() { + assert (states.size() > 0); + restoreState(); + states.pop(); + } + + private void restoreState() { + for (var entry : this.states.getLast().entrySet()) { + entry.getKey().setSymbolIndex(entry.getValue()); + } + } + + private void saveState() { + for (Cell cell : this.doku.getCells()) { + states.getLast().put(cell, cell.getSymbolIndex()); + } + } + +}