diff --git a/app/src/main/java/gui/RenderableMultidoku.java b/app/src/main/java/gui/RenderableMultidoku.java index 6e14235..9c7a711 100644 --- a/app/src/main/java/gui/RenderableMultidoku.java +++ b/app/src/main/java/gui/RenderableMultidoku.java @@ -47,8 +47,6 @@ public class RenderableMultidoku { return cells.get(index); } - - private static record PositionConstraint(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) { } diff --git a/app/src/main/java/sudoku/Main.java b/app/src/main/java/sudoku/Main.java index 3f9ecbf..e4be138 100644 --- a/app/src/main/java/sudoku/Main.java +++ b/app/src/main/java/sudoku/Main.java @@ -3,15 +3,40 @@ */ package sudoku; +import gui.RenderableMultidoku; +import gui.Symbols; import sudoku.io.ConsoleInterface; +import sudoku.io.SudokuPrinter; +import sudoku.solver.RandomSolver; +import sudoku.solver.Solver; +import sudoku.structure.MultiDoku; +import sudoku.structure.SudokuFactory; + +import java.util.Random; public class Main { public String getGreeting() { return "Hello World!"; } + public static void voidTest(){ + MultiDoku md = SudokuFactory.createBasicXShapedMultidoku(3, SudokuFactory.DEFAULT_CONSTRAINTS); + SudokuPrinter.printMultiDoku(RenderableMultidoku.fromMultidoku(md), Symbols.Numbers, 3, 3); + } + + public static void filledTest(){ + MultiDoku md = SudokuFactory.createBasicXShapedMultidoku(3, SudokuFactory.DEFAULT_CONSTRAINTS); + new RandomSolver().solve(md); + SudokuPrinter.printMultiDoku(RenderableMultidoku.fromMultidoku(md), Symbols.Numbers, 3, 3); + } + public static void main(String[] args) { ConsoleInterface console = new ConsoleInterface(); - console.start(); + /* + voidTest(); + filledTest(); + filledTest(); + */ + console.welcome(); } } diff --git a/app/src/main/java/sudoku/io/ConsoleInterface.java b/app/src/main/java/sudoku/io/ConsoleInterface.java index 82c62b5..7439932 100644 --- a/app/src/main/java/sudoku/io/ConsoleInterface.java +++ b/app/src/main/java/sudoku/io/ConsoleInterface.java @@ -1,21 +1,27 @@ package sudoku.io; +import gui.RenderableMultidoku; +import gui.Symbols; +import sudoku.constraint.*; +import sudoku.solver.RandomSolver; +import sudoku.structure.Difficulty; +import sudoku.structure.MultiDoku; +import sudoku.structure.SudokuFactory; + import java.util.ArrayList; import java.util.List; import java.util.Scanner; -import sudoku.constraint.Constraint; -import sudoku.solver.RandomSolver; -import sudoku.structure.Difficulty; -import sudoku.structure.MultiDoku; -import sudoku.structure.Sudoku; -import sudoku.structure.SudokuFactory; - public class ConsoleInterface { public Scanner reader = new Scanner(System.in); + public void welcome(){ + System.out.println("Welcome to our Sudoku Solver!"); + System.out.println("This is the project of Melvyn Bauvent, Lilas Grenier and Simon Priblyski."); + start(); + } + public void start(){ - welcome(); System.out.println("First of all, you need to tell me the size of the sudoku you want to generate."); int width = getBlockWidth(); int height = getBlockHeight(); @@ -27,26 +33,21 @@ public class ConsoleInterface { pickSymbols(listSymbols, numberOfSymbols); } else { - // TODO - System.out.println("Simon doit finir sa partie."); - assert false; + listSymbols = Symbols.Numbers.getSymbols(); } List listConstraints = getListConstraints(); - - System.out.println("Now that we have the size of our sudoku, would you rather have a single grid ('one', default), " + "or a a multidoku composed of 5 subgrids ('multi') ?"); - List subGrids = new ArrayList<>(); MultiDoku doku; if (reader.next().equalsIgnoreCase("multi")) { - doku = SudokuFactory.createBasicEmptyRectangleDoku(width, height, listConstraints); - } - else { doku = SudokuFactory.createBasicXShapedMultidoku(width, height, listConstraints); } + else { + doku = SudokuFactory.createBasicEmptyRectangleDoku(width, height, listConstraints); + } + RenderableMultidoku rm = RenderableMultidoku.fromMultidoku(doku); System.out.println("Your sudoku will look like this:"); - // TODO printMultiDoku method not yet implemented - SudokuPrinter.printMultiDoku(doku, width, height); + SudokuPrinter.printMultiDoku(rm, listSymbols, width, height); System.out.println("We now will fill this sudoku."); System.out.println("What level of difficulty would you like? ('very easy', 'easy', 'medium' (default), 'hard', 'full' (sudoku fully completed))"); String difficulty = reader.next().toLowerCase(); @@ -57,12 +58,7 @@ public class ConsoleInterface { generatePartialDoku(doku, difficulty); } System.out.println("Here's your sudoku !"); - SudokuPrinter.printMultiDoku(doku, width, height); - } - - public void welcome(){ - System.out.println("Welcome to our Sudoku Solver!"); - System.out.println("This is the project of Melvyn Bauvent, Lilas Grenier and Simon Priblyski."); + SudokuPrinter.printMultiDoku(rm, listSymbols, width, height); } public int getBlockWidth() { diff --git a/app/src/main/java/sudoku/io/SudokuPrinter.java b/app/src/main/java/sudoku/io/SudokuPrinter.java index 6cec63f..1d1c0d8 100644 --- a/app/src/main/java/sudoku/io/SudokuPrinter.java +++ b/app/src/main/java/sudoku/io/SudokuPrinter.java @@ -1,28 +1,89 @@ package sudoku.io; +import gui.RenderableMultidoku; +import gui.Symbols; +import sudoku.structure.Cell; import sudoku.structure.MultiDoku; import sudoku.structure.Sudoku; -public class SudokuPrinter { +import java.util.List; - public static void printRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight) { - for (int y = 0; y < s.getSize(); y++) { - if (y % blockHeight == 0 && y > 0) { - System.out.println(); - } - StringBuilder line = new StringBuilder("[ "); - for (int x = 0; x < s.getSize(); x++) { - line.append((s.getCell(x, y).getSymbolIndex() + 1)).append(" "); - if (x % blockWidth == blockWidth - 1 && x != blockWidth * blockHeight - 1) { - line.append("| "); - } - } - line.append("]"); - System.out.println(line); - } +public class SudokuPrinter { + public static final String ANSI_RESET = "\u001B[0m"; + public static final String ANSI_RED = "\u001B[31m"; + public static final String ANSI_GREEN = "\u001B[32m"; + public static final String ANSI_YELLOW = "\u001B[33m"; + public static final String ANSI_BLUE = "\u001B[34m"; + public static final String ANSI_PURPLE = "\u001B[35m"; + public static final String ANSI_CYAN = "\u001B[36m"; + + public static void printRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight, Symbols symbols) { + printRectangleSudoku(s, blockWidth, blockHeight, symbols.getSymbols()); } - public static String toStringRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight) { + public static void printRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight, List listSymbols){ + for (int y = 0; y < s.getSize(); y++) { + if (y % blockHeight == 0 && y > 0) { + System.out.println(); + } + StringBuilder line = new StringBuilder("[ "); + for (int x = 0; x < s.getSize(); x++) { + Cell c = s.getCell(x, y); + if (c.getSymbolIndex() == Cell.NOSYMBOL) { + line.append(" "); + } + else { + line.append(listSymbols.get(c.getSymbolIndex())).append(" "); + } + if (x % blockWidth == blockWidth - 1 && x != blockWidth * blockHeight - 1) { + line.append("| "); + } + } + line.append("]"); + System.out.println(line); + } +} + + public static void printMultiDoku(final RenderableMultidoku rm, Symbols symbols, int blockWidth, int blockHeight) { + printMultiDoku(rm, symbols.getSymbols(), blockWidth, blockHeight); + } + + public static void printMultiDoku(final RenderableMultidoku rm, List listSymbols, int blockWidth, int blockHeight) { + StringBuilder line = new StringBuilder("\n"); + int nBlockInWidth = rm.getWidth() / blockWidth; + for (int y = 0; y < rm.getHeight(); y++) { + if (y % blockHeight == 0) { + line.append("__".repeat(Math.max(0, rm.getWidth()+nBlockInWidth))).append("_\n"); + } + line.append("[ "); + for (int x = 0; x < rm.getWidth(); x++) { + if (x % blockWidth == 0 && x > 0) { + line.append("| "); + } + Cell cell = rm.getCell(x, y); + if (cell != null) { + if (cell.getSymbolIndex() == Cell.NOSYMBOL) { + line.append("- "); + } + else { + line.append(listSymbols.get(cell.getSymbolIndex())).append(" "); + } + } + else { + line.append(" "); + } + } + line.append("]\n"); + } + line.append("__".repeat(Math.max(0, rm.getWidth()+nBlockInWidth))).append("_\n"); + System.out.println(line); + } + + public static String toStringRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight, Symbols symbols){ + return toStringRectangleSudoku(s, blockWidth, blockHeight, symbols.getSymbols()); + } + + public static String toStringRectangleSudoku(final Sudoku s, int blockWidth, int blockHeight, List listSymbols) { StringBuilder result = new StringBuilder(); for (int y = 0; y < s.getSize(); y++) { // Ajouter une ligne vide entre les blocs horizontaux @@ -32,7 +93,13 @@ public class SudokuPrinter { StringBuilder line = new StringBuilder("[ "); for (int x = 0; x < s.getSize(); x++) { // Ajouter la valeur de la cellule - line.append((s.getCell(x, y).getSymbolIndex() + 1)).append(" "); + Cell cell = s.getCell(x, y); + if (cell.getSymbolIndex() == Cell.NOSYMBOL) { + line.append(" "); + } + else { + line.append(listSymbols.get(cell.getSymbolIndex())).append(" "); + } // Ajouter un séparateur vertical entre les blocs if (x % blockWidth == blockWidth - 1 && x != s.getSize() - 1) { @@ -45,7 +112,12 @@ public class SudokuPrinter { return result.toString(); } - public static void printMultiDoku(final MultiDoku doku, int blockWidth, int blockHeight){ - // TODO + public static void printMultiDoku(final MultiDoku doku, int blockWidth, int blockHeight, Symbols symbols){ + if (doku.getNbSubGrids()==1) { + printRectangleSudoku(doku.getSubGrid(0), blockWidth, blockHeight, symbols); + } + else { + printMultiDoku(RenderableMultidoku.fromMultidoku(doku), symbols, blockWidth, blockHeight); + } } } diff --git a/app/src/main/java/sudoku/solver/HumanSolver.java b/app/src/main/java/sudoku/solver/HumanSolver.java index 589d932..e649378 100644 --- a/app/src/main/java/sudoku/solver/HumanSolver.java +++ b/app/src/main/java/sudoku/solver/HumanSolver.java @@ -4,6 +4,7 @@ import java.util.List; import java.util.concurrent.CancellationException; import java.util.logging.Level; +import gui.Symbols; import sudoku.io.SudokuPrinter; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; @@ -26,7 +27,8 @@ public class HumanSolver implements Solver { logger.log(Level.FINE, '\n' + SudokuPrinter.toStringRectangleSudoku(sudoku, sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(), - sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth())); + sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(), + Symbols.Numbers)); if (doku.isSolved()) { return true; diff --git a/app/src/main/java/sudoku/solver/MixedSolver.java b/app/src/main/java/sudoku/solver/MixedSolver.java index 60ffeaf..7ed5829 100644 --- a/app/src/main/java/sudoku/solver/MixedSolver.java +++ b/app/src/main/java/sudoku/solver/MixedSolver.java @@ -5,6 +5,7 @@ import java.util.Random; import java.util.concurrent.CancellationException; import java.util.logging.Level; +import gui.Symbols; import sudoku.io.SudokuPrinter; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; @@ -17,8 +18,6 @@ public class MixedSolver implements Solver{ * backtracking. * * @param doku MultiDoku, MultiDoku à résoudre. - * @param rand Random, pour tester aléatoirement les symboles, lors du - * backtracking. * @return boolean, valant true si le MultiDoku est résolu, false sinon. */ @Override @@ -34,7 +33,8 @@ public class MixedSolver implements Solver{ '\n' + SudokuPrinter.toStringRectangleSudoku( sudoku, sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(), - sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth())); + sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(), + Symbols.Numbers)); if (doku.isSolved()) { return true; diff --git a/app/src/main/java/sudoku/solver/RandomSolver.java b/app/src/main/java/sudoku/solver/RandomSolver.java index 275d928..2763219 100644 --- a/app/src/main/java/sudoku/solver/RandomSolver.java +++ b/app/src/main/java/sudoku/solver/RandomSolver.java @@ -5,6 +5,7 @@ import java.util.Random; import java.util.concurrent.CancellationException; import java.util.logging.Level; +import gui.Symbols; import sudoku.io.SudokuPrinter; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; @@ -32,7 +33,8 @@ public class RandomSolver implements Solver { logger.log(Level.FINE, '\n' + SudokuPrinter.toStringRectangleSudoku(sudoku, sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getBlockWidth(), - sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth())); + sudoku.getBlockWidth() == 0 ? sudoku.getSize() : sudoku.getSize() / sudoku.getBlockWidth(), + Symbols.Numbers)); if (doku.isSolved()) { return true; diff --git a/app/src/test/java/sudoku/solver/SolverTest.java b/app/src/test/java/sudoku/solver/SolverTest.java index 6b64c55..83718ec 100644 --- a/app/src/test/java/sudoku/solver/SolverTest.java +++ b/app/src/test/java/sudoku/solver/SolverTest.java @@ -1,5 +1,6 @@ package sudoku.solver; +import gui.Symbols; import org.junit.jupiter.api.Test; import sudoku.io.SudokuPrinter; import sudoku.io.SudokuSerializer; @@ -38,7 +39,8 @@ class SolverTest { assert (sudokuToTest.setImmutableCellsSymbol(immutableCells)); - SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); + //SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); + SudokuPrinter.printMultiDoku(dokuToTest, 3, 3, Symbols.Numbers); List correctCells = List.of(7, 6, 0, 3, 4, 2, 8, 5, 1, 2, 3, 8, 1, 5, 6, 7, 0, 4, @@ -53,14 +55,15 @@ class SolverTest { sudokuResult.setCellsSymbol(correctCells); System.out.println("\n****************************Doku Control\n"); - SudokuPrinter.printRectangleSudoku(sudokuResult, 3, 3); + SudokuPrinter.printRectangleSudoku(sudokuResult, 3, 3, Symbols.Russian); assert (dokuResult.isSolved()); new RandomSolver().solve(dokuToTest); System.out.println("\n****************************\nDoku solved"); - SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); + //SudokuPrinter.printRectangleSudoku(dokuToTest.getSubGrid(0), 3, 3); + SudokuPrinter.printMultiDoku(dokuToTest, 3, 3, Symbols.Emojis); assert (dokuToTest.isSolved()); @@ -97,6 +100,7 @@ class SolverTest { new RandomSolver().solve(dokuToTest3); - SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3); + //SudokuPrinter.printRectangleSudoku(dokuToTest3.getSubGrid(0), 3, 3); + SudokuPrinter.printMultiDoku(dokuToTest3, 3, 3, Symbols.Letters); } } \ No newline at end of file