private void Button_Solve_Click(object sender, EventArgs e) { int[,] sudokuValues = new int[9, 9]; for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { sudokuValues[x, y] = blocks[(int)Math.Floor(x / 3.0), (int)Math.Floor(y / 3.0)] .GetCellValue(x % 3, y % 3); } } Sudoku solver = new Sudoku(); for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { solver.SetValue(x, y, sudokuValues[x, y]); } } bool solved = solver.Solve(); if (solved) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { blocks[(int)Math.Floor(x / 3.0), (int)Math.Floor(y / 3.0)] .SetCellValue(x % 3, y % 3, solver.GetValue(x, y)); } } } }
/// <summary> /// attempts to solve the sudoku /// </summary> /// <returns>true if successful, false otherwise</returns> public bool Solve() { if (!IsSudokuValid()) { return(false); } List <SudokuCell>[] rows = new List <SudokuCell> [9]; List <SudokuCell>[] columns = new List <SudokuCell> [9]; List <SudokuCell>[] blocks = new List <SudokuCell> [9]; List <SudokuCell> fixedCells = new List <SudokuCell>(); List <SudokuCell> emptyCells = new List <SudokuCell>(); for (int i = 0; i < 9; i++) { rows[i] = new List <SudokuCell>(); columns[i] = new List <SudokuCell>(); blocks[i] = new List <SudokuCell>(); } // add cells to rows, columns, blocks and to empty or fixed cells for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { SudokuCell cell = new SudokuCell(i, j, GetValue(i, j)); rows[cell.Row].Add(cell); columns[cell.Column].Add(cell); blocks[cell.Block].Add(cell); if (cell.Value == 0) { emptyCells.Add(cell); } else { fixedCells.Add(cell); } } } // eliminate fixed cell values from possible values in cells on same rows, columns or blocks fixedCells.ForEach(fixedCell => { UpdatePossibleValues(rows[fixedCell.Row], fixedCell.Value); UpdatePossibleValues(columns[fixedCell.Column], fixedCell.Value); UpdatePossibleValues(blocks[fixedCell.Block], fixedCell.Value); }); // keep updating cells untill sudoku is solved or no more updates are possible while (emptyCells.Count > 0) { int updates = 0; // get all cells from empty cells that now have a value emptyCells.ForEach(cell => { if (cell.Value != 0) { fixedCells.Add(cell); SetValue(cell.Row, cell.Column, cell.Value); updates += UpdatePossibleValues(rows[cell.Row], cell.Value); updates += UpdatePossibleValues(columns[cell.Column], cell.Value); updates += UpdatePossibleValues(blocks[cell.Block], cell.Value); } }); emptyCells.RemoveAll(c => fixedCells.Contains(c)); // fill in missing values in rows, columns and blocks for (int i = 0; i < 9; i++) { updates += FillInMissingValues(rows[i]); updates += FillInMissingValues(columns[i]); updates += FillInMissingValues(blocks[i]); } if (updates == 0) { break; } } // check if sudoku is solved if (emptyCells.Count == 0) { return(IsSudokuValid()); } else { // find the empty cell with the least number of possible values emptyCells.ForEach(cell => { if (cell.Value != 0) { fixedCells.Add(cell); SetValue(cell.Row, cell.Column, cell.Value); } }); emptyCells.RemoveAll(c => fixedCells.Contains(c)); emptyCells.Sort((a, b) => a.PossibleValues.Count - b.PossibleValues.Count); SudokuCell cell = emptyCells.First(); for (int i = 1; i <= 9; i++) { if (cell.PossibleValues.Contains(i)) { Sudoku sudoku = new Sudoku(); for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { sudoku.SetValue(x, y, GetValue(x, y)); } } sudoku.SetValue(cell.Row, cell.Column, i); if (sudoku.Solve()) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { SetValue(x, y, sudoku.GetValue(x, y)); } } return(true); } } } return(false); } }