This commit is contained in:
@@ -9,11 +9,10 @@ import java.util.Random;
|
|||||||
import sudoku.structure.Cell;
|
import sudoku.structure.Cell;
|
||||||
import sudoku.structure.MultiDoku;
|
import sudoku.structure.MultiDoku;
|
||||||
|
|
||||||
|
//TODO
|
||||||
public class HintHelper {
|
public class HintHelper {
|
||||||
|
|
||||||
public static record Hint(Cell cell, int newValue) {
|
public static record Hint(Cell cell, int newValue) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Hint getHint(MultiDoku doku, Solver solver) {
|
public static Hint getHint(MultiDoku doku, Solver solver) {
|
||||||
doku.getStateManager().pushState();
|
doku.getStateManager().pushState();
|
||||||
@@ -36,7 +35,7 @@ public class HintHelper {
|
|||||||
if (newValue == Cell.NOSYMBOL)
|
if (newValue == Cell.NOSYMBOL)
|
||||||
return new Hint(cell, newValue);
|
return new Hint(cell, newValue);
|
||||||
// we have to change the cell value
|
// we have to change the cell value
|
||||||
if (oldValue != Cell.NOSYMBOL && newValue != oldValue)
|
if (oldValue != Cell.NOSYMBOL)
|
||||||
return new Hint(cell, newValue);
|
return new Hint(cell, newValue);
|
||||||
|
|
||||||
// there is a valid move
|
// there is a valid move
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class Block {
|
|||||||
*
|
*
|
||||||
* @param newCell Cell, à ajouter
|
* @param newCell Cell, à ajouter
|
||||||
*/
|
*/
|
||||||
void addCell(Cell newCell) {
|
public void addCell(Cell newCell) {
|
||||||
this.cells.add(newCell);
|
this.cells.add(newCell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Cell {
|
public class Cell {
|
||||||
|
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="ATTRIBUTS">
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constante de valeur d'index de symbole quand il n'y en a pas,
|
* Constante de valeur d'index de symbole quand il n'y en a pas,
|
||||||
* soit que la Cell est vide.
|
* soit que la Cell est vide.
|
||||||
@@ -29,6 +31,10 @@ public class Cell {
|
|||||||
*/
|
*/
|
||||||
private boolean isMutable = true;
|
private boolean isMutable = true;
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
|
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="METHODES">
|
||||||
|
|
||||||
public Cell() {
|
public Cell() {
|
||||||
this(Cell.NOSYMBOL);
|
this(Cell.NOSYMBOL);
|
||||||
}
|
}
|
||||||
@@ -46,6 +52,22 @@ public class Cell {
|
|||||||
return this.symbolIndex;
|
return this.symbolIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie le Block qui la contient.
|
||||||
|
* @return Block.
|
||||||
|
*/
|
||||||
|
public Block getBlock() {
|
||||||
|
return this.blockContainer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie si la Cell est modifiable
|
||||||
|
* @return boolean, true si elle est modifiable ou false sinon.
|
||||||
|
*/
|
||||||
|
public boolean isMutable() {
|
||||||
|
return this.isMutable;
|
||||||
|
}
|
||||||
|
|
||||||
public void setSymbolIndex(int symbolIndex) {
|
public void setSymbolIndex(int symbolIndex) {
|
||||||
this.symbolIndex = symbolIndex;
|
this.symbolIndex = symbolIndex;
|
||||||
}
|
}
|
||||||
@@ -57,22 +79,16 @@ public class Cell {
|
|||||||
this.isMutable = false;
|
this.isMutable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock() {
|
|
||||||
return this.blockContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBlock(Block block) {
|
public void setBlock(Block block) {
|
||||||
this.blockContainer = block;
|
this.blockContainer = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the current symbolIndex and returns it
|
* Vide la Cell.
|
||||||
* @return integer symbolIndex cleared
|
|
||||||
*/
|
*/
|
||||||
public int clearCurrentSymbol() {
|
public void clearCurrentSymbol() {
|
||||||
int i = this.symbolIndex;
|
|
||||||
setSymbolIndex(NOSYMBOL);
|
setSymbolIndex(NOSYMBOL);
|
||||||
return i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,14 +99,6 @@ public class Cell {
|
|||||||
return this.symbolIndex == Cell.NOSYMBOL;
|
return this.symbolIndex == Cell.NOSYMBOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Renvoie si la Cell est modifiable
|
|
||||||
* @return boolean, true si elle est modifiable ou false sinon.
|
|
||||||
*/
|
|
||||||
public boolean isMutable() {
|
|
||||||
return this.isMutable;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vide la Cell, en renvoie l'ancien index du symbole qui était dedans.
|
* Vide la Cell, en renvoie l'ancien index du symbole qui était dedans.
|
||||||
* @return int, index du symbole anciennement contenue dans la Cell.
|
* @return int, index du symbole anciennement contenue dans la Cell.
|
||||||
@@ -101,6 +109,11 @@ public class Cell {
|
|||||||
return oldSymbol;
|
return oldSymbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si la Cell peut prendre ce symbole par rapport aux contraintes de ses Sudokus.
|
||||||
|
* @param value int, index du symbole
|
||||||
|
* @return boolean, true si elle peut, false sinon.
|
||||||
|
*/
|
||||||
public boolean canHaveValue(int value) {
|
public boolean canHaveValue(int value) {
|
||||||
for (Sudoku s :getBlock().getSudokus()) {
|
for (Sudoku s :getBlock().getSudokus()) {
|
||||||
int cellIndex = s.getCells().indexOf(this);
|
int cellIndex = s.getCells().indexOf(this);
|
||||||
@@ -116,6 +129,10 @@ public class Cell {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renvoie les symboles que peut prendre cette Cell par rapport aux contraintes de ses Sudokus.
|
||||||
|
* @return List<Integer>, la liste des symboles possibles.
|
||||||
|
*/
|
||||||
public List<Integer> getPossibleSymbols() {
|
public List<Integer> getPossibleSymbols() {
|
||||||
List<Integer> result = new ArrayList<>();
|
List<Integer> result = new ArrayList<>();
|
||||||
for (int i = 0; i < getBlock().getSudokus().get(0).getSize(); i++) {
|
for (int i = 0; i < getBlock().getSudokus().get(0).getSize(); i++) {
|
||||||
@@ -125,6 +142,11 @@ public class Cell {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Essaye de placer la valeur et renvoie false si ce n'est pas possible.
|
||||||
|
* @param newValue int, valeur à placer.
|
||||||
|
* @return boolean, true si la Cell à pris la valeur newValue, false sinon.
|
||||||
|
*/
|
||||||
public boolean trySetValue(int newValue) {
|
public boolean trySetValue(int newValue) {
|
||||||
if (!isMutable())
|
if (!isMutable())
|
||||||
return false;
|
return false;
|
||||||
@@ -133,4 +155,6 @@ public class Cell {
|
|||||||
setSymbolIndex(newValue);
|
setSymbolIndex(newValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// </editor-fold>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class SudokuFactory {
|
|||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicEmptyRectangleDoku(int widthBlock, int heightBlock,
|
public static MultiDoku createBasicEmptyRectangleDoku(int widthBlock, int heightBlock,
|
||||||
List<IConstraint> constraints) {
|
List<IConstraint> constraints) {
|
||||||
return new MultiDoku(Arrays.asList(createRectangleSudoku(widthBlock, heightBlock, constraints)));
|
return new MultiDoku(List.of(createRectangleSudoku(widthBlock, heightBlock, constraints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -96,7 +96,7 @@ public class SudokuFactory {
|
|||||||
* @return MultiDoku, MultiDoku vide.
|
* @return MultiDoku, MultiDoku vide.
|
||||||
*/
|
*/
|
||||||
public static MultiDoku createBasicEmptySquareDoku(int size, List<IConstraint> constraints) {
|
public static MultiDoku createBasicEmptySquareDoku(int size, List<IConstraint> constraints) {
|
||||||
return new MultiDoku(Arrays.asList(createSquareSudoku(size, constraints)));
|
return new MultiDoku(List.of(createSquareSudoku(size, constraints)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,24 +234,7 @@ public class SudokuFactory {
|
|||||||
public static MultiDoku createBasicXShapedMultidoku(int size, List<IConstraint> constraints) {
|
public static MultiDoku createBasicXShapedMultidoku(int size, List<IConstraint> constraints) {
|
||||||
assert (size > 1);
|
assert (size > 1);
|
||||||
|
|
||||||
/*
|
return createBasicXShapedMultidoku(size, size, constraints);
|
||||||
* 2 3
|
|
||||||
* 1
|
|
||||||
* 4 5
|
|
||||||
*/
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size));
|
|
||||||
linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size));
|
|
||||||
linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1));
|
|
||||||
linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1));
|
|
||||||
|
|
||||||
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -287,6 +270,55 @@ public class SudokuFactory {
|
|||||||
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
* Sudoku.
|
||||||
|
*
|
||||||
|
* @param size int, largeur des Blocks unitraires des Sudokus à crééer.
|
||||||
|
* @return MultiDoku, MultiDoku de forme X.
|
||||||
|
*/
|
||||||
|
public static MultiDoku createBasicPlusShapedMultidoku(int size, List<IConstraint> constraints) {
|
||||||
|
assert (size > 1);
|
||||||
|
|
||||||
|
return createBasicPlusShapedMultidoku(size, size, constraints);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
* Créée un MultiDoku de Blocks rectangulaires de forme width par height composé
|
||||||
|
* de cinq Sudokus,
|
||||||
|
* dont un central qui partage chacun de ses Blocks d'angle avec un autre
|
||||||
|
* 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
|
||||||
|
* 2 1 4
|
||||||
|
* 5
|
||||||
|
*/
|
||||||
|
|
||||||
|
Sudoku sudoku1 = createRectangleSudoku(width, height, constraints);
|
||||||
|
Sudoku sudoku2 = createRectangleSudoku(width, height, constraints);
|
||||||
|
Sudoku sudoku3 = createRectangleSudoku(width, height, constraints);
|
||||||
|
Sudoku sudoku4 = createRectangleSudoku(width, height, constraints);
|
||||||
|
Sudoku sudoku5 = createRectangleSudoku(width, height, constraints);
|
||||||
|
|
||||||
|
linkRectangleSudokus(sudoku1, sudoku2, new Coordinate(1 - height, 0));
|
||||||
|
linkRectangleSudokus(sudoku1, sudoku3, new Coordinate(0, 1 - width));
|
||||||
|
linkRectangleSudokus(sudoku1, sudoku4, new Coordinate(height - 1, 0));
|
||||||
|
linkRectangleSudokus(sudoku1, sudoku5, new Coordinate(0, width - 1));
|
||||||
|
|
||||||
|
return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5));
|
||||||
|
}
|
||||||
|
|
||||||
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
|
public static void fillDoku(MultiDoku doku, Difficulty difficulty) throws Exception {
|
||||||
Solver solver = new RandomSolver();
|
Solver solver = new RandomSolver();
|
||||||
solver.solve(doku);
|
solver.solve(doku);
|
||||||
@@ -309,8 +341,7 @@ public class SudokuFactory {
|
|||||||
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);
|
||||||
List<Cell> homeLessCells = new ArrayList<>();
|
List<Cell> homeLessCells = new ArrayList<>(cells);
|
||||||
homeLessCells.addAll(cells);
|
|
||||||
List<Block> blocks = new ArrayList<>();
|
List<Block> blocks = new ArrayList<>();
|
||||||
Random r = new Random();
|
Random r = new Random();
|
||||||
for (int i = 0; i < blockCellCount; i++) {
|
for (int i = 0; i < blockCellCount; i++) {
|
||||||
@@ -327,7 +358,7 @@ public class SudokuFactory {
|
|||||||
for (Block block : blocks) {
|
for (Block block : blocks) {
|
||||||
block.getSudokus().add(sudoku);
|
block.getSudokus().add(sudoku);
|
||||||
}
|
}
|
||||||
return new MultiDoku(Arrays.asList(sudoku));
|
return new MultiDoku(List.of(sudoku));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<IConstraint> fromConstraints(List<Constraint> constraints) {
|
public static List<IConstraint> fromConstraints(List<Constraint> constraints) {
|
||||||
|
|||||||
Reference in New Issue
Block a user