Files
Sudoku/app/src/main/java/sudoku/solver/HintHelper.java
Melvyn 71666a3883
All checks were successful
Linux arm64 / Build (push) Successful in 44s
refactor : mini fixs
2025-02-02 22:51:33 +01:00

60 lines
1.8 KiB
Java

package sudoku.solver;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import sudoku.structure.Cell;
import sudoku.structure.MultiDoku;
public class HintHelper {
public record Hint(Cell cell, int newValue) {}
/**
* Si possible, donne un indice sur la résolution du doku passé en paramètre,
* selon la méthode de résolution rensaignée.
* @param doku MultiDoku, multidoku pour lequel on veut un indice
* @param solver Solver, méthode de résolution souhaitée
* @return Hint, indice sur une case à remplir, valant null si le doku n'a pas de solution.
*/
public static Hint getHint(MultiDoku doku, Solver solver) {
doku.getStateManager().pushState();
doku.clearMutableCells();
if (!solver.solve(doku))
return null;
var stateSolved = doku.getStateManager().popAndGetState();
// find differences
Map<Cell, Integer> newValues = new HashMap<>();
for (var entry : stateSolved.entrySet()) {
Cell cell = entry.getKey();
// we only want the cells that can be filled
if (!cell.isMutable())
continue;
int oldValue = cell.getSymbolIndex();
int newValue = stateSolved.get(cell);
if (oldValue == newValue)
continue;
// we have to clear the cell
if (newValue == Cell.NOSYMBOL)
return new Hint(cell, newValue);
// we have to change the cell value
if (oldValue != Cell.NOSYMBOL)
return new Hint(cell, newValue);
// there is a valid move
newValues.put(cell, newValue);
}
// this is too complex just for fetching a random entry, but whatever ...
Random r = new Random();
List<Cell> cells = new ArrayList<>(newValues.keySet());
Cell randomCell = cells.get(r.nextInt(cells.size()));
int randomCellValue = newValues.get(randomCell);
return new Hint(randomCell, randomCellValue);
}
}