/// <summary> /// 解答题目 /// </summary> /// <param name="doString">数独字符串</param> /// <returns></returns> public static int[] Solve(string doString) { int r = 0; int c = 0; SuDoTable dt = new SuDoTable(); for (int i = 0; i < 81; i++) { r = i / 9; c = i % 9; dt[r, c] = new SuDoCell(r, c); } int[] doArray = SuDoHelper.GetDoIntArrary(doString); for (int i = 0; i < doArray.Length; i++) { r = i / 9; c = i % 9; int value = doArray[i]; dt.SetValue(r, c, value);//值先进行校验后,保存入DoTabel } dt.Solve(); List <int> intList = new List <int>(); for (int i = 0; i < dt._DoTable.Length; i++) { intList.Add(dt._DoTable[i / 9, i % 9].Value); } return(intList.ToArray()); }
/// <summary> /// Search for cells with an unique possible value. /// </summary> /// <param name="sudokuCellsToSolve">List of cells pending to solve.</param> private bool SolveCellsWithOnePossibility(List <SuDoCell> sudokuCellsToSolve) { bool result = false; int i = 0; while (i < sudokuCellsToSolve.Count) { if (sudokuCellsToSolve[i].IsValid) { sudokuCellsToSolve.RemoveAt(i); } else if (sudokuCellsToSolve[i].NumPossibilities == 1) { SuDoCell cell = sudokuCellsToSolve[i]; int solution = cell.PickRandomPossibility(); if (solution < 0) { throw new ApplicationException("Sudoku cannot be solved!"); } this.SetValue(cell.Row, cell.Column, solution); this.OnSudokuStrategyUsed( new SuDoStrategyUsedEventArgs(SuDoStrategy.UniqueValueForCell, cell)); result = true; sudokuCellsToSolve.RemoveAt(i); } else { i++; } } return(result); }
/// <summary> /// Constructor for this class. /// </summary> /// <param name="strategy">Strategy selected to solve a cell.</param> /// <param name="cell">Cell just solved.</param> public SuDoStrategyUsedEventArgs(SuDoStrategy strategy, SuDoCell cell) { this.Strategy = strategy; this.Row = cell.Row; this.Col = cell.Column; this.Value = cell.Value; }
/// <summary> /// 解答题目 /// </summary> public void Solve() { // Prepare cells, rows, cols and squares pending to solve... List <SuDoCell> sudokuCellsToSolve = new List <SuDoCell>(); List <int> sudokuRowsToSolve = new List <int>(); List <int> sudokuColsToSolve = new List <int>(); List <int> sudokuSquaresToSolve = new List <int>(); for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { if (!this[row, col].IsValid) { sudokuCellsToSolve.Add(this[row, col]); if (!sudokuRowsToSolve.Contains(row)) { sudokuRowsToSolve.Add(row); } if (!sudokuColsToSolve.Contains(col)) { sudokuColsToSolve.Add(col); } int square = (row / 3) * 3 + (col / 3); if (!sudokuSquaresToSolve.Contains(square)) { sudokuSquaresToSolve.Add(square); } } } } sudokuRowsToSolve.Sort(); sudokuColsToSolve.Sort(); sudokuSquaresToSolve.Sort(); // While any cell to solve... while (sudokuCellsToSolve.Count > 0) { while (true) { if (this.SolveCellsWithOnePossibility(sudokuCellsToSolve)) { continue; } if (this.SolveUniqueCellValueInRows(sudokuRowsToSolve)) { continue; } if (this.SolveUniqueCellValueInCols(sudokuColsToSolve)) { continue; } if (this.SolveUniqueCellValueInSquares(sudokuSquaresToSolve)) { continue; } break; } if (sudokuCellsToSolve.Count == 0) { break; } // Cannot solve any cell...now we depend on luck!! // Find the cell with the minimum possibilities to apply random... int index = -1, minPossib = 10; for (int i = 0; i < sudokuCellsToSolve.Count; i++) { if (minPossib > sudokuCellsToSolve[i].NumPossibilities) { index = i; minPossib = sudokuCellsToSolve[i].NumPossibilities; } } // We choose a solution randomly SuDoCell cell = sudokuCellsToSolve[index]; int solution = cell.PickRandomPossibility(); if (solution < 0) { throw new ApplicationException( string.Format("Cannot found a solution for cell at [{0}, {1}].", cell.Row + 1, cell.Column + 1)); } sudokuCellsToSolve.RemoveAt(index); this.SetValue(cell.Row, cell.Column, solution); this.OnSudokuStrategyUsed( new SuDoStrategyUsedEventArgs(SuDoStrategy.RandomPick, cell)); } }