/// <summary> /// Considers each cell of the grid. /// </summary> /// <returns> /// Returns the cell with the smallest number /// of possible values. This square is a good /// place to continue search. /// Returns null if the grid is invalid. /// </returns> private CellConsideration Consider(Grid grid) { int smallestNOfHints = int.MaxValue; CellConsideration smallestConsideration = null; for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { if (grid.Get(row, col) == 0) { List <int> hints = GetHintsFor(grid, row, col); if (hints.Count == 0) { // We found a square that has no solution // This means the current state of the puzzle is bogus // so stop. return(null); } if (hints.Count < smallestNOfHints) { smallestConsideration = new CellConsideration(row, col, hints); smallestNOfHints = hints.Count; } } } } return(smallestConsideration); }
/// <summary> /// The actual meat of the depthfirst search goes here. /// (solve is mostly bookkeeping) /// </summary> /// <param name="eachSolutionAction"> /// This lambda will be run once for each solution. /// </param> /// <param name="grid"> /// This grid will be left in an undefined state /// after DepthFirstSearch() terminates. /// If you want a good solution, be sure to save /// a copy in your eachSolutionAction. /// </param> public void DepthFirstSearch(Grid grid, Action eachSolutionAction) { CellConsideration cell = Consider(grid); if (grid.IsFull()) { // Found a solution! eachSolutionAction(); } else if (cell != null) { foreach (int hint in cell.PossibleValues) { grid.Set(hint, true, cell.Row, cell.Col); DepthFirstSearch(grid, eachSolutionAction); grid.Set(0, true, cell.Row, cell.Col); // speed hack: we know the previous square // was a zero, so no need to save a copy // of the grid every time. } } }
/// <summary> /// Considers each cell of the grid. /// </summary> /// <returns> /// Returns the cell with the smallest number /// of possible values. This square is a good /// place to continue search. /// Returns null if the grid is invalid. /// </returns> private CellConsideration Consider(Grid grid) { int smallestNOfHints = int.MaxValue; CellConsideration smallestConsideration = null; for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { if (grid.Get(row, col) == 0) { List<int> hints = GetHintsFor(grid, row, col); if (hints.Count == 0) { // We found a square that has no solution // This means the current state of the puzzle is bogus // so stop. return null; } if (hints.Count < smallestNOfHints) { smallestConsideration = new CellConsideration(row, col, hints); smallestNOfHints = hints.Count; } } } } return smallestConsideration; }