package sudoku.io; import java.io.*; import java.util.ArrayList; import java.util.List; import org.json.JSONArray; import org.json.JSONObject; import sudoku.structure.Block; import sudoku.structure.Cell; import sudoku.structure.MultiDoku; import sudoku.structure.Sudoku; import sudoku.structure.SudokuFactory; public class SudokuSerializer { public static JSONObject 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 symbolIndex = cell.getSymbolIndex(); JSONObject cellJsonObject = new JSONObject(); cellJsonObject.put("blockID", blockID); cellJsonObject.put("symbolIndex", symbolIndex); if (!cell.isMutable()) { cellJsonObject.put("immutable", true); } jsonCells.put(cellJsonObject); } } // init blocks for (Block blockId : blockIds) { JSONObject blockJsonObject = new JSONObject(); JSONArray cellsJsonArray = new JSONArray(); for (Cell cell : blockId.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); jsonSudoku.put("blockWidth", sudoku.getBlockWidth()); jsonSudokus.put(i, jsonSudoku); } jsonRoot.put("multidoku", jsonSudokus); jsonRoot.put("cells", jsonCells); jsonRoot.put("blocks", jsonBlocks); return jsonRoot; } public static void saveMultiDoku(final MultiDoku doku) { JSONObject jsonRoot = serializeSudoku(doku); File f = new File("save", "save.json"); InputStream is = null; int i = 1; while (f.exists()) { String newName = "save-" + i + ".json"; f = new File("save", newName); i++; } try (FileWriter file = new FileWriter(f)) { file.write(jsonRoot.toString(3)); //file.flush(); } catch (IOException e) { e.fillInStackTrace(); } } public static MultiDoku deserializeSudoku(final String json) { JSONObject jsonRoot = new JSONObject(json); return deserializeSudoku(jsonRoot); } public static MultiDoku deserializeSudoku(final JSONObject jsonObject) { 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 symbolIndex = entry.getInt("symbolIndex"); if (entry.has("immutable")) { cells.add(new Cell(symbolIndex, false)); } else { cells.add(new Cell(symbolIndex)); } } // 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)); } Sudoku s = new Sudoku(sudokuCells, sudokuBlocks, SudokuFactory.DEFAULT_CONSTRAINTS); s.setBlockWidth(sudokuJsonObject.getInt("blockWidth")); sudokus.add(s); } return new MultiDoku(sudokus); } }