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; import gui.ColorGenerator.Color; import imgui.ImGui; import imgui.ImVec2; import imgui.ImVec4; import imgui.flag.ImGuiCol; import imgui.flag.ImGuiStyleVar; import sudoku.solver.Solver; import sudoku.structure.Block; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; import sudoku.structure.Sudoku; import sudoku.structure.SudokuFactory; public class SudokuView extends BaseView { private final MultiDoku doku; private int currentIndex = -1; private final Map colorPalette; private volatile Thread resolveThread = null; public SudokuView(StateMachine stateMachine, int width, int height) { super(stateMachine); this.doku = SudokuFactory.createBasicEmptyRectangleSudoku(width, height); this.colorPalette = new HashMap<>(); initColors(); } private void stopResolve() { if (resolveThread != null && resolveThread.isAlive()) { resolveThread.interrupt(); resolveThread = null; } } private void initColors() { List colors = ColorGenerator.greatPalette(doku.getSubGrid(0).getSize()); int index = 0; for (Block block : doku.getSubGrid(0).getBlocks()) { colorPalette.put(block, colors.get(index)); index++; } } private void renderPopup() { final Sudoku sudoku = doku.getSubGrid(0); if (ImGui.beginPopup("editPopup")) { for (int i = 1; i < sudoku.getSize() + 1; i++) { if (i % (int) (Math.sqrt(sudoku.getSize())) != 1) ImGui.sameLine(); if (ImGui.button(Integer.toString(i), new ImVec2(50, 50))) { sudoku.setCellSymbol(currentIndex % sudoku.getSize(), currentIndex / sudoku.getSize(), i - 1); ImGui.closeCurrentPopup(); } } ImGui.endPopup(); } } @Override public void render() { final Sudoku sudoku = doku.getSubGrid(0); ImGui.pushStyleVar(ImGuiStyleVar.FrameBorderSize, 2.0f); ImGui.pushStyleVar(ImGuiStyleVar.ItemSpacing, new ImVec2(0.0f, 0.0f)); ImGui.pushStyleColor(ImGuiCol.Border, new ImVec4(0.0f, 0.0f, 0.0f, 1.0f)); for (int y = 0; y < sudoku.getSize(); y++) { for (int x = 0; x < sudoku.getSize(); x++) { if (x > 0) ImGui.sameLine(); int index = y * sudoku.getSize() + x; Cell cell = sudoku.getCell(x, y); int symbol = cell.getSymbolIndex(); Color blockColor = colorPalette.get(cell.getBlock()); ImGui.pushStyleVar(ImGuiStyleVar.SelectableTextAlign, new ImVec2(0.5f, 0.5f)); ImGui.pushStyleColor(ImGuiCol.Button, new ImVec4(blockColor.r, blockColor.g, blockColor.b, 1.0f)); String cellText = ""; if (symbol != -1) cellText += Integer.toString(symbol + 1); if (ImGui.button(cellText + "##" + index, new ImVec2(50, 50))) { ImGui.openPopup("editPopup"); currentIndex = index; } ImGui.popStyleVar(); ImGui.popStyleColor(); } } ImGui.popStyleVar(2); ImGui.popStyleColor(); renderPopup(); if (resolveThread != null) ImGui.beginDisabled(); if (ImGui.button("Résoudre")) { 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()){ 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(); } @Override public void closeMenu() { super.closeMenu(); stopResolve(); } }