refactor : SudokuFactory
All checks were successful
Linux arm64 / Build (push) Successful in 43s

This commit is contained in:
Melvyn
2025-02-02 16:38:04 +01:00
parent 1419898955
commit b4157167b5

View File

@@ -27,8 +27,11 @@ public class SudokuFactory {
* Comprend les contraintes de blocs, de lignes, et de colonnes.
*/
public static List<IConstraint> 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<Block> 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<Coordinate, Integer>, association de Coordinate
* coordonnées et Integer valeurs, correspondant aux cases
* à remplir.
*/
public static void setImmutableCells(MultiDoku doku, Map<Coordinate, Integer> 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<Cell> 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<IConstraint> 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<IConstraint> 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<IConstraint> 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<IConstraint>, la liste des contraintes.
* @return MultiDoku, avec un seul Sudoku.
*/
public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List<IConstraint> constraints) {
int blockCellCount = blockSize * blockSize;
List<Cell> 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<Cell> 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<Constraints>
* @return List<IConstraints>
*/
public static List<IConstraint> fromConstraints(List<Constraint> constraints) {
List<IConstraint> iconstraints = new ArrayList<>();
for (Constraint cons : constraints) {