This commit is contained in:
@@ -25,6 +25,10 @@ dependencies {
|
|||||||
|
|
||||||
// uml
|
// uml
|
||||||
implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.26.2'
|
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 {
|
application {
|
||||||
@@ -36,3 +40,7 @@ tasks.named('test') {
|
|||||||
// Use JUnit Platform for unit tests.
|
// Use JUnit Platform for unit tests.
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run {
|
||||||
|
enableAssertions = true
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package sudoku;
|
package sudoku;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
public abstract class Cell {
|
public abstract class Cell {
|
||||||
|
|
||||||
protected static int NOSYMBOLE = -1;
|
protected static int NOSYMBOLE = -1;
|
||||||
|
@JsonProperty("symboleIndex")
|
||||||
protected int symboleIndex;
|
protected int symboleIndex;
|
||||||
protected Block block = null;
|
protected Block block = null;
|
||||||
|
|
||||||
@@ -25,15 +28,15 @@ public abstract class Cell {
|
|||||||
return this.block;
|
return this.block;
|
||||||
}
|
}
|
||||||
|
|
||||||
// only SudokuFactory should access this
|
// only SudokuFactory and SudokuSerializer should access this
|
||||||
void setBlock(Block block) {
|
public void setBlock(Block block) {
|
||||||
this.block = block;
|
this.block = block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public boolean equals(Object obj) {
|
// public boolean equals(Object obj) {
|
||||||
if (obj instanceof Cell otherCell)
|
// if (obj instanceof Cell otherCell)
|
||||||
return otherCell.getSymboleIndex() == this.getSymboleIndex();
|
// return otherCell.getSymboleIndex() == this.getSymboleIndex();
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package sudoku;
|
package sudoku;
|
||||||
|
|
||||||
import sudoku.io.SudokuPrinter;
|
import sudoku.io.SudokuPrinter;
|
||||||
|
import sudoku.io.SudokuSerializer;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public String getGreeting() {
|
public String getGreeting() {
|
||||||
@@ -12,9 +13,5 @@ public class Main {
|
|||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.out.println(new Main().getGreeting());
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package sudoku;
|
|||||||
|
|
||||||
import sudoku.constraint.IConstraint;
|
import sudoku.constraint.IConstraint;
|
||||||
|
|
||||||
import javax.swing.*;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -49,4 +48,17 @@ public class Sudoku {
|
|||||||
}
|
}
|
||||||
return mutableCells;
|
return mutableCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// only used by the serializer
|
||||||
|
|
||||||
|
public List<Block> getBlocks() {
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Cell> getCells() {
|
||||||
|
return cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
9
app/src/main/java/sudoku/io/SudokuFile.java
Normal file
9
app/src/main/java/sudoku/io/SudokuFile.java
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
package sudoku.io;
|
||||||
|
|
||||||
|
import sudoku.MultiDoku;
|
||||||
|
|
||||||
|
public class SudokuFile {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
17
app/src/main/java/sudoku/io/SudokuSave.java
Normal file
17
app/src/main/java/sudoku/io/SudokuSave.java
Normal file
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
166
app/src/main/java/sudoku/io/SudokuSerializer.java
Normal file
166
app/src/main/java/sudoku/io/SudokuSerializer.java
Normal file
@@ -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<Cell> cellIds = new ArrayList<>();
|
||||||
|
List<Block> 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<Cell> cells = new ArrayList<>();
|
||||||
|
List<Block> blocks = new ArrayList<>();
|
||||||
|
List<Sudoku> 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<Cell> 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<Cell> sudokuCells = new ArrayList<>();
|
||||||
|
List<Block> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class Solver {
|
public class Solver {
|
||||||
Caretaker stack;
|
// Caretaker stack;
|
||||||
|
|
||||||
public Solver() {
|
public Solver() {
|
||||||
}
|
}
|
||||||
@@ -27,8 +27,8 @@ public class Solver {
|
|||||||
int indexCurrentCell = rand.nextInt(remainingCellsToCheck.size());
|
int indexCurrentCell = rand.nextInt(remainingCellsToCheck.size());
|
||||||
MutableCell currentCell = remainingCellsToCheck.get(indexCurrentCell);
|
MutableCell currentCell = remainingCellsToCheck.get(indexCurrentCell);
|
||||||
if (currentCell.getHints().isEmpty()){
|
if (currentCell.getHints().isEmpty()){
|
||||||
MutableCell modify = allMutableCells.get(stack.undo());
|
// MutableCell modify = allMutableCells.get(stack.undo());
|
||||||
modify.clear(modify.getSymboleIndex());
|
// modify.clear(modify.getSymboleIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
28
app/src/test/java/sudoku/SudokuSerializerTest.java
Normal file
28
app/src/test/java/sudoku/SudokuSerializerTest.java
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user