1 package io.github.skenvy;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import javax.swing.text.Utilities;
6
7 import io.github.skenvy.CellCollection;
8 import io.github.skenvy.Utility;
9
10
11
12
13
14
15 public class SudokuGrid {
16
17
18
19
20 private final List<CellCollection> rows;
21
22
23
24
25 private final List<CellCollection> columns;
26
27
28
29
30
31 private final List<CellCollection> boxes;
32
33
34
35
36 private final Cell[][][][] cells;
37
38
39
40
41 public SudokuGrid() throws SudokuCellGridInvalidGridShapeException, Cell.SudokuCellInvalidInitialValueException {
42 this.cells = createCellGrid(new int[3][3][3][3]);
43 this.rows = null;
44 this.columns = null;
45 this.boxes = null;
46 }
47
48
49
50
51 public SudokuGrid(int boardSize) throws SudokuCellGridInvalidGridShapeException, Cell.SudokuCellInvalidInitialValueException {
52 this.cells = createCellGrid(new int[3][3][3][3]);
53 int collectionSize = (boardSize * boardSize);
54 this.rows = null;
55 this.columns = null;
56 this.boxes = null;
57 }
58
59
60
61
62 public SudokuGrid(SudokuGrid initialGrid, boolean exactReplica) throws SudokuCellGridInvalidGridShapeException, Cell.SudokuCellInvalidInitialValueException {
63 this.cells = createCellGrid(new int[3][3][3][3]);
64 this.rows = initialGrid.getRows();
65 this.columns = initialGrid.getColumns();
66 this.boxes = initialGrid.getBoxes();
67 }
68
69 private Cell[][][][] createCellGrid(int[][] valuesGrid) throws SudokuCellGridInvalidGridShapeException, Cell.SudokuCellInvalidInitialValueException {
70 if (valuesGrid.length != valuesGrid[0].length) {
71 throw new SudokuCellGridInvalidGridShapeException(valuesGrid.length, valuesGrid[0].length);
72 } else if (!Utility.isIntegerSquared(valuesGrid.length)) {
73 throw new SudokuCellGridInvalidGridShapeException(valuesGrid.length);
74 }
75 int boardSize = Utility.integerSquareRoot(valuesGrid.length);
76 int[][][][] newValuesGrid = new int[boardSize][boardSize][boardSize][boardSize];
77 for (int boardRow = 0; boardRow < boardSize; boardRow++) {
78 for (int boardColumn = 0; boardColumn < boardSize; boardColumn++) {
79 for (int boxInternalRow = 0; boxInternalRow < boardSize; boxInternalRow++) {
80 for (int boxInternalColumn = 0; boxInternalColumn < boardSize; boxInternalColumn++) {
81 newValuesGrid[boardRow][boardColumn][boxInternalRow][boxInternalColumn] = valuesGrid[boardSize * boardRow + boxInternalRow][boardSize * boardColumn + boxInternalColumn];
82 }
83 }
84 }
85 }
86 return createCellGrid(newValuesGrid);
87 }
88
89 private Cell[][][][] createCellGrid(int[][][][] valuesGrid) throws SudokuCellGridInvalidGridShapeException, Cell.SudokuCellInvalidInitialValueException {
90 if ((valuesGrid.length != valuesGrid[0].length) || (valuesGrid.length != valuesGrid[0][0].length) || (valuesGrid.length != valuesGrid[0][0][0].length)) {
91 throw new SudokuCellGridInvalidGridShapeException(valuesGrid.length, valuesGrid[0].length, valuesGrid[0][0].length, valuesGrid[0][0][0].length);
92 }
93 int boardSize = valuesGrid.length;
94 Cell[][][][] tempCells = new Cell[boardSize][boardSize][boardSize][boardSize];
95 List<CellCollection> rows = initialiseEmptyCellCollections(boardSize);
96 List<CellCollection> columns = initialiseEmptyCellCollections(boardSize);
97 List<CellCollection> boxes = initialiseEmptyCellCollections(boardSize);
98 for (int boardRow = 0; boardRow < boardSize; boardRow++) {
99 for (int boardColumn = 0; boardColumn < boardSize; boardColumn++) {
100 for (int boxInternalRow = 0; boxInternalRow < boardSize; boxInternalRow++) {
101 for (int boxInternalColumn = 0; boxInternalColumn < boardSize; boxInternalColumn++) {
102
103 int rowIndex = boardSize * boardRow + boxInternalRow;
104 int colIndex = boardSize * boardColumn + boxInternalColumn;
105 int boxIndex = boardSize * boardRow + boardColumn;
106 tempCells[boardRow][boardColumn][boxInternalRow][boxInternalColumn] = new Cell(valuesGrid[boardRow][boardColumn][boxInternalRow][boxInternalColumn], boardSize, rows.get(rowIndex), columns.get(colIndex), boxes.get(boxIndex));
107
108 rows.get(rowIndex).addCellToCollection(tempCells[boardRow][boardColumn][boxInternalRow][boxInternalColumn]);
109 columns.get(colIndex).addCellToCollection(tempCells[boardRow][boardColumn][boxInternalRow][boxInternalColumn]);
110 boxes.get(boxIndex).addCellToCollection(tempCells[boardRow][boardColumn][boxInternalRow][boxInternalColumn]);
111 }
112 }
113 }
114 }
115 return tempCells;
116 }
117
118 List<CellCollection> initialiseEmptyCellCollections(int boardSize) {
119 List<CellCollection> tempCollections = new ArrayList<CellCollection>((boardSize * boardSize));
120 for (int k = 0; k < (boardSize * boardSize); k++) {
121 tempCollections.add(new CellCollection(boardSize));
122 }
123 return tempCollections;
124 }
125
126 public List<CellCollection> getRows() {
127 return this.rows;
128 }
129
130 public List<CellCollection> getColumns() {
131 return this.columns;
132 }
133
134 public List<CellCollection> getBoxes() {
135 return this.boxes;
136 }
137
138
139
140
141 public class SudokuCellGridException extends Exception {
142
143 public SudokuCellGridException(String string) {
144 super(string);
145 }
146
147 }
148
149 public class SudokuCellGridInvalidGridShapeException extends Exception {
150
151 public SudokuCellGridInvalidGridShapeException(int macroRows, int macroCols, int microRows, int microCols) {
152 super(String.format("The shape of the input grid was not a valid square, received nested array lengths of %d, %d, %d, %d", macroRows, macroCols, microRows, microCols));
153 }
154
155 public SudokuCellGridInvalidGridShapeException(int rows, int cols) {
156 super(String.format("The shape of the input grid was not a valid square, received nested array lengths of %d, %d", rows, cols));
157 }
158
159 public SudokuCellGridInvalidGridShapeException(int rows) {
160 super(String.format("The shape of the input grid was not a valid square, received non square value for collections count, received %d", rows));
161 }
162
163 }
164
165 }