From b7f9ca8a98ef69d50328a99b165314980d9d191b Mon Sep 17 00:00:00 2001 From: Melvyn Date: Fri, 31 Jan 2025 18:26:44 +0100 Subject: [PATCH] fix : MixedSolver --- .../main/java/sudoku/solver/MixedSolver.java | 31 ++++++----------- .../java/sudoku/structure/SudokuFactory.java | 34 +++++++++---------- 2 files changed, 26 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/sudoku/solver/MixedSolver.java b/app/src/main/java/sudoku/solver/MixedSolver.java index 60ffeaf..87351d7 100644 --- a/app/src/main/java/sudoku/solver/MixedSolver.java +++ b/app/src/main/java/sudoku/solver/MixedSolver.java @@ -17,8 +17,6 @@ public class MixedSolver implements Solver{ * 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 @@ -40,29 +38,20 @@ public class MixedSolver implements Solver{ return true; } - List cellsToFill = doku.getEmptyCells(); - if (cellsToFill.isEmpty()) { + Cell cellToFill = doku.getFirstEmptyCell(); + if (cellToFill == null) { 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(); + if (possibleSymbols.size() == 1) { + cellToFill.setSymbolIndex(possibleSymbols.getFirst()); + if (this.solve(doku)) { + return true; + } + } + while (!possibleSymbols.isEmpty()) { int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size()); int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex); @@ -71,9 +60,9 @@ public class MixedSolver implements Solver{ if (this.solve(doku)) { return true; } - cellToFill.setSymbolIndex(Cell.NOSYMBOL); possibleSymbols.remove(nextPossibleSymbolIndex); + } return false; diff --git a/app/src/main/java/sudoku/structure/SudokuFactory.java b/app/src/main/java/sudoku/structure/SudokuFactory.java index 77cac97..d259bfb 100644 --- a/app/src/main/java/sudoku/structure/SudokuFactory.java +++ b/app/src/main/java/sudoku/structure/SudokuFactory.java @@ -145,7 +145,7 @@ public class SudokuFactory { cellsThatCanBeEmptied.remove(cellToEmpty); } - return newDokuFromFilledOne(doku, --nbCellsToEmpty, solver); + return false; } /** @@ -181,21 +181,22 @@ public class SudokuFactory { * @param sudoku2 Sudoku, second sudoku à connecter. * @param offset Coordinate, décalage entre les deux Sudokus. */ - private static void linkSquareSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) { + private static void linkRectangleSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) { int blockWidth = sudoku1.getBlockWidth(); - for (int dx = 0; dx < blockWidth; dx++) { + int blockHeight = sudoku1.getSize() / blockWidth; + for (int dx = 0; dx < blockHeight; dx++) { for (int dy = 0; dy < blockWidth; dy++) { int block1X = dx + offset.getX(); int block1Y = dy + offset.getY(); int block2X = dx; int block2Y = dy; - if ((block1X < blockWidth) && (block1X >= 0) && (block1Y >= 0) && (block1Y < blockWidth)) { - Block block1 = sudoku1.getBlocks().get(block1Y * blockWidth + block1X); - Block block2 = sudoku2.getBlocks().get(block2Y * blockWidth + block2X); + if ((block1X < blockHeight) && (block1X >= 0) && (block1Y >= 0) && (block1Y < blockWidth)) { + Block block1 = sudoku1.getBlocks().get(block1Y * blockHeight + block1X); + Block block2 = sudoku2.getBlocks().get(block2Y * blockHeight + block2X); // on remplace le bloc - sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1); + sudoku2.getBlocks().set(block2Y * blockHeight + block2X, block1); block1.getSudokus().add(sudoku2); // on remplace les cellules @@ -231,10 +232,10 @@ public class SudokuFactory { Sudoku sudoku4 = createSquareSudoku(size, constraints); Sudoku sudoku5 = createSquareSudoku(size, constraints); - linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size)); - linkSquareSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size)); - linkSquareSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1)); - linkSquareSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1)); + linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size)); + linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size)); + linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1)); + linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); } @@ -263,10 +264,10 @@ public class SudokuFactory { Sudoku sudoku4 = createRectangleSudoku(width, height, constraints); Sudoku sudoku5 = createRectangleSudoku(width, height, constraints); - linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - width, 1 - height)); - linkSquareSudokus(sudoku1, sudoku3, new Coordinate(width - 1, 1 - height)); - linkSquareSudokus(sudoku1, sudoku4, new Coordinate(1 - width, height - 1)); - linkSquareSudokus(sudoku1, sudoku5, new Coordinate(width - 1, height - 1)); + linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - height, 1 - width)); + linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(height - 1, 1 - width)); + linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - height, width - 1)); + linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(height - 1, width - 1)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); } @@ -276,9 +277,6 @@ public class SudokuFactory { solver.solve(doku); int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver); - if (!successfull) { - throw new Exception("Canno't create this doku with this difficulty"); - } doku.setFilledCellsImmutable(); }