diff --git a/app/src/main/java/sudoku/structure/SudokuFactory.java b/app/src/main/java/sudoku/structure/SudokuFactory.java index 753a526..feef263 100644 --- a/app/src/main/java/sudoku/structure/SudokuFactory.java +++ b/app/src/main/java/sudoku/structure/SudokuFactory.java @@ -27,8 +27,11 @@ public class SudokuFactory { * Comprend les contraintes de blocs, de lignes, et de colonnes. */ public static List DEFAULT_CONSTRAINTS = SudokuFactory - .fromConstraints(Arrays.asList(Constraint.Block, Constraint.Column, - Constraint.Line)); + .fromConstraints(Arrays.asList( + Constraint.Block, + Constraint.Column, + Constraint.Line) + ); /** * Créée des Cells et les met dans une liste de taille size. @@ -65,9 +68,6 @@ public class SudokuFactory { int index = ((y + blockY * height) * size + (x + blockX * width)); Cell blockCell = cells.get(index); blockCell.setBlock(newBlock); - // List blockContainers = new ArrayList<>(); - // blockContainers.add(newBlock); - // blockCell.setBlockContainers(blockContainers); newBlock.addCell(blockCell); } } @@ -99,62 +99,6 @@ public class SudokuFactory { return new MultiDoku(List.of(createSquareSudoku(size, constraints))); } - /** - * Place des Cells immutables de valeurs fournies, aux Coordinate fournies dans - * le MultiDoku doku fourni. - * - * @param doku MultiDoku, MultiDoku à remplir. - * @param immutableCells Map, association de Coordinate - * coordonnées et Integer valeurs, correspondant aux cases - * à remplir. - */ - public static void setImmutableCells(MultiDoku doku, Map immutableCells) { - immutableCells.forEach((coordinate, symbol) -> { - for (Sudoku sudoku : doku.getSubGrids()) { - Cell cell = sudoku.getCell(coordinate.getX(), coordinate.getY()); - if (cell != null) { - cell.setSymbolIndex(symbol); - cell.setImmutable(); - } - } - }); - } - - /** - * Créée un MultiDoku de difficulté difficulty à partir d'un MultiDoku fourni. - * - * @param doku MultiDoku, MultiDoku dont on doit vider des Cells. - * @param nbCellsToEmpty int, nombre de cases à retirer. - * @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, Solver solver) throws Exception { - - if (nbCellsToEmpty >= doku.getCells().size()) { - throw new Exception(); - } - - if (nbCellsToEmpty == 0) { - return true; - } - - List cellsThatCanBeEmptied = doku.getFilledCells(); - - int index = random.nextInt(cellsThatCanBeEmptied.size()); - Cell cellToEmpty = cellsThatCanBeEmptied.get(index); - - cellToEmpty.empty(); - - int nbDokuSultions = solver.countSolution(doku); - if (nbDokuSultions == 1) { - return newDokuFromFilledOne(doku, --nbCellsToEmpty, solver); - } - - return false; - } - /** * Créée un Sudoku vide dont les Blocks sont de taille widthBlock par * heightBlock. @@ -227,7 +171,10 @@ public class SudokuFactory { * Créée un MultiDoku de Blocks carrés de taille size composé de cinq Sudokus, * dont un central qui partage chacun de ses Blockss d'angle avec un autre * Sudoku. - * + * 2 3 + * 1 + * 4 5 + * * @param size int, largeur des Blocks unitraires des Sudokus à crééer. * @return MultiDoku, MultiDoku de forme X. */ @@ -238,24 +185,21 @@ public class SudokuFactory { } /** - * Créée un MultiDoku de Blocks rectangulaires de forme width par height composé + * Créée un MultiDoku de Blocks rectangulaires de forme X, de taille width par height composé * de cinq Sudokus, * dont un central qui partage chacun de ses Blocks d'angle avec un autre * Sudoku. + * 2 3 + * 1 + * 4 5 * - * @param width int, largeur des Blocks unitraires des Sudokus à crééer. - * @param height int, hauteur des Blocks unitraires des Sudokus à crééer. + * @param width int, largeur des Blocks unitaires des Sudokus à crééer. + * @param height int, hauteur des Blocks unitaires des Sudokus à crééer. * @return MultiDoku, MultiDoku de forme X. */ public static MultiDoku createBasicXShapedMultidoku(int width, int height, List constraints) { assert (width > 1 && height > 1); - /* - * 2 3 - * 1 - * 4 5 - */ - Sudoku sudoku1 = createRectangleSudoku(width, height, constraints); Sudoku sudoku2 = createRectangleSudoku(width, height, constraints); Sudoku sudoku3 = createRectangleSudoku(width, height, constraints); @@ -271,13 +215,16 @@ public class SudokuFactory { } /** - * TODO - * Créée un MultiDoku de Blocks carrés de taille size composé de cinq Sudokus, - * dont un central qui partage chacun de ses Blockss d'angle avec un autre + * Créée un MultiDoku de Blocks carrés de forme +, de taille size composé + * de cinq Sudokus, + * dont un central qui partage chacun de ses Blocks de bord avec un autre * Sudoku. + * 3 + * 2 1 4 + * 5 * - * @param size int, largeur des Blocks unitraires des Sudokus à crééer. - * @return MultiDoku, MultiDoku de forme X. + * @param size int, largeur des Blocks unitaires des Sudokus à crééer. + * @return MultiDoku, MultiDoku de forme +. */ public static MultiDoku createBasicPlusShapedMultidoku(int size, List constraints) { assert (size > 1); @@ -286,25 +233,21 @@ public class SudokuFactory { } /** - * TODO - * Créée un MultiDoku de Blocks rectangulaires de forme width par height composé + * Créée un MultiDoku de Blocks rectangulaires de forme +, de taille width par height composé * de cinq Sudokus, - * dont un central qui partage chacun de ses Blocks d'angle avec un autre + * dont un central qui partage chacun de ses Blocks de bord avec un autre * Sudoku. + * 3 + * 2 1 4 + * 5 * - * @param width int, largeur des Blocks unitraires des Sudokus à crééer. - * @param height int, hauteur des Blocks unitraires des Sudokus à crééer. - * @return MultiDoku, MultiDoku de forme X. + * @param width int, largeur des Blocks unitaires des Sudokus à crééer. + * @param height int, hauteur des Blocks unitaires des Sudokus à crééer. + * @return MultiDoku, MultiDoku de forme +. */ public static MultiDoku createBasicPlusShapedMultidoku(int width, int height, List constraints) { assert (width > 1 && height > 1); - /* - * 3 - * 2 1 4 - * 5 - */ - Sudoku sudoku1 = createRectangleSudoku(width, height, constraints); Sudoku sudoku2 = createRectangleSudoku(width, height, constraints); Sudoku sudoku3 = createRectangleSudoku(width, height, constraints); @@ -319,25 +262,13 @@ public class SudokuFactory { return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); } - public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception { - Solver solver = new RandomSolver(); - solver.solve(doku); - int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); - boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver); - doku.setFilledCellsImmutable(); - } - - public static MultiDoku fromfile(String filePath) { - try { - String content = Files.readString(Paths.get(filePath)); - MultiDoku doku = SudokuSerializer.deserializeSudoku(content); - return doku; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - + /** + * Crée un Sudoku vide avec les Blocks aléatoires. + * + * @param blockSize int, la taille des Block. + * @param constraints List, la liste des contraintes. + * @return MultiDoku, avec un seul Sudoku. + */ public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List constraints) { int blockCellCount = blockSize * blockSize; List cells = initCells(blockCellCount); @@ -361,6 +292,76 @@ public class SudokuFactory { return new MultiDoku(List.of(sudoku)); } + /** + * Créée un MultiDoku de difficulté difficulty à partir d'un MultiDoku fourni. + * + * @param doku MultiDoku, MultiDoku dont on doit vider des Cells. + * @param nbCellsToEmpty int, nombre de cases à retirer. + * @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, Solver solver) throws Exception { + + if (nbCellsToEmpty >= doku.getCells().size()) { + throw new Exception(); + } + + if (nbCellsToEmpty == 0) { + return true; + } + + List cellsThatCanBeEmptied = doku.getFilledCells(); + + int index = random.nextInt(cellsThatCanBeEmptied.size()); + Cell cellToEmpty = cellsThatCanBeEmptied.get(index); + + cellToEmpty.empty(); + + int nbDokuSultions = solver.countSolution(doku); + if (nbDokuSultions == 1) { + return newDokuFromFilledOne(doku, --nbCellsToEmpty, solver); + } + + return false; + } + + /** + * Rempli un MultiDoku donné par rapport à un difficulté. + * + * @param doku MultiDoku, vide. + * @param difficulty Difficulty, qui correspond au pourcentage de cases à enlever. + */ + public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception { + Solver solver = new RandomSolver(); + solver.solve(doku); + int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells()); + newDokuFromFilledOne(doku, nbCellsToEmpty, solver); + doku.setFilledCellsImmutable(); + } + + /** + * Génère un MultiDoku à partir d'un fichier de sauvegarde. + * + * @param filePath String, chemin du fichier. + * @return MultiDoku. + */ + public static MultiDoku fromfile(String filePath) { + try { + String content = Files.readString(Paths.get(filePath)); + return SudokuSerializer.deserializeSudoku(content); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Transforme des Constraint en IConstraint correspondants + * @param constraints List + * @return List + */ public static List fromConstraints(List constraints) { List iconstraints = new ArrayList<>(); for (Constraint cons : constraints) {