package sudoku.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; 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.getSymbolIndex(); JSONObject cellJsonObject = new JSONObject(); cellJsonObject.put("blockID", blockID); cellJsonObject.put("symboleIndex", symboleIndex); 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); 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 Cell(symboleIndex, false)); } else { cells.add(new Cell(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, null)); } return new MultiDoku(sudokus); } }