feat: dynamic constraints (Fixes #8)
All checks were successful
Linux arm64 / Build (push) Successful in 37s
All checks were successful
Linux arm64 / Build (push) Successful in 37s
This commit is contained in:
@@ -1,8 +1,10 @@
|
|||||||
package gui;
|
package gui;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import common.Signal;
|
import common.Signal;
|
||||||
import gui.ColorGenerator.Color;
|
import gui.ColorGenerator.Color;
|
||||||
@@ -11,10 +13,11 @@ import imgui.ImVec2;
|
|||||||
import imgui.ImVec4;
|
import imgui.ImVec4;
|
||||||
import imgui.flag.ImGuiCol;
|
import imgui.flag.ImGuiCol;
|
||||||
import imgui.flag.ImGuiStyleVar;
|
import imgui.flag.ImGuiStyleVar;
|
||||||
import imgui.flag.ImGuiWindowFlags;
|
import sudoku.constraint.Constraint;
|
||||||
import sudoku.structure.Block;
|
import sudoku.structure.Block;
|
||||||
import sudoku.structure.Cell;
|
import sudoku.structure.Cell;
|
||||||
import sudoku.structure.MultiDoku;
|
import sudoku.structure.MultiDoku;
|
||||||
|
import sudoku.structure.Sudoku;
|
||||||
|
|
||||||
public class SudokuRenderer {
|
public class SudokuRenderer {
|
||||||
|
|
||||||
@@ -24,13 +27,28 @@ public class SudokuRenderer {
|
|||||||
|
|
||||||
private static final ImVec4 BLACK = new ImVec4(0, 0, 0, 1);
|
private static final ImVec4 BLACK = new ImVec4(0, 0, 0, 1);
|
||||||
private static final ImVec4 TRANSPARENT = new ImVec4();
|
private static final ImVec4 TRANSPARENT = new ImVec4();
|
||||||
|
private static final ImVec4 WHITE = new ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
private static final ImVec2 cellSize = new ImVec2(50, 50);
|
private static final ImVec2 cellSize = new ImVec2(50, 50);
|
||||||
|
|
||||||
|
private final Set<Cell> diagonals = new HashSet<>();
|
||||||
|
|
||||||
public final Signal onResolve = new Signal();
|
public final Signal onResolve = new Signal();
|
||||||
|
|
||||||
public SudokuRenderer(MultiDoku doku) {
|
public SudokuRenderer(MultiDoku doku) {
|
||||||
this.doku = RenderableMultidoku.fromMultidoku(doku);
|
this.doku = RenderableMultidoku.fromMultidoku(doku);
|
||||||
this.colorPalette = initColors();
|
this.colorPalette = initColors();
|
||||||
|
initDiagonals();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initDiagonals() {
|
||||||
|
for (Sudoku sudoku : this.doku.getDoku().getSubGrids()) {
|
||||||
|
if (sudoku.hasConstraint(Constraint.Diagonal)) {
|
||||||
|
for (int i = 0; i < sudoku.getSize(); i++) {
|
||||||
|
this.diagonals.add(sudoku.getCell(i, i));
|
||||||
|
this.diagonals.add(sudoku.getCell(sudoku.getSize() - i - 1, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Block, Color> initColors() {
|
private Map<Block, Color> initColors() {
|
||||||
@@ -91,13 +109,16 @@ public class SudokuRenderer {
|
|||||||
ImGui.pushStyleColor(ImGuiCol.Border, TRANSPARENT);
|
ImGui.pushStyleColor(ImGuiCol.Border, TRANSPARENT);
|
||||||
ImGui.pushStyleColor(ImGuiCol.Button, TRANSPARENT);
|
ImGui.pushStyleColor(ImGuiCol.Button, TRANSPARENT);
|
||||||
ImGui.button("##" + index, cellSize);
|
ImGui.button("##" + index, cellSize);
|
||||||
|
} else {
|
||||||
|
if (diagonals.contains(cell)) {
|
||||||
|
ImGui.pushStyleColor(ImGuiCol.Border, WHITE);
|
||||||
} else {
|
} else {
|
||||||
ImGui.pushStyleColor(ImGuiCol.Border, BLACK);
|
ImGui.pushStyleColor(ImGuiCol.Border, BLACK);
|
||||||
|
}
|
||||||
int symbol = cell.getSymbolIndex();
|
int symbol = cell.getSymbolIndex();
|
||||||
Color blockColor = colorPalette.get(cell.getBlock());
|
Color blockColor = colorPalette.get(cell.getBlock());
|
||||||
if (!cell.isMutable()) {
|
if (!cell.isMutable()) {
|
||||||
blockColor = new Color(blockColor.r - 0.20f, blockColor.g - 0.20f, blockColor.b - 0.20f);
|
blockColor = new Color(blockColor.r - 0.20f, blockColor.g - 0.20f, blockColor.b - 0.20f);
|
||||||
} else {
|
|
||||||
}
|
}
|
||||||
ImGui.pushStyleColor(ImGuiCol.Button, new ImVec4(blockColor.r, blockColor.g, blockColor.b, 1.0f));
|
ImGui.pushStyleColor(ImGuiCol.Button, new ImVec4(blockColor.r, blockColor.g, blockColor.b, 1.0f));
|
||||||
String cellText = "";
|
String cellText = "";
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
package gui;
|
package gui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import common.Signal;
|
import common.Signal;
|
||||||
import imgui.ImGui;
|
import imgui.ImGui;
|
||||||
import imgui.extension.imguifiledialog.ImGuiFileDialog;
|
import imgui.extension.imguifiledialog.ImGuiFileDialog;
|
||||||
import imgui.extension.imguifiledialog.flag.ImGuiFileDialogFlags;
|
import imgui.extension.imguifiledialog.flag.ImGuiFileDialogFlags;
|
||||||
|
import imgui.type.ImBoolean;
|
||||||
import imgui.type.ImInt;
|
import imgui.type.ImInt;
|
||||||
|
import sudoku.constraint.Constraint;
|
||||||
import sudoku.structure.Difficulty;
|
import sudoku.structure.Difficulty;
|
||||||
import sudoku.structure.MultiDoku;
|
import sudoku.structure.MultiDoku;
|
||||||
import sudoku.structure.SudokuFactory;
|
import sudoku.structure.SudokuFactory;
|
||||||
@@ -19,7 +24,7 @@ public class SudokuSelector {
|
|||||||
private final ImInt sudokuType = new ImInt(0);
|
private final ImInt sudokuType = new ImInt(0);
|
||||||
|
|
||||||
private final ImInt difficulty = new ImInt(Difficulty.Medium.ordinal());
|
private final ImInt difficulty = new ImInt(Difficulty.Medium.ordinal());
|
||||||
private final String[] difficulties;
|
private final List<ImBoolean> contraints = new ArrayList<>();
|
||||||
|
|
||||||
private static final String[] sudokuTypes = { "Carré", "Rectangle", "Multidoku" };
|
private static final String[] sudokuTypes = { "Carré", "Rectangle", "Multidoku" };
|
||||||
private static final int SQUARE = 0, RECTANGLE = 1, MULTIDOKU = 2;
|
private static final int SQUARE = 0, RECTANGLE = 1, MULTIDOKU = 2;
|
||||||
@@ -31,10 +36,21 @@ public class SudokuSelector {
|
|||||||
|
|
||||||
public SudokuSelector(boolean canGenEmptyGrid) {
|
public SudokuSelector(boolean canGenEmptyGrid) {
|
||||||
this.canGenEmptyGrid = canGenEmptyGrid;
|
this.canGenEmptyGrid = canGenEmptyGrid;
|
||||||
Difficulty[] diffs = Difficulty.values();
|
initConstraints();
|
||||||
difficulties = new String[diffs.length];
|
}
|
||||||
for (int i = 0; i < diffs.length; i++) {
|
|
||||||
difficulties[i] = diffs[i].getDisplayName();
|
private List<Constraint> getConstraints() {
|
||||||
|
List<Constraint> constraints = new ArrayList<>();
|
||||||
|
for (int i = 0; i < this.contraints.size(); i++) {
|
||||||
|
if (this.contraints.get(i).get())
|
||||||
|
constraints.add(Constraint.values()[i]);
|
||||||
|
}
|
||||||
|
return constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initConstraints() {
|
||||||
|
for (Constraint cons : Constraint.values()) {
|
||||||
|
contraints.add(new ImBoolean(SudokuFactory.DEFAULT_CONSTRAINTS.contains(cons)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,15 +87,21 @@ public class SudokuSelector {
|
|||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
ImGui.combo("Type de Sudoku", sudokuType, sudokuTypes);
|
ImGui.combo("Type de Sudoku", sudokuType, sudokuTypes);
|
||||||
ImGui.combo("Difficulté", difficulty, difficulties);
|
ImGui.combo("Difficulté", difficulty, Difficulty.getDifficultyNames());
|
||||||
|
if (ImGui.treeNode("Constraintes")) {
|
||||||
|
for (Constraint cons : Constraint.values()) {
|
||||||
|
ImGui.checkbox(cons.getDisplayName(), contraints.get(cons.ordinal()));
|
||||||
|
}
|
||||||
|
ImGui.treePop();
|
||||||
|
}
|
||||||
switch (sudokuType.get()) {
|
switch (sudokuType.get()) {
|
||||||
case SQUARE:
|
case SQUARE:
|
||||||
ImGui.inputInt("Taille", sudokuSize);
|
ImGui.inputInt("Taille", sudokuSize);
|
||||||
if (ImGui.button("Résoudre un sudoku")) {
|
if (ImGui.button("Résoudre un sudoku")) {
|
||||||
selectSudoku(SudokuFactory.createBasicEmptySquareSudoku(sudokuSize.get()), false);
|
selectSudoku(SudokuFactory.createBasicEmptySquareDoku(sudokuSize.get(), getConstraints()), false);
|
||||||
}
|
}
|
||||||
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
||||||
selectSudoku(SudokuFactory.createBasicEmptySquareSudoku(sudokuSize.get()), true);
|
selectSudoku(SudokuFactory.createBasicEmptySquareDoku(sudokuSize.get(), getConstraints()), true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -88,22 +110,25 @@ public class SudokuSelector {
|
|||||||
ImGui.inputInt("Longueur", sudokuWidth);
|
ImGui.inputInt("Longueur", sudokuWidth);
|
||||||
if (ImGui.button("Résoudre un sudoku")) {
|
if (ImGui.button("Résoudre un sudoku")) {
|
||||||
selectSudoku(
|
selectSudoku(
|
||||||
SudokuFactory.createBasicEmptyRectangleSudoku(sudokuWidth.get(), sudokuHeight.get()),
|
SudokuFactory.createBasicEmptyRectangleDoku(sudokuWidth.get(), sudokuHeight.get(),
|
||||||
|
getConstraints()),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
||||||
selectSudoku(
|
selectSudoku(
|
||||||
SudokuFactory.createBasicEmptyRectangleSudoku(sudokuWidth.get(), sudokuHeight.get()), true);
|
SudokuFactory.createBasicEmptyRectangleDoku(sudokuWidth.get(), sudokuHeight.get(),
|
||||||
|
getConstraints()),
|
||||||
|
true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MULTIDOKU:
|
case MULTIDOKU:
|
||||||
ImGui.inputInt("Taille", sudokuSize);
|
ImGui.inputInt("Taille", sudokuSize);
|
||||||
if (ImGui.button("Résoudre un sudoku")) {
|
if (ImGui.button("Résoudre un sudoku")) {
|
||||||
selectSudoku(SudokuFactory.createBasicXShapedMultidoku(sudokuSize.get()), false);
|
selectSudoku(SudokuFactory.createBasicXShapedMultidoku(sudokuSize.get(), getConstraints()), false);
|
||||||
}
|
}
|
||||||
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
if (canGenEmptyGrid && ImGui.button("Générer une grille vide")) {
|
||||||
selectSudoku(SudokuFactory.createBasicXShapedMultidoku(sudokuSize.get()), true);
|
selectSudoku(SudokuFactory.createBasicXShapedMultidoku(sudokuSize.get(), getConstraints()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ public class MultiPlayerView extends BaseView {
|
|||||||
this.client = client;
|
this.client = client;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.client.onDisconnect.connect(this::onDisconnect);
|
this.client.onDisconnect.connect(this::onDisconnect);
|
||||||
this.client.onGameStarted.connect(() -> this.stateMachine.pushState(new MultiPlayerDokuView(stateMachine, client, server)));
|
this.client.onGameStarted
|
||||||
|
.connect(() -> this.stateMachine.pushState(new MultiPlayerDokuView(stateMachine, client, server)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -36,7 +37,7 @@ public class MultiPlayerView extends BaseView {
|
|||||||
} else {
|
} else {
|
||||||
if (ImGui.button("Démarrer")) {
|
if (ImGui.button("Démarrer")) {
|
||||||
// temp
|
// temp
|
||||||
MultiDoku doku = SudokuFactory.createBasicXShapedMultidoku(3);
|
MultiDoku doku = SudokuFactory.createBasicXShapedMultidoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
this.server.startGame(doku);
|
this.server.startGame(doku);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,30 +18,29 @@ public class Main {
|
|||||||
|
|
||||||
int blockWidth = 2;
|
int blockWidth = 2;
|
||||||
int blockHeight = 2;
|
int blockHeight = 2;
|
||||||
var multidoku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight);
|
var multidoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
|
||||||
|
SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
var sudoku = multidoku.getSubGrid(0);
|
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.");
|
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();
|
* Solver solver = new Solver();
|
||||||
ArrayList<IConstraint> constraints = new ArrayList<>();
|
* ArrayList<IConstraint> constraints = new ArrayList<>();
|
||||||
constraints.add(new LineConstraint());
|
* constraints.add(new LineConstraint());
|
||||||
constraints.add(new ColumnConstraint());
|
* constraints.add(new ColumnConstraint());
|
||||||
constraints.add(new BlockConstraint());
|
* constraints.add(new BlockConstraint());
|
||||||
try {
|
* try {
|
||||||
solver.solve(multidoku, constraints);
|
* solver.solve(multidoku, constraints);
|
||||||
} catch (Exception e) {
|
* } catch (Exception e) {
|
||||||
System.out.println(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ public class DiagonalConstraint implements IConstraint {
|
|||||||
}
|
}
|
||||||
} else if (s.getSize() - x == y) {
|
} else if (s.getSize() - x == y) {
|
||||||
for (int i = 0; i < s.getSize(); i++) {
|
for (int i = 0; i < s.getSize(); i++) {
|
||||||
if (s.getCell(s.getSize() - i, i).getSymbolIndex() == newSymbolIndex)
|
if (s.getCell(s.getSize() - i - 1, i).getSymbolIndex() == newSymbolIndex)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Class qui représente les block de chaque sudoku,
|
* 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 {
|
public class Block {
|
||||||
|
|
||||||
@@ -18,14 +19,15 @@ public class Block {
|
|||||||
* List de sudoku qui contiennent le block
|
* List de sudoku qui contiennent le block
|
||||||
* Pour un acces plus rapide aux sudokus
|
* Pour un acces plus rapide aux sudokus
|
||||||
*/
|
*/
|
||||||
private List<Sudoku> sudokus;
|
private final List<Sudoku> sudokus;
|
||||||
|
|
||||||
public Block(List<Cell> cells) {
|
public Block(List<Cell> cells) {
|
||||||
this.cells = cells;
|
this.cells = cells;
|
||||||
|
this.sudokus = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block() {
|
public Block() {
|
||||||
this.cells = new ArrayList<>();
|
this(new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Cell> getCells() {
|
public List<Cell> getCells() {
|
||||||
@@ -34,6 +36,7 @@ public class Block {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ajoute une Cell au Block
|
* Ajoute une Cell au Block
|
||||||
|
*
|
||||||
* @param newCell Cell, à ajouter
|
* @param newCell Cell, à ajouter
|
||||||
*/
|
*/
|
||||||
void addCell(Cell newCell) {
|
void addCell(Cell newCell) {
|
||||||
@@ -42,6 +45,7 @@ public class Block {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Cherche si le Block contient déjà un symbole donné.
|
* Cherche si le Block contient déjà un symbole donné.
|
||||||
|
*
|
||||||
* @param symbolIndex int, un index de symbole
|
* @param symbolIndex int, un index de symbole
|
||||||
* @return boolean, true s'il contient le symbole et false sinon
|
* @return boolean, true s'il contient le symbole et false sinon
|
||||||
*/
|
*/
|
||||||
@@ -65,8 +69,4 @@ public class Block {
|
|||||||
public List<Sudoku> getSudokus() {
|
public List<Sudoku> getSudokus() {
|
||||||
return sudokus;
|
return sudokus;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSudokus(List<Sudoku> sudokus) {
|
|
||||||
this.sudokus = sudokus;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ public enum Difficulty {
|
|||||||
double factor;
|
double factor;
|
||||||
String displayName;
|
String displayName;
|
||||||
|
|
||||||
Difficulty(String displayName, double factor) {
|
private Difficulty(String displayName, double factor) {
|
||||||
this.factor = factor;
|
this.factor = factor;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
@@ -21,4 +21,18 @@ public enum Difficulty {
|
|||||||
return factor;
|
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;
|
package sudoku.structure;
|
||||||
|
|
||||||
|
import sudoku.constraint.BlockConstraint;
|
||||||
|
import sudoku.constraint.Constraint;
|
||||||
import sudoku.constraint.IConstraint;
|
import sudoku.constraint.IConstraint;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -22,13 +24,14 @@ public class Sudoku {
|
|||||||
/**
|
/**
|
||||||
* Liste des contraintes (TODO) du 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.
|
* Largeur des Blocks s'ils sont rectangulaires, valant 0 si ce n'est pas le
|
||||||
|
* cas.
|
||||||
*/
|
*/
|
||||||
private int blockWidth;
|
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.cells = cells;
|
||||||
this.blocks = blocks;
|
this.blocks = blocks;
|
||||||
this.constraints = constraints;
|
this.constraints = constraints;
|
||||||
@@ -46,6 +49,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforme des coordonées d'une Cell en index.
|
* Transforme des coordonées d'une Cell en index.
|
||||||
|
*
|
||||||
* @param x int, abscisse.
|
* @param x int, abscisse.
|
||||||
* @param y int, ordonnée.
|
* @param y int, ordonnée.
|
||||||
* @return int, index correspondant.
|
* @return int, index correspondant.
|
||||||
@@ -56,7 +60,9 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie que des coordonnées correspondent bien à une Cell dans le Sudoku.
|
* Vérifie que des coordonnées correspondent bien à une Cell dans le Sudoku.
|
||||||
* @return boolean, valant true si les coordonnées sont dans les bornes du Sudoku, false sinon.
|
*
|
||||||
|
* @return boolean, valant true si les coordonnées sont dans les bornes du
|
||||||
|
* Sudoku, false sinon.
|
||||||
*/
|
*/
|
||||||
public boolean isValidCoords(int x, int y) {
|
public boolean isValidCoords(int x, int y) {
|
||||||
int index = toIndex(x, y);
|
int index = toIndex(x, y);
|
||||||
@@ -65,21 +71,25 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie que l'index correspond bien à une Cell dans le Sudoku.
|
* Vérifie que l'index correspond bien à une Cell dans le Sudoku.
|
||||||
* @return boolean, valant true si l'index est dans les bornes du Sudoku, false sinon.
|
*
|
||||||
|
* @return boolean, valant true si l'index est dans les bornes du Sudoku, false
|
||||||
|
* sinon.
|
||||||
*/
|
*/
|
||||||
public boolean isValidCoords(int index) {
|
public boolean isValidCoords(int index) {
|
||||||
return index < getSize() * getSize();
|
return index < getSize() * getSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Teste si on peut placer la value dans la Cell aux coordonnées x, y d'après les contraintes du 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 x int, abscisse de la Cell voulue.
|
||||||
* @param y int, ordonnée de la Cell voulue.
|
* @param y int, ordonnée de la Cell voulue.
|
||||||
* @param value int, index du symbole qu'on veut placer.
|
* @param value int, index du symbole qu'on veut placer.
|
||||||
* @return boolean, true si on peut la placer et false sinon.
|
* @return boolean, true si on peut la placer et false sinon.
|
||||||
*/
|
*/
|
||||||
public boolean canBePlaced(int x, int y, int value) {
|
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)) {
|
if (!constraint.canBePlaced(this, x, y, value)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -89,6 +99,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Tente de placer le symbole value dans la Cell de coordonnées x, y.
|
* Tente de placer le symbole value dans la Cell de coordonnées x, y.
|
||||||
|
*
|
||||||
* @param x int, abscisse de la Cell voulue.
|
* @param x int, abscisse de la Cell voulue.
|
||||||
* @param y int, coordonnée de la Cell voulue;
|
* @param y int, coordonnée de la Cell voulue;
|
||||||
* @param value int, index du symbole que l'on veut placer.
|
* @param value int, index du symbole que l'on veut placer.
|
||||||
@@ -105,6 +116,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vide la Cell dotn les coordonnées sont renseignées de son symbole.
|
* Vide la Cell dotn les coordonnées sont renseignées de son symbole.
|
||||||
|
*
|
||||||
* @param x int, abscisse de la Cell voulue.
|
* @param x int, abscisse de la Cell voulue.
|
||||||
* @param y int, coordonnée de la Cell voulue.
|
* @param y int, coordonnée de la Cell voulue.
|
||||||
*/
|
*/
|
||||||
@@ -132,6 +144,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Place le symbole d'index value dans la Cell de coordonnées précisées.
|
* Place le symbole d'index value dans la Cell de coordonnées précisées.
|
||||||
|
*
|
||||||
* @param x int, abscisse de la Cell voulue.
|
* @param x int, abscisse de la Cell voulue.
|
||||||
* @param y int, coordonnée de la Cell voulue.
|
* @param y int, coordonnée de la Cell voulue.
|
||||||
* @param value int, index du symbole à placer.
|
* @param value int, index du symbole à placer.
|
||||||
@@ -139,7 +152,7 @@ public class Sudoku {
|
|||||||
*/
|
*/
|
||||||
public Cell setCellSymbol(int x, int y, int value) {
|
public Cell setCellSymbol(int x, int y, int value) {
|
||||||
assert (isValidCoords(x, y));
|
assert (isValidCoords(x, y));
|
||||||
for (IConstraint constraint : this.constraints) {
|
for (Constraint constraint : this.constraints) {
|
||||||
if (!constraint.canBePlaced(this, x, y, value)) {
|
if (!constraint.canBePlaced(this, x, y, value)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -151,6 +164,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Place les symboles d'index contenus dans values dans les cases du Sudoku.
|
* Place les symboles d'index contenus dans values dans les cases du Sudoku.
|
||||||
|
*
|
||||||
* @param values List<Integer>, liste des index des symboles à placer.
|
* @param values List<Integer>, liste des index des symboles à placer.
|
||||||
* @return boolean, vaut true si les symboles ont été placés, false sinon.
|
* @return boolean, vaut true si les symboles ont été placés, false sinon.
|
||||||
*/
|
*/
|
||||||
@@ -168,7 +182,9 @@ public class Sudoku {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place les symboles d'index contenus dans values dans les cases du Sudoku et rend ces cases immuables.
|
* Place les symboles d'index contenus dans values dans les cases du Sudoku et
|
||||||
|
* rend ces cases immuables.
|
||||||
|
*
|
||||||
* @param values List<Integer>, liste des index des symboles à placer.
|
* @param values List<Integer>, liste des index des symboles à placer.
|
||||||
* @return boolean, vaut true si les symboles ont été placés, false sinon.
|
* @return boolean, vaut true si les symboles ont été placés, false sinon.
|
||||||
*/
|
*/
|
||||||
@@ -205,7 +221,7 @@ public class Sudoku {
|
|||||||
return this.cells.get(i);
|
return this.cells.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IConstraint> getConstraints() {
|
public List<Constraint> getConstraints() {
|
||||||
return constraints;
|
return constraints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,6 +239,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie si une Cell appartient au Sudoku.
|
* Vérifie si une Cell appartient au Sudoku.
|
||||||
|
*
|
||||||
* @param cell Cell, cellule dont on veut vérifier l'appartenance au Sudoku.
|
* @param cell Cell, cellule dont on veut vérifier l'appartenance au Sudoku.
|
||||||
* @return boolean, vaut true si la Cell appartient au Sudoku.
|
* @return boolean, vaut true si la Cell appartient au Sudoku.
|
||||||
*/
|
*/
|
||||||
@@ -232,6 +249,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Localise la Cell dans le Sudoku.
|
* Localise la Cell dans le Sudoku.
|
||||||
|
*
|
||||||
* @param c Cell, cellule dont on veut les coordonées.
|
* @param c Cell, cellule dont on veut les coordonées.
|
||||||
* @return Coordinate, coordonnées de la Cell.
|
* @return Coordinate, coordonnées de la Cell.
|
||||||
* @throws Exception si la Cell n'appartient pas au Sudoku.
|
* @throws Exception si la Cell n'appartient pas au Sudoku.
|
||||||
@@ -265,7 +283,7 @@ public class Sudoku {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void updateSymbolsPossibilities() {
|
public void updateSymbolsPossibilities() {
|
||||||
for (IConstraint constraint : constraints) {
|
for (Constraint constraint : constraints) {
|
||||||
List<Cell> cells = this.getCells();
|
List<Cell> cells = this.getCells();
|
||||||
for (Cell cell : cells) {
|
for (Cell cell : cells) {
|
||||||
Coordinate coord = null;
|
Coordinate coord = null;
|
||||||
@@ -275,7 +293,8 @@ public class Sudoku {
|
|||||||
System.out.println("Cas jamais atteint.");
|
System.out.println("Cas jamais atteint.");
|
||||||
}
|
}
|
||||||
List<Integer> newPossibleSymbols = cell.getPossibleSymbols();
|
List<Integer> newPossibleSymbols = cell.getPossibleSymbols();
|
||||||
newPossibleSymbols.retainAll(constraint.getPossibleSymbols(this, coord.getX(), coord.getY()));
|
newPossibleSymbols
|
||||||
|
.retainAll(constraint.getConstraint().getPossibleSymbols(this, coord.getX(), coord.getY()));
|
||||||
|
|
||||||
cell.setPossibleSymbols(newPossibleSymbols);
|
cell.setPossibleSymbols(newPossibleSymbols);
|
||||||
}
|
}
|
||||||
@@ -298,6 +317,7 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie la 1re Cell vide du Sudoku.
|
* Renvoie la 1re Cell vide du Sudoku.
|
||||||
|
*
|
||||||
* @return Cell, une Cell vide, ou null s'il n'y en a pas.
|
* @return Cell, une Cell vide, ou null s'il n'y en a pas.
|
||||||
*/
|
*/
|
||||||
public Cell getFirstEmptyCell() {
|
public Cell getFirstEmptyCell() {
|
||||||
@@ -311,8 +331,10 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Renvoie l'index des symboles possibles de la Cell passée en paramètres.
|
* Renvoie l'index des symboles possibles de la Cell passée en paramètres.
|
||||||
|
*
|
||||||
* @param cellToFill Cell, cellule dont on cherche les symboles posisbles.
|
* @param cellToFill Cell, cellule dont on cherche les symboles posisbles.
|
||||||
* @return List<Integer>, la liste des index des symboles possibles, vide si la Cell n'appartient pas au Sudoku.
|
* @return List<Integer>, la liste des index des symboles possibles, vide si la
|
||||||
|
* Cell n'appartient pas au Sudoku.
|
||||||
*/
|
*/
|
||||||
public List<Integer> getPossibleSymbolsOfCell(Cell cellToFill) {
|
public List<Integer> getPossibleSymbolsOfCell(Cell cellToFill) {
|
||||||
List<Integer> result = new ArrayList<>();
|
List<Integer> result = new ArrayList<>();
|
||||||
@@ -323,7 +345,7 @@ public class Sudoku {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < this.constraints.size(); i++) {
|
for (int i = 0; i < this.constraints.size(); i++) {
|
||||||
IConstraint constraint = this.constraints.get(i);
|
Constraint constraint = this.constraints.get(i);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
result.addAll(constraint.getPossibleSymbols(this, cellCoordinates.getX(), cellCoordinates.getY()));
|
result.addAll(constraint.getPossibleSymbols(this, cellCoordinates.getX(), cellCoordinates.getY()));
|
||||||
} else {
|
} else {
|
||||||
@@ -335,7 +357,9 @@ public class Sudoku {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Vérifie que le Sudoku est cohérent avec ses contraintes.
|
* Vérifie que le Sudoku est cohérent avec ses contraintes.
|
||||||
* @return boolean, valant true si le Sudoku est cohérent avec ses contraintes, false sinon.
|
*
|
||||||
|
* @return boolean, valant true si le Sudoku est cohérent avec ses contraintes,
|
||||||
|
* false sinon.
|
||||||
*/
|
*/
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
for (Cell cell : this.cells) {
|
for (Cell cell : this.cells) {
|
||||||
@@ -343,7 +367,7 @@ public class Sudoku {
|
|||||||
if (cell.isEmpty()) {
|
if (cell.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (IConstraint constraint : this.constraints) {
|
for (Constraint constraint : this.constraints) {
|
||||||
Coordinate coords;
|
Coordinate coords;
|
||||||
try {
|
try {
|
||||||
int symbolPlaced = cell.getSymbolIndex();
|
int symbolPlaced = cell.getSymbolIndex();
|
||||||
@@ -389,4 +413,8 @@ public class Sudoku {
|
|||||||
this.blockWidth = blockWidth;
|
this.blockWidth = blockWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasConstraint(Constraint constraint) {
|
||||||
|
return this.constraints.contains(constraint);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import java.util.Random;
|
|||||||
|
|
||||||
import sudoku.constraint.BlockConstraint;
|
import sudoku.constraint.BlockConstraint;
|
||||||
import sudoku.constraint.ColumnConstraint;
|
import sudoku.constraint.ColumnConstraint;
|
||||||
|
import sudoku.constraint.Constraint;
|
||||||
|
import sudoku.constraint.DiagonalConstraint;
|
||||||
import sudoku.constraint.IConstraint;
|
import sudoku.constraint.IConstraint;
|
||||||
import sudoku.constraint.LineConstraint;
|
import sudoku.constraint.LineConstraint;
|
||||||
import sudoku.io.SudokuSerializer;
|
import sudoku.io.SudokuSerializer;
|
||||||
@@ -27,10 +29,12 @@ public class SudokuFactory {
|
|||||||
* Liste des contraintes par défaut d'un Multi- ou Sudoku.
|
* Liste des contraintes par défaut d'un Multi- ou Sudoku.
|
||||||
* 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 = 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.
|
* Créée des Cells et les met dans une liste de taille size.
|
||||||
|
*
|
||||||
* @param size int, nombre de Cells à initialiser.
|
* @param size int, nombre de Cells à initialiser.
|
||||||
* @return List<Cell>, liste des Cells initialisées.
|
* @return List<Cell>, liste des Cells initialisées.
|
||||||
*/
|
*/
|
||||||
@@ -43,7 +47,9 @@ public class SudokuFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée des Blocks de taille width par height à partir des cellules données, et les met dans une liste.
|
* Créée des Blocks de taille width par height à partir des cellules données, et
|
||||||
|
* les met dans une liste.
|
||||||
|
*
|
||||||
* @param cells List<Cell>, liste des Cells à découper en Blocks.
|
* @param cells List<Cell>, liste des Cells à découper en Blocks.
|
||||||
* @param width int, largeur des Blocks à créer.
|
* @param width int, largeur des Blocks à créer.
|
||||||
* @param height int, hauteur des Blocks à créer.
|
* @param height int, hauteur des Blocks à créer.
|
||||||
@@ -73,29 +79,36 @@ public class SudokuFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée un MultiDoku vide dont les Blocks sont de taille widthBlock par heightBlock.
|
* Créée un MultiDoku 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.
|
* @param heightBlock int, hauteur des Blocks.
|
||||||
* @return MultiDoku, MultiDoku vide.
|
* @return MultiDoku, MultiDoku vide.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicEmptyRectangleSudoku(int widthBlock, int heightBlock) {
|
public static MultiDoku createBasicEmptyRectangleDoku(int widthBlock, int heightBlock,
|
||||||
Sudoku s = createRectangleSudoku(widthBlock, heightBlock);
|
List<Constraint> constraints) {
|
||||||
return new MultiDoku(Arrays.asList(s));
|
return new MultiDoku(Arrays.asList(createRectangleSudoku(widthBlock, heightBlock, constraints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée un MultiDoku vide dont les Blocks sont carrés de longueur size.
|
* Créée un MultiDoku vide dont les Blocks sont carrés de longueur size.
|
||||||
|
*
|
||||||
* @param size int, taille des Blocks.
|
* @param size int, taille des Blocks.
|
||||||
* @return MultiDoku, MultiDoku vide.
|
* @return MultiDoku, MultiDoku vide.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicEmptySquareSudoku(int size) {
|
public static MultiDoku createBasicEmptySquareDoku(int size, List<Constraint> constraints) {
|
||||||
return createBasicEmptyRectangleSudoku(size, size);
|
return new MultiDoku(Arrays.asList(createSquareSudoku(size, constraints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Place des Cells immutables de valeurs fournies, aux Coordinate fournies dans le MultiDoku doku fourni.
|
* 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.
|
* @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) {
|
public static void setImmutableCells(MultiDoku doku, Map<Coordinate, Integer> immutableCells) {
|
||||||
immutableCells.forEach((coordinate, symbol) -> {
|
immutableCells.forEach((coordinate, symbol) -> {
|
||||||
@@ -114,8 +127,10 @@ public class SudokuFactory {
|
|||||||
*
|
*
|
||||||
* @param doku MultiDoku, MultiDoku dont on doit vider des Cells.
|
* @param doku MultiDoku, MultiDoku dont on doit vider des Cells.
|
||||||
* @param nbCellsToEmpty int, nombre de cases à retirer.
|
* @param nbCellsToEmpty int, nombre de cases à retirer.
|
||||||
* @return boolean, valant true si un MultiDoku de difficulté donnée peut être créée, false sinon.
|
* @return boolean, valant true si un MultiDoku de difficulté donnée peut être
|
||||||
* @throws Exception si la difficulté n'est pas compatible avec la taille du MultiDoku.
|
* 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 {
|
||||||
|
|
||||||
@@ -149,31 +164,38 @@ public class SudokuFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée un Sudoku vide dont les Blocks sont de taille widthBlock par heightBlock.
|
* 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.
|
* @param heightBlock int, hauteur des Blocks.
|
||||||
* @return Sudoku, Sudoku vide.
|
* @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;
|
int symbolCount = widthBlock * heightBlock;
|
||||||
List<Cell> cases = initCells(symbolCount);
|
List<Cell> cases = initCells(symbolCount);
|
||||||
List<Block> blocs = initRectangleBlocs(cases, widthBlock, heightBlock);
|
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);
|
s.setBlockWidth(widthBlock);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Créée un Sudoku vide dont les Blocks sont carrés de longueur size.
|
* Créée un Sudoku vide dont les Blocks sont carrés de longueur size.
|
||||||
|
*
|
||||||
* @param size int, taille des Blocks.
|
* @param size int, taille des Blocks.
|
||||||
* @return Sudoku, Sudoku vide.
|
* @return Sudoku, Sudoku vide.
|
||||||
*/
|
*/
|
||||||
private static Sudoku createSquareSudoku(int size) {
|
private static Sudoku createSquareSudoku(int size, List<Constraint> constraints) {
|
||||||
return createRectangleSudoku(size, size);
|
return createRectangleSudoku(size, size, constraints);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connecte deux Sudokus selon la décalage offset fourni.
|
* Connecte deux Sudokus selon la décalage offset fourni.
|
||||||
|
*
|
||||||
* @param sudoku1 Sudoku, premier sudoku à connecter.
|
* @param sudoku1 Sudoku, premier sudoku à connecter.
|
||||||
* @param sudoku2 Sudoku, second 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.
|
||||||
@@ -193,6 +215,7 @@ public class SudokuFactory {
|
|||||||
|
|
||||||
// on remplace le bloc
|
// on remplace le bloc
|
||||||
sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1);
|
sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1);
|
||||||
|
block1.getSudokus().add(sudoku2);
|
||||||
|
|
||||||
// on remplace les cellules
|
// on remplace les cellules
|
||||||
for (int i = 0; i < block1.getCells().size(); i++) {
|
for (int i = 0; i < block1.getCells().size(); i++) {
|
||||||
@@ -208,11 +231,14 @@ 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.
|
* 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.
|
||||||
|
*
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicXShapedMultidoku(int size) {
|
public static MultiDoku createBasicXShapedMultidoku(int size, List<Constraint> constraints) {
|
||||||
assert (size > 1);
|
assert (size > 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -221,11 +247,11 @@ public class SudokuFactory {
|
|||||||
* 4 5
|
* 4 5
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Sudoku sudoku1 = createSquareSudoku(size);
|
Sudoku sudoku1 = createSquareSudoku(size, constraints);
|
||||||
Sudoku sudoku2 = createSquareSudoku(size);
|
Sudoku sudoku2 = createSquareSudoku(size, constraints);
|
||||||
Sudoku sudoku3 = createSquareSudoku(size);
|
Sudoku sudoku3 = createSquareSudoku(size, constraints);
|
||||||
Sudoku sudoku4 = createSquareSudoku(size);
|
Sudoku sudoku4 = createSquareSudoku(size, constraints);
|
||||||
Sudoku sudoku5 = createSquareSudoku(size);
|
Sudoku sudoku5 = createSquareSudoku(size, constraints);
|
||||||
|
|
||||||
linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size));
|
linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size));
|
||||||
linkSquareSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size));
|
linkSquareSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size));
|
||||||
|
|||||||
@@ -13,14 +13,16 @@ import sudoku.structure.SudokuFactory;
|
|||||||
public class SudokuSerializerTest {
|
public class SudokuSerializerTest {
|
||||||
|
|
||||||
void testSerializeWithSize(int blockWidth, int blockHeight) {
|
void testSerializeWithSize(int blockWidth, int blockHeight) {
|
||||||
var sudoku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight);
|
var sudoku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
|
||||||
|
SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
JSONObject data = SudokuSerializer.serializeSudoku(sudoku);
|
JSONObject data = SudokuSerializer.serializeSudoku(sudoku);
|
||||||
MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data);
|
MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data);
|
||||||
assert (data.toString().equals(SudokuSerializer.serializeSudoku(multiDoku).toString()));
|
assert (data.toString().equals(SudokuSerializer.serializeSudoku(multiDoku).toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void testSaveWithSize(int blockWidth, int blockHeight) {
|
void testSaveWithSize(int blockWidth, int blockHeight) {
|
||||||
MultiDoku doku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight);
|
MultiDoku doku = SudokuFactory.createBasicEmptyRectangleDoku(blockWidth, blockHeight,
|
||||||
|
SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
String savePath = SudokuSerializer.saveMultiDoku(doku);
|
String savePath = SudokuSerializer.saveMultiDoku(doku);
|
||||||
MultiDoku otherDoku = null;
|
MultiDoku otherDoku = null;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -16,8 +16,8 @@ class SolverTest {
|
|||||||
void solveTest() {
|
void solveTest() {
|
||||||
Random rand = new Random();
|
Random rand = new Random();
|
||||||
|
|
||||||
MultiDoku dokuToTest = SudokuFactory.createBasicEmptySquareSudoku(3);
|
MultiDoku dokuToTest = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
MultiDoku dokuResult = SudokuFactory.createBasicEmptySquareSudoku(3);
|
MultiDoku dokuResult = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
|
|
||||||
Sudoku sudokuToTest = dokuToTest.getSubGrid(0);
|
Sudoku sudokuToTest = dokuToTest.getSubGrid(0);
|
||||||
Sudoku sudokuResult = dokuResult.getSubGrid(0);
|
Sudoku sudokuResult = dokuResult.getSubGrid(0);
|
||||||
@@ -35,10 +35,8 @@ class SolverTest {
|
|||||||
|
|
||||||
assert (sudokuToTest.setImmutableCellsSymbol(immutableCells));
|
assert (sudokuToTest.setImmutableCellsSymbol(immutableCells));
|
||||||
|
|
||||||
|
|
||||||
SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3);
|
SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3);
|
||||||
|
|
||||||
|
|
||||||
List<Integer> correctCells = List.of(7, 6, 0, 3, 4, 2, 8, 5, 1,
|
List<Integer> correctCells = List.of(7, 6, 0, 3, 4, 2, 8, 5, 1,
|
||||||
2, 3, 8, 1, 5, 6, 7, 0, 4,
|
2, 3, 8, 1, 5, 6, 7, 0, 4,
|
||||||
1, 4, 5, 8, 0, 7, 3, 2, 6,
|
1, 4, 5, 8, 0, 7, 3, 2, 6,
|
||||||
@@ -51,25 +49,21 @@ class SolverTest {
|
|||||||
|
|
||||||
sudokuResult.setCellsSymbol(correctCells);
|
sudokuResult.setCellsSymbol(correctCells);
|
||||||
|
|
||||||
|
|
||||||
System.out.println("\n****************************Doku Control\n");
|
System.out.println("\n****************************Doku Control\n");
|
||||||
SudokuPrinter.printRectangleSudoku(sudokuResult, 3, 3);
|
SudokuPrinter.printRectangleSudoku(sudokuResult, 3, 3);
|
||||||
|
|
||||||
|
|
||||||
assert (dokuResult.isValid());
|
assert (dokuResult.isValid());
|
||||||
|
|
||||||
Solver.solveRandom(dokuToTest, rand);
|
Solver.solveRandom(dokuToTest, rand);
|
||||||
|
|
||||||
|
|
||||||
System.out.println("\n****************************\nDoku solved");
|
System.out.println("\n****************************\nDoku solved");
|
||||||
SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3);
|
SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3);
|
||||||
|
|
||||||
|
|
||||||
assert (dokuToTest.isValid());
|
assert (dokuToTest.isValid());
|
||||||
|
|
||||||
assert (dokuToTest.equals(dokuResult));
|
assert (dokuToTest.equals(dokuResult));
|
||||||
|
|
||||||
MultiDoku dokuToTest2 = SudokuFactory.createBasicEmptySquareSudoku(3);
|
MultiDoku dokuToTest2 = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
Sudoku sudokuToTest2 = dokuToTest2.getSubGrid(0);
|
Sudoku sudokuToTest2 = dokuToTest2.getSubGrid(0);
|
||||||
|
|
||||||
List<Integer> immutableCells2 = List.of(ns, ns, 0, ns, ns, 2, 8, ns, 1,
|
List<Integer> immutableCells2 = List.of(ns, ns, 0, ns, ns, 2, 8, ns, 1,
|
||||||
@@ -87,7 +81,7 @@ class SolverTest {
|
|||||||
|
|
||||||
assert (!isSolved);
|
assert (!isSolved);
|
||||||
|
|
||||||
MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareSudoku(3);
|
MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareDoku(3, SudokuFactory.DEFAULT_CONSTRAINTS);
|
||||||
|
|
||||||
Solver.solveRandom(dokuToTest3, rand);
|
Solver.solveRandom(dokuToTest3, rand);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user