From 64a2dca1b06ff0b995a8c020bba19acffb783c03 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Tue, 21 Jan 2025 17:13:46 +0100 Subject: [PATCH] =?UTF-8?q?=C3=A7a=20part?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 8 + app/src/main/java/sudoku/Cell.java | 19 +- app/src/main/java/sudoku/Main.java | 5 +- app/src/main/java/sudoku/Sudoku.java | 14 +- app/src/main/java/sudoku/io/SudokuFile.java | 9 + app/src/main/java/sudoku/io/SudokuSave.java | 17 ++ .../main/java/sudoku/io/SudokuSerializer.java | 166 ++++++++++++++++++ app/src/main/java/sudoku/solver/Solver.java | 6 +- .../java/sudoku/SudokuSerializerTest.java | 28 +++ 9 files changed, 256 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/sudoku/io/SudokuFile.java create mode 100644 app/src/main/java/sudoku/io/SudokuSave.java create mode 100644 app/src/main/java/sudoku/io/SudokuSerializer.java create mode 100644 app/src/test/java/sudoku/SudokuSerializerTest.java diff --git a/app/build.gradle b/app/build.gradle index 187d39d..4d27427 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,6 +25,10 @@ dependencies { // uml implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.2' + + implementation 'org.json:json:20250107' + + implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.2' } application { @@ -36,3 +40,7 @@ tasks.named('test') { // Use JUnit Platform for unit tests. useJUnitPlatform() } + +run { + enableAssertions = true +} \ No newline at end of file diff --git a/app/src/main/java/sudoku/Cell.java b/app/src/main/java/sudoku/Cell.java index c7088a4..b17474c 100644 --- a/app/src/main/java/sudoku/Cell.java +++ b/app/src/main/java/sudoku/Cell.java @@ -1,8 +1,11 @@ package sudoku; +import com.fasterxml.jackson.annotation.JsonProperty; + public abstract class Cell { protected static int NOSYMBOLE = -1; + @JsonProperty("symboleIndex") protected int symboleIndex; protected Block block = null; @@ -25,15 +28,15 @@ public abstract class Cell { return this.block; } - // only SudokuFactory should access this - void setBlock(Block block) { + // only SudokuFactory and SudokuSerializer should access this + public void setBlock(Block block) { this.block = block; } - @Override - public boolean equals(Object obj) { - if (obj instanceof Cell otherCell) - return otherCell.getSymboleIndex() == this.getSymboleIndex(); - return false; - } + // @Override + // public boolean equals(Object obj) { + // if (obj instanceof Cell otherCell) + // return otherCell.getSymboleIndex() == this.getSymboleIndex(); + // return false; + // } } diff --git a/app/src/main/java/sudoku/Main.java b/app/src/main/java/sudoku/Main.java index 5199c55..fb8efe2 100644 --- a/app/src/main/java/sudoku/Main.java +++ b/app/src/main/java/sudoku/Main.java @@ -4,6 +4,7 @@ package sudoku; import sudoku.io.SudokuPrinter; +import sudoku.io.SudokuSerializer; public class Main { public String getGreeting() { @@ -12,9 +13,5 @@ public class Main { public static void main(String[] args) { System.out.println(new Main().getGreeting()); - int blockWidth = 3; - int blockHeight = 3; - var sudoku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight); - SudokuPrinter.printRectangleSudoku(sudoku.getSubGrid(0), blockWidth , blockHeight); } } diff --git a/app/src/main/java/sudoku/Sudoku.java b/app/src/main/java/sudoku/Sudoku.java index 3b60963..7f37727 100644 --- a/app/src/main/java/sudoku/Sudoku.java +++ b/app/src/main/java/sudoku/Sudoku.java @@ -2,7 +2,6 @@ package sudoku; import sudoku.constraint.IConstraint; -import javax.swing.*; import java.util.ArrayList; import java.util.List; @@ -49,4 +48,17 @@ public class Sudoku { } return mutableCells; } + + + // only used by the serializer + + public List getBlocks() { + return blocks; + } + + public List getCells() { + return cells; + } + + } diff --git a/app/src/main/java/sudoku/io/SudokuFile.java b/app/src/main/java/sudoku/io/SudokuFile.java new file mode 100644 index 0000000..f862138 --- /dev/null +++ b/app/src/main/java/sudoku/io/SudokuFile.java @@ -0,0 +1,9 @@ +package sudoku.io; + +import sudoku.MultiDoku; + +public class SudokuFile { + + + +} diff --git a/app/src/main/java/sudoku/io/SudokuSave.java b/app/src/main/java/sudoku/io/SudokuSave.java new file mode 100644 index 0000000..9dc8b15 --- /dev/null +++ b/app/src/main/java/sudoku/io/SudokuSave.java @@ -0,0 +1,17 @@ +package sudoku.io; + +import sudoku.MultiDoku; + +public class SudokuSave { + + public static enum AlgoResolution { + Backtracking, + NoBacktring + } + + // private final MultiDoku sudoku; + // private final AlgoResolution resolution; + + + +} diff --git a/app/src/main/java/sudoku/io/SudokuSerializer.java b/app/src/main/java/sudoku/io/SudokuSerializer.java new file mode 100644 index 0000000..ea10eed --- /dev/null +++ b/app/src/main/java/sudoku/io/SudokuSerializer.java @@ -0,0 +1,166 @@ +package sudoku.io; + +import java.util.ArrayList; +import java.util.List; + +import org.json.JSONArray; +import org.json.JSONObject; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import sudoku.Block; +import sudoku.Cell; +import sudoku.ImmutableCell; +import sudoku.MultiDoku; +import sudoku.MutableCell; +import sudoku.Sudoku; + +public class SudokuSerializer { + + public static String serializeSudoku(final MultiDoku multidoku) { + List cellIds = new ArrayList<>(); + List blockIds = new ArrayList<>(); + + JSONObject jsonRoot = new JSONObject(); + JSONArray jsonCells = new JSONArray(); + JSONArray jsonBlocks = new JSONArray(); + JSONArray jsonSudokus = new JSONArray(multidoku.getNbSubGrids()); + + for (int i = 0; i < multidoku.getNbSubGrids(); i++) { + Sudoku sudoku = multidoku.getSubGrid(i); + + // init cells + for (Cell cell : sudoku.getCells()) { + if (!cellIds.contains(cell)) { + cellIds.add(cell); + + } + + Block block = cell.getBlock(); + if (!blockIds.contains(block)) { + blockIds.add(block); + } + + int blockID = blockIds.indexOf(block); + int symboleIndex = cell.getSymboleIndex(); + + JSONObject cellJsonObject = new JSONObject(); + cellJsonObject.put("blockID", blockID); + cellJsonObject.put("symboleIndex", symboleIndex); + if (cell instanceof ImmutableCell) { + cellJsonObject.put("immutable", true); + } + jsonCells.put(cellJsonObject); + } + + } + + // init blocks + + for (int i = 0; i < blockIds.size(); i++) { + JSONObject blockJsonObject = new JSONObject(); + JSONArray cellsJsonArray = new JSONArray(); + Block block = blockIds.get(i); + for (Cell cell : block.getCells()) { + int cellID = cellIds.indexOf(cell); + cellsJsonArray.put(cellID); + } + blockJsonObject.put("cellIDs", cellsJsonArray); + jsonBlocks.put(blockJsonObject); + } + + for (int i = 0; i < multidoku.getNbSubGrids(); i++) { + // serialise sub grid + JSONObject jsonSudoku = new JSONObject(); + JSONArray cellsJsonArray = new JSONArray(); + JSONArray blocksJsonArray = new JSONArray(); + + Sudoku sudoku = multidoku.getSubGrid(i); + + // serialize cells + + for (Cell cell : sudoku.getCells()) { + int cellID = cellIds.indexOf(cell); + cellsJsonArray.put(cellID); + } + + // serialize blocks + + for (Block block : sudoku.getBlocks()) { + int blockID = blockIds.indexOf(block); + blocksJsonArray.put(blockID); + } + + jsonSudoku.put("cells", cellsJsonArray); + jsonSudoku.put("blocks", blocksJsonArray); + jsonSudokus.put(i, jsonSudoku); + } + + jsonRoot.put("multidoku", jsonSudokus); + jsonRoot.put("cells", jsonCells); + jsonRoot.put("blocks", jsonBlocks); + return jsonRoot.toString(); + } + + public static MultiDoku deserializeSudoku(final String data) { + JSONObject jsonObject = new JSONObject(data); + + List cells = new ArrayList<>(); + List blocks = new ArrayList<>(); + List sudokus = new ArrayList<>(); + + // init cells + JSONArray cellsJson = jsonObject.getJSONArray("cells"); + for (int i = 0; i < cellsJson.length(); i++) { + JSONObject entry = cellsJson.getJSONObject(i); + int symboleIndex = entry.getInt("symboleIndex"); + if (entry.has("immutable")) { + cells.add(new ImmutableCell(symboleIndex)); + } else { + cells.add(new MutableCell(symboleIndex)); + } + } + + // init blocks + JSONArray blocksJson = jsonObject.getJSONArray("blocks"); + for (int i = 0; i < blocksJson.length(); i++) { + JSONObject entry = blocksJson.getJSONObject(i); + JSONArray cellIds = entry.getJSONArray("cellIDs"); + List blockCells = new ArrayList<>(); + Block newBlock = new Block(blockCells); + for (int j = 0; j < cellIds.length(); j++) { + int cellID = cellIds.getInt(j); + Cell blockCell = cells.get(cellID); + blockCell.setBlock(newBlock); + blockCells.add(blockCell); + } + blocks.add(newBlock); + } + + JSONArray multidokuJsonObject = jsonObject.getJSONArray("multidoku"); + for (int i = 0; i < multidokuJsonObject.length(); i++) { + JSONObject sudokuJsonObject = multidokuJsonObject.getJSONObject(i); + JSONArray sudokuCellsJsonArray = sudokuJsonObject.getJSONArray("cells"); + JSONArray sudokuBlocksJsonArray = sudokuJsonObject.getJSONArray("blocks"); + + List sudokuCells = new ArrayList<>(); + List sudokuBlocks = new ArrayList<>(); + + for (int j = 0; j < sudokuCellsJsonArray.length(); j++) { + int cellID = sudokuCellsJsonArray.getInt(j); + sudokuCells.add(cells.get(cellID)); + } + + for (int j = 0; j < sudokuBlocksJsonArray.length(); j++) { + int blockID = sudokuBlocksJsonArray.getInt(j); + sudokuBlocks.add(blocks.get(blockID)); + } + + sudokus.add(new Sudoku(sudokuCells, sudokuBlocks)); + } + + return new MultiDoku(sudokus); + } + +} diff --git a/app/src/main/java/sudoku/solver/Solver.java b/app/src/main/java/sudoku/solver/Solver.java index 9f4376f..8050057 100644 --- a/app/src/main/java/sudoku/solver/Solver.java +++ b/app/src/main/java/sudoku/solver/Solver.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.Random; public class Solver { - Caretaker stack; + // Caretaker stack; public Solver() { } @@ -27,8 +27,8 @@ public class Solver { int indexCurrentCell = rand.nextInt(remainingCellsToCheck.size()); MutableCell currentCell = remainingCellsToCheck.get(indexCurrentCell); if (currentCell.getHints().isEmpty()){ - MutableCell modify = allMutableCells.get(stack.undo()); - modify.clear(modify.getSymboleIndex()); + // MutableCell modify = allMutableCells.get(stack.undo()); + // modify.clear(modify.getSymboleIndex()); } diff --git a/app/src/test/java/sudoku/SudokuSerializerTest.java b/app/src/test/java/sudoku/SudokuSerializerTest.java new file mode 100644 index 0000000..663d0a2 --- /dev/null +++ b/app/src/test/java/sudoku/SudokuSerializerTest.java @@ -0,0 +1,28 @@ +package sudoku; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import sudoku.io.SudokuPrinter; +import sudoku.io.SudokuSerializer; + +public class SudokuSerializerTest { + + void testSerializeWithSize(int blockWidth, int blockHeight) { + var sudoku = SudokuFactory.createBasicEmptyRectangleSudoku(blockWidth, blockHeight); + SudokuPrinter.printRectangleSudoku(sudoku.getSubGrid(0), blockWidth, blockHeight); + String data = SudokuSerializer.serializeSudoku(sudoku); + MultiDoku multiDoku = SudokuSerializer.deserializeSudoku(data); + assertTrue(data.equals(SudokuSerializer.serializeSudoku(multiDoku))); + } + + @Test + void testSerialize() { + int blockWidth = 3; + int blockHeight = 3; + testSerializeWithSize(blockWidth, blockHeight); + } + +}