This commit is contained in:
@@ -25,7 +25,7 @@ public class StateMachine {
|
|||||||
|
|
||||||
private void checkEscape() {
|
private void checkEscape() {
|
||||||
if (ImGui.isKeyPressed(ImGuiKey.Escape) && menus.size() > 1) {
|
if (ImGui.isKeyPressed(ImGuiKey.Escape) && menus.size() > 1) {
|
||||||
popState();
|
menus.getLast().closeMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package gui.menu;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.CancellationException;
|
||||||
|
|
||||||
import gui.ColorGenerator;
|
import gui.ColorGenerator;
|
||||||
import gui.ColorGenerator.Color;
|
import gui.ColorGenerator.Color;
|
||||||
@@ -11,7 +12,7 @@ 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 sudoku.solver.Solver;
|
import sudoku.solver.StupidSolver;
|
||||||
import sudoku.structure.Block;
|
import sudoku.structure.Block;
|
||||||
import sudoku.structure.Cell;
|
import sudoku.structure.Cell;
|
||||||
import sudoku.structure.MultiDoku;
|
import sudoku.structure.MultiDoku;
|
||||||
@@ -23,6 +24,7 @@ public class SudokuView extends BaseView {
|
|||||||
private final MultiDoku doku;
|
private final MultiDoku doku;
|
||||||
private int currentIndex = -1;
|
private int currentIndex = -1;
|
||||||
private final Map<Block, Color> colorPalette;
|
private final Map<Block, Color> colorPalette;
|
||||||
|
private volatile Thread resolveThread = null;
|
||||||
|
|
||||||
public SudokuView(StateMachine stateMachine, int width, int height) {
|
public SudokuView(StateMachine stateMachine, int width, int height) {
|
||||||
super(stateMachine);
|
super(stateMachine);
|
||||||
@@ -31,6 +33,13 @@ public class SudokuView extends BaseView {
|
|||||||
initColors();
|
initColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void stopResolve() {
|
||||||
|
if (resolveThread != null && resolveThread.isAlive()) {
|
||||||
|
resolveThread.interrupt();
|
||||||
|
resolveThread = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initColors() {
|
private void initColors() {
|
||||||
List<Color> colors = ColorGenerator.greatPalette(doku.getSubGrid(0).getSize());
|
List<Color> colors = ColorGenerator.greatPalette(doku.getSubGrid(0).getSize());
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@@ -80,10 +89,44 @@ public class SudokuView extends BaseView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
renderPopup();
|
renderPopup();
|
||||||
|
if (resolveThread != null)
|
||||||
|
ImGui.beginDisabled();
|
||||||
|
|
||||||
if (ImGui.button("Résoudre")) {
|
if (ImGui.button("Résoudre")) {
|
||||||
Solver.solve(doku);
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
boolean wantsToStop = false;
|
||||||
|
if (resolveThread != null && resolveThread.isAlive()){
|
||||||
|
ImGui.endDisabled();
|
||||||
|
if (ImGui.button("Annuler")) {
|
||||||
|
// we can't stop the Thread right now
|
||||||
|
wantsToStop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (resolveThread != null && !resolveThread.isAlive()) {
|
||||||
|
resolveThread.start();
|
||||||
|
}
|
||||||
|
if (wantsToStop)
|
||||||
|
stopResolve();
|
||||||
renderReturnButton();
|
renderReturnButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeMenu() {
|
||||||
|
super.closeMenu();
|
||||||
|
stopResolve();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
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;
|
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
|
* @return wether the coords are in the sudoku
|
||||||
*/
|
*/
|
||||||
public boolean isValidCoords(int x, int y) {
|
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();
|
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
|
* Try to place a cell at the given coordinate
|
||||||
*
|
*
|
||||||
@@ -79,7 +120,6 @@ public class Sudoku {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Cell getCell(int x, int y) {
|
public Cell getCell(int x, int y) {
|
||||||
int index = y * getSize() + x;
|
int index = y * getSize() + x;
|
||||||
assert (isValidCoords(x, y));
|
assert (isValidCoords(x, y));
|
||||||
@@ -212,7 +252,8 @@ public class Sudoku {
|
|||||||
coords = this.getCoordinateCell(cell);
|
coords = this.getCoordinateCell(cell);
|
||||||
|
|
||||||
cell.setSymbolIndex(Cell.NOSYMBOL);
|
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);
|
cell.setSymbolIndex(symbolPlaced);
|
||||||
if (possibleSymbols.size() != 1 || possibleSymbols.get(0) != symbolPlaced) {
|
if (possibleSymbols.size() != 1 || possibleSymbols.get(0) != symbolPlaced) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user