This commit is contained in:
@@ -27,8 +27,11 @@ public class SudokuFactory {
|
|||||||
* Comprend les contraintes de blocs, de lignes, et de colonnes.
|
* Comprend les contraintes de blocs, de lignes, et de colonnes.
|
||||||
*/
|
*/
|
||||||
public static List<IConstraint> DEFAULT_CONSTRAINTS = SudokuFactory
|
public static List<IConstraint> DEFAULT_CONSTRAINTS = SudokuFactory
|
||||||
.fromConstraints(Arrays.asList(Constraint.Block, Constraint.Column,
|
.fromConstraints(Arrays.asList(
|
||||||
Constraint.Line));
|
Constraint.Block,
|
||||||
|
Constraint.Column,
|
||||||
|
Constraint.Line)
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée des Cells et les met dans une liste de taille size.
|
* 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));
|
int index = ((y + blockY * height) * size + (x + blockX * width));
|
||||||
Cell blockCell = cells.get(index);
|
Cell blockCell = cells.get(index);
|
||||||
blockCell.setBlock(newBlock);
|
blockCell.setBlock(newBlock);
|
||||||
// List<Block> blockContainers = new ArrayList<>();
|
|
||||||
// blockContainers.add(newBlock);
|
|
||||||
// blockCell.setBlockContainers(blockContainers);
|
|
||||||
newBlock.addCell(blockCell);
|
newBlock.addCell(blockCell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,62 +99,6 @@ public class SudokuFactory {
|
|||||||
return new MultiDoku(List.of(createSquareSudoku(size, constraints)));
|
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
|
* Créée un Sudoku vide dont les Blocks sont de taille widthBlock par
|
||||||
* heightBlock.
|
* heightBlock.
|
||||||
@@ -227,6 +171,9 @@ public class SudokuFactory {
|
|||||||
* Créée un MultiDoku de Blocks carrés de taille size composé de cinq Sudokus,
|
* 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
|
* dont un central qui partage chacun de ses Blockss d'angle avec un autre
|
||||||
* Sudoku.
|
* Sudoku.
|
||||||
|
* 2 3
|
||||||
|
* 1
|
||||||
|
* 4 5
|
||||||
*
|
*
|
||||||
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
|
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
|
||||||
* @return MultiDoku, MultiDoku de forme X.
|
* @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,
|
* 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 d'angle avec un autre
|
||||||
* Sudoku.
|
* Sudoku.
|
||||||
|
* 2 3
|
||||||
|
* 1
|
||||||
|
* 4 5
|
||||||
*
|
*
|
||||||
* @param width int, largeur des Blocks unitraires des Sudokus à crééer.
|
* @param width int, largeur des Blocks unitaires des Sudokus à crééer.
|
||||||
* @param height int, hauteur des Blocks unitraires des Sudokus à crééer.
|
* @param height int, hauteur des Blocks unitaires des Sudokus à crééer.
|
||||||
* @return MultiDoku, MultiDoku de forme X.
|
* @return MultiDoku, MultiDoku de forme X.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicXShapedMultidoku(int width, int height, List<IConstraint> constraints) {
|
public static MultiDoku createBasicXShapedMultidoku(int width, int height, List<IConstraint> constraints) {
|
||||||
assert (width > 1 && height > 1);
|
assert (width > 1 && height > 1);
|
||||||
|
|
||||||
/*
|
|
||||||
* 2 3
|
|
||||||
* 1
|
|
||||||
* 4 5
|
|
||||||
*/
|
|
||||||
|
|
||||||
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
|
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
|
||||||
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
|
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
|
||||||
Sudoku sudoku3 = 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 forme +, de taille size composé
|
||||||
* Créée un MultiDoku de Blocks carrés de taille size composé de cinq Sudokus,
|
* de cinq Sudokus,
|
||||||
* dont un central qui partage chacun de ses Blockss d'angle avec un autre
|
* dont un central qui partage chacun de ses Blocks de bord avec un autre
|
||||||
* Sudoku.
|
* Sudoku.
|
||||||
|
* 3
|
||||||
|
* 2 1 4
|
||||||
|
* 5
|
||||||
*
|
*
|
||||||
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
|
* @param size int, largeur des Blocks unitaires des Sudokus à crééer.
|
||||||
* @return MultiDoku, MultiDoku de forme X.
|
* @return MultiDoku, MultiDoku de forme +.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicPlusShapedMultidoku(int size, List<IConstraint> constraints) {
|
public static MultiDoku createBasicPlusShapedMultidoku(int size, List<IConstraint> constraints) {
|
||||||
assert (size > 1);
|
assert (size > 1);
|
||||||
@@ -286,24 +233,20 @@ public class SudokuFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* Créée un MultiDoku de Blocks rectangulaires de forme +, de taille width par height composé
|
||||||
* Créée un MultiDoku de Blocks rectangulaires de forme width par height composé
|
|
||||||
* de cinq Sudokus,
|
* 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.
|
* Sudoku.
|
||||||
*
|
|
||||||
* @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.
|
|
||||||
*/
|
|
||||||
public static MultiDoku createBasicPlusShapedMultidoku(int width, int height, List<IConstraint> constraints) {
|
|
||||||
assert (width > 1 && height > 1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 3
|
* 3
|
||||||
* 2 1 4
|
* 2 1 4
|
||||||
* 5
|
* 5
|
||||||
|
*
|
||||||
|
* @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);
|
||||||
|
|
||||||
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
|
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
|
||||||
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
|
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
|
||||||
@@ -319,25 +262,13 @@ public class SudokuFactory {
|
|||||||
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
|
/**
|
||||||
Solver solver = new RandomSolver();
|
* Crée un Sudoku vide avec les Blocks aléatoires.
|
||||||
solver.solve(doku);
|
*
|
||||||
int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells());
|
* @param blockSize int, la taille des Block.
|
||||||
boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty, solver);
|
* @param constraints List<IConstraint>, la liste des contraintes.
|
||||||
doku.setFilledCellsImmutable();
|
* @return MultiDoku, avec un seul Sudoku.
|
||||||
}
|
*/
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List<IConstraint> constraints) {
|
public static MultiDoku createBasicEmptyRandomBlockDoku(int blockSize, List<IConstraint> constraints) {
|
||||||
int blockCellCount = blockSize * blockSize;
|
int blockCellCount = blockSize * blockSize;
|
||||||
List<Cell> cells = initCells(blockCellCount);
|
List<Cell> cells = initCells(blockCellCount);
|
||||||
@@ -361,6 +292,76 @@ public class SudokuFactory {
|
|||||||
return new MultiDoku(List.of(sudoku));
|
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) {
|
public static List<IConstraint> fromConstraints(List<Constraint> constraints) {
|
||||||
List<IConstraint> iconstraints = new ArrayList<>();
|
List<IConstraint> iconstraints = new ArrayList<>();
|
||||||
for (Constraint cons : constraints) {
|
for (Constraint cons : constraints) {
|
||||||
|
|||||||
Reference in New Issue
Block a user