private static Grid <int> RunBacktrackingSearch(SudokuGrid puzzleGrid) { var nextVariable = GetNextVariable(puzzleGrid); if (nextVariable == null) { return(puzzleGrid.GetValues()); // the base case: the grid is full } // Save the constraining variables here to avoid generating them on // every iteration below. var constraints = puzzleGrid.GetUnsetNeighbors(nextVariable); foreach (int value in nextVariable.GetPossibleValues()) { nextVariable.Value = value; if (CheckConsistency(nextVariable, constraints)) { var nextGrid = UpdateGridForAssignment(nextVariable, constraints, puzzleGrid); var solution = RunBacktrackingSearch(nextGrid); if (solution != null) { return(solution); } } } return(null); }
/// <summary> /// Makes a deep copy of a grid. /// </summary> /// <param name="other">the grid to copy</param> public SudokuGrid(SudokuGrid other) { Validate.IsNotNull(other, "other"); Variables = new Grid <Variable>(GRID_SIZE, GRID_SIZE); foreach (var v in other.Variables) { Variables[v.Location] = new Variable(v); } }
/* * Deep copies the grid and propagates the constraints implied by the assigned variable. */ private static SudokuGrid UpdateGridForAssignment( Variable assigned, IEnumerable <Variable> constraints, SudokuGrid currentGrid) { var newGrid = new SudokuGrid(currentGrid); foreach (var constraint in constraints) { newGrid[constraint.Location].RemovePossibleValue(assigned.Value); } return(newGrid); }
/* * Returns the unset variable with the fewest remaining possible values. */ private static Variable GetNextVariable(SudokuGrid puzzleGrid) { Variable result = null; foreach (var v in puzzleGrid.GetAllUnsetVariables()) { if (result == null || v.PossibleValuesCount < result.PossibleValuesCount) { result = v; } } return(result); }
/* * Initialize the possible values for each variable using the known * initial values. */ private static SudokuGrid InitializeVariables(Grid <int> initialValues) { var puzzleGrid = new SudokuGrid(initialValues); foreach (var unset in puzzleGrid.GetAllUnsetVariables()) { foreach (var constraint in puzzleGrid.GetSetNeighbors(unset)) { unset.RemovePossibleValue(constraint.Value); } } return(puzzleGrid); }