package sudoku.structure; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import sudoku.constraint.BlockConstraint; import sudoku.constraint.ColumnConstraint; import sudoku.constraint.IConstraint; import sudoku.constraint.LineConstraint; public class SudokuFactory { public static List DEFAULT_CONSTRAINTS = Arrays.asList(new BlockConstraint(), new LineConstraint(), new ColumnConstraint()); private static List initCells(int size) { List cells = new ArrayList<>(size * size); for (int i = 0; i < size * size; i++) { cells.add(new Cell()); } return cells; } private static List initRectangleBlocs(List cells, int width, int height) { List blocs = new ArrayList<>(); int size = width * height; for (int i = 0; i < size; i++) { Block newBlock = new Block(); int blockX = i % height; int blockY = i / height; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int index = ((y + blockY * height) * size + (x + blockX * width)); Cell blockCell = cells.get(index); blockCell.setBlock(newBlock); // List blockContainers = new ArrayList<>(); // blockContainers.add(newBlock); // blockCell.setBlockContainers(blockContainers); newBlock.addCell(blockCell); } } blocs.add(newBlock); } return blocs; } public static MultiDoku createBasicEmptyRectangleSudoku(int widthBlock, int heightBlock) { Sudoku s = createRectangleSudoku(widthBlock, heightBlock); return new MultiDoku(Arrays.asList(s)); } public static MultiDoku createBasicEmptySquareSudoku(int size) { return createBasicEmptyRectangleSudoku(size, size); } public static void setIMMutableCells(MultiDoku doku, Map immutableCells) { immutableCells.forEach((coordinate, symbol) -> { for (Sudoku sudoku : doku.getSubGrids()) { Cell cell = sudoku.getCell(coordinate.getX(), coordinate.getY()); if (cell != null) { cell.setSymbolIndex(symbol); cell.setImmutable(); } } }); } private static Sudoku createRectangleSudoku(int width, int height) { int symbolCount = width * height; List cases = initCells(symbolCount); List blocs = initRectangleBlocs(cases, width, height); Sudoku s = new Sudoku(cases, blocs, DEFAULT_CONSTRAINTS); s.setBlockWidth(width); return s; } private static Sudoku createSquareSudoku(int size) { return createRectangleSudoku(size, size); } private static void linkSquareSudokus(Sudoku sudoku1, Sudoku sudoku2, Coordinate offset) { int blockWidth = sudoku1.getBlockWidth(); for (int dx = 0; dx < blockWidth; dx++) { for (int dy = 0; dy < blockWidth; dy++) { int block1X = dx + offset.getX(); int block1Y = dy + offset.getY(); int block2X = dx; int block2Y = dy; if ((block1X < blockWidth) && (block1X >= 0) && (block1Y >= 0) && (block1Y < blockWidth)) { Block block1 = sudoku1.getBlocks().get(block1Y * blockWidth + block1X); Block block2 = sudoku2.getBlocks().get(block2Y * blockWidth + block2X); // on remplace le bloc sudoku2.getBlocks().set(block2Y * blockWidth + block2X, block1); // on remplace les cellules for (int i = 0; i < block1.getCells().size(); i++) { Cell newCell = block1.getCells().get(i); Cell oldCell = block2.getCells().get(i); int oldCellIndex = sudoku2.getCells().indexOf(oldCell); sudoku2.getCells().set(oldCellIndex, newCell); } } } } } public static MultiDoku createBasicSquareMultidoku(int size) { assert (size > 1); /** * 2 3 * 1 * 4 5 */ Sudoku sudoku1 = createSquareSudoku(size); Sudoku sudoku2 = createSquareSudoku(size); Sudoku sudoku3 = createSquareSudoku(size); Sudoku sudoku4 = createSquareSudoku(size); Sudoku sudoku5 = createSquareSudoku(size); linkSquareSudokus(sudoku1, sudoku2, new Coordinate(1 - size, 1 - size)); linkSquareSudokus(sudoku1, sudoku3, new Coordinate(size - 1, 1 - size)); linkSquareSudokus(sudoku1, sudoku4, new Coordinate(1 - size, size - 1)); linkSquareSudokus(sudoku1, sudoku5, new Coordinate(size - 1, size - 1)); return new MultiDoku(Arrays.asList(sudoku1, sudoku2, sudoku3, sudoku4, sudoku5)); } }