Compare commits
3 Commits
d5009371f2
...
4a8644181a
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a8644181a | |||
| efa357a1ab | |||
| 618e436270 |
@@ -11,8 +11,6 @@ plugins {
|
|||||||
id 'application'
|
id 'application'
|
||||||
}
|
}
|
||||||
|
|
||||||
project.ext.os = System.properties['os.name'].toLowerCase().split(" ")[0]
|
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Use Maven Central for resolving dependencies.
|
// Use Maven Central for resolving dependencies.
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -22,6 +20,8 @@ dependencies {
|
|||||||
// Use JUnit Jupiter for testing.
|
// Use JUnit Jupiter for testing.
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
|
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
|
||||||
|
|
||||||
|
implementation 'com.google.guava:guava:31.1-jre'
|
||||||
|
|
||||||
implementation 'org.json:json:20250107'
|
implementation 'org.json:json:20250107'
|
||||||
|
|
||||||
implementation "io.github.spair:imgui-java-app:1.88.0"
|
implementation "io.github.spair:imgui-java-app:1.88.0"
|
||||||
@@ -50,6 +50,10 @@ jar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
|
|
||||||
run {
|
run {
|
||||||
enableAssertions = true
|
enableAssertions = true
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package sudoku.solver;
|
package sudoku.solver;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
|
||||||
import sudoku.structure.Cell;
|
import sudoku.structure.Cell;
|
||||||
@@ -9,6 +8,19 @@ import sudoku.structure.MultiDoku;
|
|||||||
|
|
||||||
public class MixedSolver implements Solver {
|
public class MixedSolver implements Solver {
|
||||||
|
|
||||||
|
private Cell findCellToBacktrack(MultiDoku doku, int maxPossibilities) {
|
||||||
|
for (Cell cell : doku.getCells()) {
|
||||||
|
if (!cell.isMutable() || !cell.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
List<Integer> possibleSymbols = cell.getPossibleSymbols();
|
||||||
|
if (possibleSymbols.size() == maxPossibilities) {
|
||||||
|
return cell;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Résout le MultiDoku passé en paramètre, avec règles de déduction et
|
* Résout le MultiDoku passé en paramètre, avec règles de déduction et
|
||||||
* backtracking.
|
* backtracking.
|
||||||
@@ -18,47 +30,45 @@ public class MixedSolver implements Solver {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean solve(MultiDoku doku, List<SolverStep> steps) {
|
public boolean solve(MultiDoku doku, List<SolverStep> steps) {
|
||||||
Random rand = new Random();
|
|
||||||
|
|
||||||
if (Thread.interrupted()) {
|
if (Thread.interrupted()) {
|
||||||
throw new CancellationException("User wants to stop the solver");
|
throw new CancellationException("User wants to stop the solver");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doku.isSolved()) {
|
while (!doku.isSolved()) {
|
||||||
return true;
|
boolean filledCell = false;
|
||||||
}
|
for (Cell cell : doku.getCells()) {
|
||||||
|
if (!cell.isMutable() || !cell.isEmpty())
|
||||||
Cell cellToFill = doku.getFirstEmptyCell();
|
continue;
|
||||||
if (cellToFill == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Integer> possibleSymbols = cellToFill.getPossibleSymbols();
|
|
||||||
|
|
||||||
|
List<Integer> possibleSymbols = cell.getPossibleSymbols();
|
||||||
if (possibleSymbols.size() == 1) {
|
if (possibleSymbols.size() == 1) {
|
||||||
cellToFill.setSymbolIndex(possibleSymbols.getFirst());
|
cell.setSymbolIndex(possibleSymbols.getFirst());
|
||||||
addStep(cellToFill, steps);
|
addStep(cell, steps);
|
||||||
if (this.solve(doku, steps)) {
|
filledCell = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// on ne peut plus remplir de cases, on tente de backtrack
|
||||||
|
if (!filledCell) {
|
||||||
|
int maxPossibilities = 2;
|
||||||
|
Cell backtrackCell = null;
|
||||||
|
while (backtrackCell == null) {
|
||||||
|
backtrackCell = findCellToBacktrack(doku, maxPossibilities);
|
||||||
|
maxPossibilities++;
|
||||||
|
}
|
||||||
|
// on fait du backtracking
|
||||||
|
List<Integer> possibilities = backtrackCell.getPossibleSymbols();
|
||||||
|
for (int symbol : possibilities) {
|
||||||
|
doku.getStateManager().pushState();
|
||||||
|
backtrackCell.setSymbolIndex(symbol);
|
||||||
|
if (solve(doku, steps))
|
||||||
|
return true;
|
||||||
|
doku.getStateManager().popState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
while (!possibleSymbols.isEmpty()) {
|
|
||||||
int nextPossibleSymbolIndex = rand.nextInt(possibleSymbols.size());
|
|
||||||
int nextSymbol = possibleSymbols.get(nextPossibleSymbolIndex);
|
|
||||||
|
|
||||||
cellToFill.setSymbolIndex(nextSymbol);
|
|
||||||
addStep(cellToFill, steps);
|
|
||||||
if (this.solve(doku, steps)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
cellToFill.setSymbolIndex(Cell.NOSYMBOL);
|
|
||||||
addStep(cellToFill, steps);
|
|
||||||
possibleSymbols.remove(nextPossibleSymbolIndex);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package sudoku.solver;
|
package sudoku.solver;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
|
||||||
import sudoku.structure.MultiDoku;
|
import sudoku.structure.MultiDoku;
|
||||||
@@ -8,9 +9,9 @@ import sudoku.structure.Sudoku;
|
|||||||
/**
|
/**
|
||||||
* Class de test non utilisé
|
* Class de test non utilisé
|
||||||
*/
|
*/
|
||||||
public class StupidSolver {
|
public class StupidSolver implements Solver{
|
||||||
|
|
||||||
private static boolean solve(Sudoku sudoku, int index) {
|
private boolean solve(Sudoku sudoku, int index, List<SolverStep> steps) {
|
||||||
// mécanisme d'abandon
|
// mécanisme d'abandon
|
||||||
if (Thread.interrupted())
|
if (Thread.interrupted())
|
||||||
throw new CancellationException("User wants to stop the solver");
|
throw new CancellationException("User wants to stop the solver");
|
||||||
@@ -21,27 +22,30 @@ public class StupidSolver {
|
|||||||
|
|
||||||
// si la case n'est pas modifiable, on passe à la suivante
|
// si la case n'est pas modifiable, on passe à la suivante
|
||||||
if (!sudoku.getCell(index).isMutable())
|
if (!sudoku.getCell(index).isMutable())
|
||||||
return solve(sudoku, index + 1);
|
return solve(sudoku, index + 1, steps);
|
||||||
|
|
||||||
for (int symbol = 0; symbol < sudoku.getSize(); symbol++) {
|
for (int symbol = 0; symbol < sudoku.getSize(); symbol++) {
|
||||||
if (sudoku.getCell(index).trySetValue(symbol)) {
|
if (sudoku.getCell(index).trySetValue(symbol)) {
|
||||||
|
addStep(sudoku.getCell(index), steps);
|
||||||
// on tente de placer sur la case suivante
|
// on tente de placer sur la case suivante
|
||||||
if (solve(sudoku, index + 1)) {
|
if (solve(sudoku, index + 1, steps)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// on a tout essayé et rien n'a fonctionné
|
// on a tout essayé et rien n'a fonctionné
|
||||||
sudoku.getCell(index).empty();
|
sudoku.getCell(index).empty();
|
||||||
|
addStep(sudoku.getCell(index), steps);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean solve(MultiDoku doku) {
|
@Override
|
||||||
|
public boolean solve(MultiDoku doku, List<SolverStep> steps) {
|
||||||
if (doku.isSolved())
|
if (doku.isSolved())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (Sudoku sudoku : doku.getSubGrids()) {
|
for (Sudoku sudoku : doku.getSubGrids()) {
|
||||||
if (!solve(sudoku, 0))
|
if (!solve(sudoku, 0, steps))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user