This commit is contained in:
48
app/src/main/java/sudoku/solver/StupidSolver.java
Normal file
48
app/src/main/java/sudoku/solver/StupidSolver.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package sudoku.solver;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import sudoku.structure.MultiDoku;
|
||||
import sudoku.structure.Sudoku;
|
||||
|
||||
public class StupidSolver {
|
||||
|
||||
private static boolean solve(Sudoku sudoku, int index) {
|
||||
// mécanisme d'abandon
|
||||
if (Thread.interrupted())
|
||||
throw new CancellationException("User wants to stop the solver");
|
||||
|
||||
// si tout est bon avant, on a gagné
|
||||
if (!sudoku.isValidCoords(index))
|
||||
return true;
|
||||
|
||||
// si la case n'est pas modifiable, on passe à la suivante
|
||||
if (!sudoku.getCell(index).isMutable())
|
||||
return solve(sudoku, index + 1);
|
||||
|
||||
var coords = sudoku.toCoords(index);
|
||||
for (int symbol = 0; symbol < sudoku.getSize(); symbol++) {
|
||||
if (sudoku.tryPlaceCellSymbol(coords[0], coords[1], symbol)) {
|
||||
// on tente de placer sur la case suivante
|
||||
if (solve(sudoku, index + 1)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// on a tout essayé et rien n'a fonctionné
|
||||
sudoku.clearCell(coords[0], coords[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean solve(MultiDoku doku) {
|
||||
if (doku.isValid())
|
||||
return true;
|
||||
|
||||
for (Sudoku sudoku : doku.getSubGrids()) {
|
||||
if (!solve(sudoku, 0))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,14 +22,55 @@ public class Sudoku {
|
||||
this.constraints = constraints;
|
||||
}
|
||||
|
||||
public int[] toCoords(int index) {
|
||||
return new int[]{index % getSize(), index / getSize()};
|
||||
}
|
||||
|
||||
public int toIndex(int x, int y) {
|
||||
return y * getSize() + x;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return wether the coords are in the sudoku
|
||||
*/
|
||||
public boolean isValidCoords(int x, int y) {
|
||||
int index = y * getSize() + x;
|
||||
int index = toIndex(x, y);
|
||||
return isValidCoords(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return wether the coords are in the sudoku
|
||||
*/
|
||||
public boolean isValidCoords(int index) {
|
||||
return index < getSize() * getSize();
|
||||
}
|
||||
|
||||
public boolean tryPlaceCellSymbol(int x, int y, int value) {
|
||||
assert (isValidCoords(x, y));
|
||||
for (IConstraint constraint : this.constraints) {
|
||||
if (!constraint.canBePlaced(this, x, y, value)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Cell cell = getCell(x, y);
|
||||
cell.setSymbolIndex(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void clearCell(int x, int y) {
|
||||
assert (isValidCoords(x, y));
|
||||
Cell cell = getCell(x, y);
|
||||
cell.setSymbolIndex(Cell.NOSYMBOL);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < getSize() * getSize(); i++) {
|
||||
Cell cell = getCell(i);
|
||||
if (cell.isMutable())
|
||||
cell.setSymbolIndex(Cell.NOSYMBOL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to place a cell at the given coordinate
|
||||
*
|
||||
@@ -53,7 +94,7 @@ public class Sudoku {
|
||||
}
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
int x = i % this.blocks.size();
|
||||
int y = (i-x) / this.blocks.size();
|
||||
int y = (i - x) / this.blocks.size();
|
||||
int value = values.get(i);
|
||||
this.setCellSymbol(x, y, value);
|
||||
}
|
||||
@@ -65,8 +106,8 @@ public class Sudoku {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
int x = i%this.blocks.size();
|
||||
int y = (i-x)/this.blocks.size();
|
||||
int x = i % this.blocks.size();
|
||||
int y = (i - x) / this.blocks.size();
|
||||
int value = values.get(i);
|
||||
if (value != Cell.NOSYMBOL) {
|
||||
Cell cellPlaced = this.setCellSymbol(x, y, value);
|
||||
@@ -79,12 +120,11 @@ public class Sudoku {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public Cell getCell(int x, int y) {
|
||||
int index = y * getSize() + x;
|
||||
assert (isValidCoords(x, y));
|
||||
try {
|
||||
return this.cells.get(index);
|
||||
return this.cells.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
@@ -212,7 +252,8 @@ public class Sudoku {
|
||||
coords = this.getCoordinateCell(cell);
|
||||
|
||||
cell.setSymbolIndex(Cell.NOSYMBOL);
|
||||
List<Integer> possibleSymbols = constraint.getPossibleSymbols(this, coords.getX(), coords.getY());
|
||||
List<Integer> possibleSymbols = constraint.getPossibleSymbols(this, coords.getX(),
|
||||
coords.getY());
|
||||
cell.setSymbolIndex(symbolPlaced);
|
||||
if (possibleSymbols.size() != 1 || possibleSymbols.get(0) != symbolPlaced) {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user