This commit is contained in:
5
app/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
app/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -3,6 +3,7 @@ package gui.menu;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
import gui.ColorGenerator;
|
||||
@@ -12,7 +13,7 @@ import imgui.ImVec2;
|
||||
import imgui.ImVec4;
|
||||
import imgui.flag.ImGuiCol;
|
||||
import imgui.flag.ImGuiStyleVar;
|
||||
import sudoku.solver.StupidSolver;
|
||||
import sudoku.solver.Solver;
|
||||
import sudoku.structure.Block;
|
||||
import sudoku.structure.Cell;
|
||||
import sudoku.structure.MultiDoku;
|
||||
@@ -98,19 +99,18 @@ public class SudokuView extends BaseView {
|
||||
ImGui.beginDisabled();
|
||||
|
||||
if (ImGui.button("Résoudre")) {
|
||||
resolveThread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
doku.getSubGrid(0).clear();
|
||||
StupidSolver.solve(doku);
|
||||
Thread.sleep(200);
|
||||
} catch (CancellationException | InterruptedException e) {
|
||||
System.out.println("The user is bored !");
|
||||
}
|
||||
stopResolve();
|
||||
}
|
||||
});
|
||||
|
||||
resolveThread = new Thread(() -> {
|
||||
try {
|
||||
Random rand = new Random();
|
||||
doku.getSubGrid(0).clear();
|
||||
Solver.solveRandom(doku, rand);
|
||||
Thread.sleep(200);
|
||||
} catch (CancellationException | InterruptedException e) {
|
||||
System.out.println("The user is bored !");
|
||||
}
|
||||
stopResolve();
|
||||
});
|
||||
}
|
||||
boolean wantsToStop = false;
|
||||
if (resolveThread != null && resolveThread.isAlive()){
|
||||
|
||||
@@ -4,16 +4,54 @@ import sudoku.structure.MultiDoku;
|
||||
import sudoku.structure.Cell;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.CancellationException;
|
||||
|
||||
public class Solver {
|
||||
|
||||
/**
|
||||
* Résout le multidoku passé en paramètre si c'est possible.
|
||||
* En testant toutes les possibilités avec un algorithme de backtracking.
|
||||
*
|
||||
* @param doku Multidoku, à résoudre
|
||||
* @param rand random pour tester aléatoirement les symboles
|
||||
* @return boolean, true s'il est résolut ou false s'il ne l'est pas.
|
||||
*/
|
||||
public static boolean solveRandom(MultiDoku doku, Random rand) {
|
||||
if (Thread.interrupted())
|
||||
throw new CancellationException("User wants to stop the solver");
|
||||
|
||||
if (doku.isValid()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Cell cellToFill = doku.getFirstEmptyCell();
|
||||
if (cellToFill == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<Integer> possibleSymbols = doku.getPossibleSymbolsOfCell(cellToFill);
|
||||
|
||||
while (!possibleSymbols.isEmpty()){
|
||||
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
|
||||
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
|
||||
|
||||
cellToFill.setSymbolIndex(nextSymbol);
|
||||
if (Solver.solveRandom(doku, rand)) {
|
||||
return true;
|
||||
} else {
|
||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
||||
possibleSymbols.remove(nextPossibleSymbolIndex);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean solve(MultiDoku doku) {
|
||||
if (Thread.interrupted())
|
||||
throw new CancellationException("User wants to stop the solver");
|
||||
|
||||
if (doku.isValid()) {
|
||||
return true;
|
||||
}
|
||||
@@ -28,46 +66,16 @@ public class Solver {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int symbol : possibleSymbols) {
|
||||
for (int symbol : possibleSymbols){
|
||||
|
||||
cellToFill.setSymbolIndex(symbol);
|
||||
if (Solver.solve(doku)) {
|
||||
return true;
|
||||
} else {
|
||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
Ancien algo abandonné pour le moment
|
||||
|
||||
private void rollBack() {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
|
||||
public MultiDoku solve(MultiDoku doku, List<IConstraint> constraints) throws Exception {
|
||||
List<MutableCell> allMutableCells = doku.getMutableCells();
|
||||
List<MutableCell> remainingCellsToCheck = new ArrayList<>(allMutableCells);
|
||||
Random rand = new Random();
|
||||
while (!remainingCellsToCheck.isEmpty()) {
|
||||
int indexCurrentCell = rand.nextInt(remainingCellsToCheck.size());
|
||||
MutableCell currentCell = remainingCellsToCheck.get(indexCurrentCell);
|
||||
|
||||
int symbol = currentCell.getPossibleSymbols().get(0);
|
||||
currentCell.setSymbolIndex(symbol);
|
||||
// stack.push(new MutableCell(currentCell));
|
||||
try {
|
||||
doku.updateSymbolsPossibilities();
|
||||
} catch (Exception e) {
|
||||
this.rollBack();
|
||||
System.out.println(this.stack);
|
||||
}
|
||||
remainingCellsToCheck.remove(indexCurrentCell);
|
||||
}
|
||||
return doku;
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import java.util.concurrent.CancellationException;
|
||||
import sudoku.structure.MultiDoku;
|
||||
import sudoku.structure.Sudoku;
|
||||
|
||||
/**
|
||||
* Class de test non utilisé
|
||||
*/
|
||||
public class StupidSolver {
|
||||
|
||||
private static boolean solve(Sudoku sudoku, int index) {
|
||||
|
||||
@@ -229,8 +229,9 @@ public class Sudoku {
|
||||
} catch (Exception e) {
|
||||
return result;
|
||||
}
|
||||
for (IConstraint constraint : this.constraints) {
|
||||
if (result.isEmpty()) {
|
||||
for (int i = 0; i < this.constraints.size(); i++) {
|
||||
IConstraint constraint = this.constraints.get(i);
|
||||
if (i == 0) {
|
||||
result.addAll(constraint.getPossibleSymbols(this, cellCoordinates.getX(), cellCoordinates.getY()));
|
||||
} else {
|
||||
result.retainAll(constraint.getPossibleSymbols(this, cellCoordinates.getX(), cellCoordinates.getY()));
|
||||
|
||||
@@ -56,7 +56,7 @@ class SolverTest {
|
||||
|
||||
assert(dokuResult.isValid());
|
||||
|
||||
Solver.solve(dokuToTest);
|
||||
Solver.solveRandom(dokuToTest, );
|
||||
|
||||
|
||||
System.out.println("\n****************************\nDoku solved");
|
||||
@@ -81,8 +81,14 @@ class SolverTest {
|
||||
5, ns, ns, ns, 3, 1, 0, ns, ns);
|
||||
sudokuToTest2.setImmutableCellsSymbol(immutableCells2);
|
||||
|
||||
boolean isSolved = Solver.solve(dokuToTest2);
|
||||
boolean isSolved = Solver.solveRandom(dokuToTest2, );
|
||||
|
||||
assert(!isSolved);
|
||||
|
||||
MultiDoku dokuToTest3 = SudokuFactory.createBasicEmptySquareSudoku(3);
|
||||
|
||||
Solver.solveRandom(dokuToTest3, );
|
||||
|
||||
SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user