// Initialise the forward checking algorithm static void initialise_forwardchecking() { starttime = DateTime.Now; // Make a new grid currentGrid = new Sudoku_Grid(); // Add squares to the grid with their number, row and column for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { currentGrid.sudoku[i, j] = new Square(); currentGrid.sudoku[i, j].row = i; currentGrid.sudoku[i, j].column = j; currentGrid.sudoku[i, j].number = sudoku[i, j]; // Make a domain list of all the possible numbers a square can have if it is changeable if (!unchangable[i, j]) { currentGrid.sudoku[i, j].variables = new List <int>(); int size = 0; for (int k = 1; k <= N; k++) { sudoku[i, j] = k; if (!Violation(i, j)) { currentGrid.sudoku[i, j].variables.Add(k); size++; } } // Reset the value sudoku[i, j] = 0; currentGrid.sudoku[i, j].domainSize = size; } } } currentGrid.ForwardCheck(); }
// Recursive backtracking method that uses forward checking with the most constraining variable public void ForwardCheck() { // Check if the most constraining variable is empty if (MCV == null) { // Create a new location with a high domain size Location l = new Location(); l.size = 900; //Check for each square in the sudoku which square has the lowest domainsize foreach (Square s in sudoku) { if (!Program.unchangable[s.row, s.column]) { if (s.domainSize <= l.size) { l.row = s.row; l.column = s.column; l.size = s.domainSize; if (l.size == 1) { break; } } } } // Assign the location to the most contraining variable MCV = l; } // If the most constraining variable has a size of 900, the sudoku is solved and print the solution if (MCV.size > 800) { //PrintSolution(); Program.sudokufc = sudoku; Printer.print_sudoku(); return; } Program.recursivecalls++; // Copy this grid to make changes in the child child = new Sudoku_Grid(); child = Clone(this); child.parent = this; // Get location of most constraining square int row = MCV.row; int col = MCV.column; // Check if index has exceeded the amount of variables there are if (currentVariableIndex < sudoku[row, col].variables.Count) { int variable = sudoku[row, col].variables[currentVariableIndex]; // Set the square to this variable child.sudoku[row, col].number = variable; // If there are no empty domains move next with the child if (child.MakeConsistent(row, col)) { child.ForwardCheck(); } // Else increase the variable index to try the next possible variable else { currentVariableIndex++; ForwardCheck(); } } // If it has exceeded the amount of variables go back to the parent else { parent.currentVariableIndex++; parent.ForwardCheck(); } }