Merge remote-tracking branch 'origin/master'
# Conflicts: # app/src/main/java/sudoku/structure/MultiDoku.java # app/src/main/java/sudoku/structure/Sudoku.java # app/src/main/java/sudoku/structure/SudokuFactory.java # app/src/test/java/sudoku/solver/SolverTest.java
This commit is contained in:
@@ -18,30 +18,29 @@ public class Main {
|
||||
|
||||
int blockWidth = 2;
|
||||
int blockHeight = 2;
|
||||
var multidoku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight);
|
||||
var multidoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
|
||||
SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||
var sudoku = multidoku.getSubGrid(0);
|
||||
if(!sudoku.setCellsSymbol(Arrays.asList(0,1,2,3, 2,3,1,1, 1,0,3,2, 3,2,1,1))){
|
||||
if (!sudoku.setCellsSymbol(Arrays.asList(0, 1, 2, 3, 2, 3, 1, 1, 1, 0, 3, 2, 3, 2, 1, 1))) {
|
||||
System.out.println("At least one of those values does not respect the constraints.");
|
||||
}
|
||||
|
||||
// sudoku.setCellSymbol(8,3,0);
|
||||
|
||||
//sudoku.setCellSymbol(8,3,0);
|
||||
|
||||
SudokuPrinter.printRectangleSudoku(multidoku.getSubGrid(0), blockWidth , blockHeight);
|
||||
SudokuPrinter.printRectangleSudoku(multidoku.getSubGrid(0), blockWidth, blockHeight);
|
||||
|
||||
/*
|
||||
Solver solver = new Solver();
|
||||
ArrayList<IConstraint> constraints = new ArrayList<>();
|
||||
constraints.add(new LineConstraint());
|
||||
constraints.add(new ColumnConstraint());
|
||||
constraints.add(new BlockConstraint());
|
||||
try {
|
||||
solver.solve(multidoku, constraints);
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
*/
|
||||
|
||||
* Solver solver = new Solver();
|
||||
* ArrayList<IConstraint> constraints = new ArrayList<>();
|
||||
* constraints.add(new LineConstraint());
|
||||
* constraints.add(new ColumnConstraint());
|
||||
* constraints.add(new BlockConstraint());
|
||||
* try {
|
||||
* solver.solve(multidoku, constraints);
|
||||
* } catch (Exception e) {
|
||||
* System.out.println(e);
|
||||
* }
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
52
app/src/main/java/sudoku/constraint/Constraint.java
Normal file
52
app/src/main/java/sudoku/constraint/Constraint.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package sudoku.constraint;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import sudoku.structure.Sudoku;
|
||||
|
||||
public enum Constraint {
|
||||
|
||||
Block("Bloc", new BlockConstraint()),
|
||||
Column("Colonne", new ColumnConstraint()),
|
||||
Line("Ligne", new LineConstraint()),
|
||||
Diagonal("Diagonale", new DiagonalConstraint());
|
||||
|
||||
String displayName;
|
||||
IConstraint constraint;
|
||||
|
||||
private Constraint(String displayName, IConstraint contraint) {
|
||||
this.constraint = contraint;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public boolean canBePlaced(Sudoku s, int x, int y, int newValue) {
|
||||
return getConstraint().canBePlaced(s, x, y, newValue);
|
||||
}
|
||||
|
||||
public List<Integer> getPossibleSymbols(final Sudoku s, int x, int y) {
|
||||
return getConstraint().getPossibleSymbols(s, x, y);
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public IConstraint getConstraint() {
|
||||
return constraint;
|
||||
}
|
||||
|
||||
private static final String[] constraintNames;
|
||||
|
||||
static {
|
||||
Constraint[] cons = Constraint.values();
|
||||
constraintNames = new String[cons.length];
|
||||
for (int i = 0; i < cons.length; i++) {
|
||||
constraintNames[i] = cons[i].getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getConstraintNames() {
|
||||
return constraintNames;
|
||||
}
|
||||
|
||||
}
|
||||
24
app/src/main/java/sudoku/constraint/DiagonalConstraint.java
Normal file
24
app/src/main/java/sudoku/constraint/DiagonalConstraint.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package sudoku.constraint;
|
||||
|
||||
import sudoku.structure.Sudoku;
|
||||
|
||||
public class DiagonalConstraint implements IConstraint {
|
||||
|
||||
@Override
|
||||
public boolean canBePlaced(Sudoku s, int x, int y, int newSymbolIndex) {
|
||||
if (x == y) {
|
||||
for (int i = 0; i < s.getSize(); i++) {
|
||||
if (s.getCell(i, i).getSymbolIndex() == newSymbolIndex)
|
||||
return false;
|
||||
}
|
||||
} else if (s.getSize() - x == y) {
|
||||
for (int i = 0; i < s.getSize(); i++) {
|
||||
if (s.getCell(s.getSize() - i - 1, i).getSymbolIndex() == newSymbolIndex)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// not in diagonal
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import java.util.List;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import sudoku.constraint.Constraint;
|
||||
import sudoku.structure.Block;
|
||||
import sudoku.structure.Cell;
|
||||
import sudoku.structure.MultiDoku;
|
||||
@@ -34,7 +35,6 @@ public class SudokuSerializer {
|
||||
for (Cell cell : sudoku.getCells()) {
|
||||
if (!cellIds.contains(cell)) {
|
||||
cellIds.add(cell);
|
||||
|
||||
}
|
||||
|
||||
Block block = cell.getBlock();
|
||||
@@ -74,6 +74,7 @@ public class SudokuSerializer {
|
||||
JSONObject jsonSudoku = new JSONObject();
|
||||
JSONArray cellsJsonArray = new JSONArray();
|
||||
JSONArray blocksJsonArray = new JSONArray();
|
||||
JSONArray constraintsJsonArray = new JSONArray();
|
||||
|
||||
Sudoku sudoku = multidoku.getSubGrid(i);
|
||||
|
||||
@@ -91,6 +92,13 @@ public class SudokuSerializer {
|
||||
blocksJsonArray.put(blockID);
|
||||
}
|
||||
|
||||
// serialize constraints
|
||||
|
||||
for (Constraint cons : sudoku.getConstraints()) {
|
||||
constraintsJsonArray.put(cons.ordinal());
|
||||
}
|
||||
|
||||
jsonSudoku.put("constraints", constraintsJsonArray);
|
||||
jsonSudoku.put("cells", cellsJsonArray);
|
||||
jsonSudoku.put("blocks", blocksJsonArray);
|
||||
jsonSudoku.put("blockWidth", sudoku.getBlockWidth());
|
||||
@@ -107,9 +115,9 @@ public class SudokuSerializer {
|
||||
/**
|
||||
* Save a serialized MultiDoku in a JSON file.
|
||||
* @param doku MultiDoku, MultiDoku to save.
|
||||
* @return int, number of the save.
|
||||
* @return String, the path of the save.
|
||||
*/
|
||||
public static int saveMultiDoku(final MultiDoku doku) {
|
||||
public static String saveMultiDoku(final MultiDoku doku) {
|
||||
|
||||
JSONObject jsonRoot = serializeSudoku(doku);
|
||||
|
||||
@@ -124,9 +132,9 @@ public class SudokuSerializer {
|
||||
try (FileWriter file = new FileWriter(f)) {
|
||||
file.write(jsonRoot.toString(3));
|
||||
} catch (IOException e) {
|
||||
e.fillInStackTrace();
|
||||
e.printStackTrace();
|
||||
}
|
||||
return i;
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,9 +220,11 @@ public class SudokuSerializer {
|
||||
JSONObject sudokuJsonObject = multidokuJsonObject.getJSONObject(i);
|
||||
JSONArray sudokuCellsJsonArray = sudokuJsonObject.getJSONArray("cells");
|
||||
JSONArray sudokuBlocksJsonArray = sudokuJsonObject.getJSONArray("blocks");
|
||||
JSONArray sudokuConstraintsJsonArray = sudokuJsonObject.getJSONArray("constraints");
|
||||
|
||||
List<Cell> sudokuCells = new ArrayList<>();
|
||||
List<Block> sudokuBlocks = new ArrayList<>();
|
||||
List<Constraint> sudokuConstraints = new ArrayList<>();
|
||||
|
||||
for (int j = 0; j < sudokuCellsJsonArray.length(); j++) {
|
||||
int cellID = sudokuCellsJsonArray.getInt(j);
|
||||
@@ -226,7 +236,12 @@ public class SudokuSerializer {
|
||||
sudokuBlocks.add(blocks.get(blockID));
|
||||
}
|
||||
|
||||
Sudoku s = new Sudoku(sudokuCells, sudokuBlocks, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||
for (int j = 0; j < sudokuConstraintsJsonArray.length(); j++) {
|
||||
int constraintID = sudokuConstraintsJsonArray.getInt(j);
|
||||
sudokuConstraints.add(Constraint.values()[constraintID]);
|
||||
}
|
||||
|
||||
Sudoku s = new Sudoku(sudokuCells, sudokuBlocks, sudokuConstraints);
|
||||
s.setBlockWidth(sudokuJsonObject.getInt("blockWidth"));
|
||||
sudokus.add(s);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,8 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* Class qui représente les block de chaque sudoku,
|
||||
* Un block étant un ensemble de cellule avec une contrainte de block qui lui ait associé
|
||||
* Un block étant un ensemble de cellule avec une contrainte de block qui lui
|
||||
* ait associé
|
||||
*/
|
||||
public class Block {
|
||||
|
||||
@@ -18,14 +19,15 @@ public class Block {
|
||||
* List de sudoku qui contiennent le block
|
||||
* Pour un acces plus rapide aux sudokus
|
||||
*/
|
||||
private List<Sudoku> sudokus;
|
||||
private final List<Sudoku> sudokus;
|
||||
|
||||
public Block(List<Cell> cells) {
|
||||
this.cells = cells;
|
||||
this.sudokus = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Block() {
|
||||
this.cells = new ArrayList<>();
|
||||
this(new ArrayList<>());
|
||||
}
|
||||
|
||||
public List<Cell> getCells() {
|
||||
@@ -34,6 +36,7 @@ public class Block {
|
||||
|
||||
/**
|
||||
* Ajoute une Cell au Block
|
||||
*
|
||||
* @param newCell Cell, à ajouter
|
||||
*/
|
||||
void addCell(Cell newCell) {
|
||||
@@ -42,6 +45,7 @@ public class Block {
|
||||
|
||||
/**
|
||||
* Cherche si le Block contient déjà un symbole donné.
|
||||
*
|
||||
* @param symbolIndex int, un index de symbole
|
||||
* @return boolean, true s'il contient le symbole et false sinon
|
||||
*/
|
||||
@@ -65,8 +69,4 @@ public class Block {
|
||||
public List<Sudoku> getSudokus() {
|
||||
return sudokus;
|
||||
}
|
||||
|
||||
void setSudokus(List<Sudoku> sudokus) {
|
||||
this.sudokus = sudokus;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ public enum Difficulty {
|
||||
double factor;
|
||||
String displayName;
|
||||
|
||||
Difficulty(String displayName, double factor) {
|
||||
private Difficulty(String displayName, double factor) {
|
||||
this.factor = factor;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
@@ -21,4 +21,18 @@ public enum Difficulty {
|
||||
return factor;
|
||||
}
|
||||
|
||||
private static final String[] difficultyNames;
|
||||
|
||||
static {
|
||||
Difficulty[] diffs = Difficulty.values();
|
||||
difficultyNames = new String[diffs.length];
|
||||
for (int i = 0; i < diffs.length; i++) {
|
||||
difficultyNames[i] = diffs[i].getDisplayName();
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getDifficultyNames() {
|
||||
return difficultyNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package sudoku.structure;
|
||||
|
||||
import sudoku.constraint.BlockConstraint;
|
||||
import sudoku.constraint.Constraint;
|
||||
import sudoku.constraint.IConstraint;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,13 +24,13 @@ public class Sudoku {
|
||||
/**
|
||||
* Liste des contraintes (TODO) du Sudoku.
|
||||
*/
|
||||
private final List<IConstraint> constraints;
|
||||
private final List<Constraint> constraints;
|
||||
/**
|
||||
* Largeur des Blocks s'ils sont rectangulaires, valant 0 si ce n'est pas le cas.
|
||||
*/
|
||||
private int blockWidth;
|
||||
|
||||
public Sudoku(List<Cell> cells, List<Block> blocks, List<IConstraint> constraints) {
|
||||
public Sudoku(List<Cell> cells, List<Block> blocks, List<Constraint> constraints) {
|
||||
this.cells = cells;
|
||||
this.blocks = blocks;
|
||||
this.constraints = constraints;
|
||||
@@ -41,7 +43,7 @@ public class Sudoku {
|
||||
* @return Coordinate, correspondante à l'index donné.
|
||||
*/
|
||||
public Coordinate toCoords(int index) {
|
||||
return new Coordinate( index % getSize(), index / getSize() );
|
||||
return new Coordinate(index % getSize(), index / getSize());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,13 +75,13 @@ public class Sudoku {
|
||||
|
||||
/**
|
||||
* Teste si on peut placer la value dans la Cell aux coordonnées x, y d'après les contraintes du Sudoku.
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, ordonnée de la Cell voulue.
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, ordonnée de la Cell voulue.
|
||||
* @param value int, index du symbole qu'on veut placer.
|
||||
* @return boolean, true si on peut la placer et false sinon.
|
||||
*/
|
||||
public boolean canBePlaced(int x, int y, int value) {
|
||||
for (IConstraint constraint : this.constraints) {
|
||||
for (Constraint constraint : this.constraints) {
|
||||
if (!constraint.canBePlaced(this, x, y, value)) {
|
||||
return false;
|
||||
}
|
||||
@@ -89,8 +91,8 @@ public class Sudoku {
|
||||
|
||||
/**
|
||||
* Tente de placer le symbole value dans la Cell de coordonnées x, y.
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, coordonnée de la Cell voulue;
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, coordonnée de la Cell voulue;
|
||||
* @param value int, index du symbole que l'on veut placer.
|
||||
* @return boolean, true si le symbole a été placé, false sinon
|
||||
*/
|
||||
@@ -132,14 +134,14 @@ public class Sudoku {
|
||||
|
||||
/**
|
||||
* Place le symbole d'index value dans la Cell de coordonnées précisées.
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, coordonnée de la Cell voulue.
|
||||
* @param x int, abscisse de la Cell voulue.
|
||||
* @param y int, coordonnée de la Cell voulue.
|
||||
* @param value int, index du symbole à placer.
|
||||
* @return Cell, la Cell qui a été modifiée.
|
||||
*/
|
||||
public Cell setCellSymbol(int x, int y, int value) {
|
||||
assert (isValidCoords(x, y));
|
||||
for (IConstraint constraint : this.constraints) {
|
||||
for (Constraint constraint : this.constraints) {
|
||||
if (!constraint.canBePlaced(this, x, y, value)) {
|
||||
return null;
|
||||
}
|
||||
@@ -205,7 +207,7 @@ public class Sudoku {
|
||||
return this.cells.get(i);
|
||||
}
|
||||
|
||||
public List<IConstraint> getConstraints() {
|
||||
public List<Constraint> getConstraints() {
|
||||
return constraints;
|
||||
}
|
||||
|
||||
@@ -264,8 +266,8 @@ public class Sudoku {
|
||||
* Met à jour les symboles possibles des Cells du Sudoku.
|
||||
*
|
||||
*/
|
||||
public void updateSymbolsPossibilities(){
|
||||
for (IConstraint constraint : constraints) {
|
||||
public void updateSymbolsPossibilities() {
|
||||
for (Constraint constraint : constraints) {
|
||||
List<Cell> cells = this.getCells();
|
||||
for (Cell cell : cells) {
|
||||
Coordinate coord = null;
|
||||
@@ -275,7 +277,11 @@ public class Sudoku {
|
||||
System.out.println("Cas jamais atteint.");
|
||||
}
|
||||
List<Integer> newPossibleSymbols = cell.getPossibleSymbols();
|
||||
newPossibleSymbols.retainAll(constraint.getPossibleSymbols(this, coord.getX(), coord.getY()));
|
||||
newPossibleSymbols.retainAll(constraint.getPossibleSymbols(
|
||||
this,
|
||||
coord.getX(),
|
||||
coord.getY()
|
||||
));
|
||||
|
||||
cell.setPossibleSymbols(newPossibleSymbols);
|
||||
}
|
||||
@@ -323,7 +329,7 @@ public class Sudoku {
|
||||
return result;
|
||||
}
|
||||
for (int i = 0; i < this.constraints.size(); i++) {
|
||||
IConstraint constraint = this.constraints.get(i);
|
||||
Constraint constraint = this.constraints.get(i);
|
||||
if (i == 0) {
|
||||
result.addAll(constraint.getPossibleSymbols(this, cellCoordinates.getX(), cellCoordinates.getY()));
|
||||
} else {
|
||||
@@ -446,4 +452,8 @@ public class Sudoku {
|
||||
this.blockWidth = blockWidth;
|
||||
}
|
||||
|
||||
public boolean hasConstraint(Constraint constraint) {
|
||||
return this.constraints.contains(constraint);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package sudoku.structure;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -8,9 +11,10 @@ import java.util.Random;
|
||||
|
||||
import sudoku.constraint.BlockConstraint;
|
||||
import sudoku.constraint.ColumnConstraint;
|
||||
import sudoku.constraint.Constraint;
|
||||
import sudoku.constraint.DiagonalConstraint;
|
||||
import sudoku.constraint.IConstraint;
|
||||
import sudoku.constraint.LineConstraint;
|
||||
import sudoku.io.SudokuPrinter;
|
||||
import sudoku.solver.Solver;
|
||||
|
||||
public class SudokuFactory {
|
||||
@@ -19,18 +23,13 @@ public class SudokuFactory {
|
||||
* Générateur de nombre aléatoire.
|
||||
*/
|
||||
private static final Random random = new Random();
|
||||
/**
|
||||
* Difficulté avec le ration des cases qui seront vides.
|
||||
*/
|
||||
private static final double VERY_EASY = 0.1;
|
||||
private static final double EASY = 0.25;
|
||||
private static final double MEDIUM = 0.5;
|
||||
private static final double HARD = 0.75;
|
||||
|
||||
/**
|
||||
* Liste des contraintes par défaut d'un Multi- ou Sudoku.
|
||||
* Comprend les contraintes de blocs, de lignes, et de colonnes.
|
||||
*/
|
||||
public static List<IConstraint> DEFAULT_CONSTRAINTS = Arrays.asList(new BlockConstraint(), new LineConstraint(), new ColumnConstraint());
|
||||
public static List<Constraint> DEFAULT_CONSTRAINTS = Arrays.asList(Constraint.Block, Constraint.Column,
|
||||
Constraint.Line);
|
||||
|
||||
/**
|
||||
* Créée des Cells et les met dans une liste de taille size.
|
||||
@@ -81,9 +80,9 @@ public class SudokuFactory {
|
||||
* @param heightBlock int, hauteur des Blocks.
|
||||
* @return MultiDoku, MultiDoku vide.
|
||||
*/
|
||||
public static MultiDoku createBasicEmptyRectangleSudoku(int widthBlock, int heightBlock) {
|
||||
Sudoku s = createRectangleSudoku(widthBlock, heightBlock);
|
||||
return new MultiDoku(Arrays.asList(s));
|
||||
public static MultiDoku createBasicEmptyRectangleDoku(int widthBlock, int heightBlock,
|
||||
List<Constraint> constraints) {
|
||||
return new MultiDoku(Arrays.asList(createRectangleSudoku(widthBlock, heightBlock, constraints)));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,13 +90,13 @@ public class SudokuFactory {
|
||||
* @param size int, taille des Blocks.
|
||||
* @return MultiDoku, MultiDoku vide.
|
||||
*/
|
||||
public static MultiDoku createBasicEmptySquareSudoku(int size) {
|
||||
return createBasicEmptyRectangleSudoku(size, size);
|
||||
public static MultiDoku createBasicEmptySquareDoku(int size, List<Constraint> constraints) {
|
||||
return new MultiDoku(Arrays.asList(createSquareSudoku(size, constraints)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Place des Cells immutables de valeurs fournies, aux Coordinate fournies dans le MultiDoku doku fourni.
|
||||
* @param doku MultiDoku, MultiDoku à remplir.
|
||||
* @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) {
|
||||
@@ -120,7 +119,7 @@ public class SudokuFactory {
|
||||
* @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) throws Exception {
|
||||
public static boolean newDokuFromFilledOne(MultiDoku doku, int nbCellsToEmpty) throws Exception {
|
||||
|
||||
System.out.println("nbCellsToEmpty : "+nbCellsToEmpty);
|
||||
if (nbCellsToEmpty >= doku.getCells().size()) {
|
||||
@@ -152,37 +151,40 @@ public class SudokuFactory {
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Créée un Sudoku vide dont les Blocks sont de taille widthBlock par heightBlock.
|
||||
* @param widthBlock int, largeur des Blocks.
|
||||
* @param widthBlock int, largeur des Blocks.
|
||||
* @param heightBlock int, hauteur des Blocks.
|
||||
* @return Sudoku, Sudoku vide.
|
||||
*/
|
||||
private static Sudoku createRectangleSudoku(int widthBlock, int heightBlock) {
|
||||
private static Sudoku createRectangleSudoku(int widthBlock, int heightBlock, List<Constraint> constraints) {
|
||||
int symbolCount = widthBlock * heightBlock;
|
||||
List<Cell> cases = initCells(symbolCount);
|
||||
List<Block> blocs = initRectangleBlocs(cases, widthBlock, heightBlock);
|
||||
Sudoku s = new Sudoku(cases, blocs, DEFAULT_CONSTRAINTS);
|
||||
Sudoku s = new Sudoku(cases, blocs, constraints);
|
||||
for (Block block : s.getBlocks()) {
|
||||
block.getSudokus().add(s);
|
||||
}
|
||||
s.setBlockWidth(widthBlock);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Créée un Sudoku vide dont les Blocks sont carrés de longueur size.
|
||||
* @param size int, taille des Blocks.
|
||||
* @return Sudoku, Sudoku vide.
|
||||
*/
|
||||
private static Sudoku createSquareSudoku(int size) {
|
||||
return createRectangleSudoku(size, size);
|
||||
private static Sudoku createSquareSudoku(int size, List<Constraint> constraints) {
|
||||
return createRectangleSudoku(size, size, constraints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connecte deux Sudokus selon la décalage offset fourni.
|
||||
* @param sudoku1 Sudoku, premier sudoku à connecter.
|
||||
* @param sudoku2 Sudoku, second sudoku à connecter.
|
||||
* @param offset Coordinate, décalage entre les deux Sudokus.
|
||||
* @param offset Coordinate, décalage entre les deux Sudokus.
|
||||
*/
|
||||
private static void linkSquareSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) {
|
||||
int blockWidth = sudoku1.getBlockWidth();
|
||||
@@ -199,6 +201,7 @@ public class SudokuFactory {
|
||||
|
||||
// on remplace le bloc
|
||||
sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1);
|
||||
block1.getSudokus().add(sudoku2);
|
||||
|
||||
// on remplace les cellules
|
||||
for (int i = 0; i < block1.getCells().size(); i++) {
|
||||
@@ -218,7 +221,7 @@ public class SudokuFactory {
|
||||
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
|
||||
* @return MultiDoku, MultiDoku de forme X.
|
||||
*/
|
||||
public static MultiDoku createBasicXShapedMultidoku(int size) {
|
||||
public static MultiDoku createBasicXShapedMultidoku(int size, List<Constraint> constraints) {
|
||||
assert (size > 1);
|
||||
|
||||
/*
|
||||
@@ -227,11 +230,11 @@ public class SudokuFactory {
|
||||
* 4 5
|
||||
*/
|
||||
|
||||
Sudoku sudoku1 = createSquareSudoku(size);
|
||||
Sudoku sudoku2 = createSquareSudoku(size);
|
||||
Sudoku sudoku3 = createSquareSudoku(size);
|
||||
Sudoku sudoku4 = createSquareSudoku(size);
|
||||
Sudoku sudoku5 = createSquareSudoku(size);
|
||||
Sudoku sudoku1 = createSquareSudoku(size, constraints);
|
||||
Sudoku sudoku2 = createSquareSudoku(size, constraints);
|
||||
Sudoku sudoku3 = createSquareSudoku(size, constraints);
|
||||
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));
|
||||
@@ -243,15 +246,22 @@ public class SudokuFactory {
|
||||
|
||||
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
|
||||
Solver.solveRandom(doku, random);
|
||||
//SudokuPrinter.printRectangleSudoku(doku.getSubGrid(0), 3, 3);
|
||||
int nbCellsToEmpty = (int)(difficulty.getFactor()*doku.getNbCells());
|
||||
//System.out.println(nbCellsToEmpty);
|
||||
boolean successful = newDokuFromFilledOne(doku, nbCellsToEmpty);
|
||||
|
||||
|
||||
if (!successful) {
|
||||
int nbCellsToEmpty = (int) (difficulty.getFactor() * doku.getNbCells());
|
||||
boolean successfull = newDokuFromFilledOne(doku, nbCellsToEmpty);
|
||||
if (!successfull) {
|
||||
throw new Exception("Canno't create this doku with this difficulty");
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user