private bool SetCellPossibilityToFalse(SudokuCell cell, int number) { if (cell.Number > 0) return false; if (cell.PossibleNumbers[number]) { cell.PossibleNumbers[number] = false; bool isSolved = cell.IsSolved(); if (!CheckValid()) { int thisIsTheSpotToCheck = 10; } if (isSolved) SolvedCellCleanup(cell); return isSolved; } return false; }
private void SolvedCellCleanup(SudokuCell solvedCell) { string values = solvedCell.Possibilities; List<SudokuCell> horiz = GetCellGroupingFor(solvedCell, CellGroupingType.Horizontal); CleanOtherCells(horiz, values); List<SudokuCell> verts = GetCellGroupingFor(solvedCell, CellGroupingType.Vertical); CleanOtherCells(verts, values); List<SudokuCell> sqrs = GetCellGroupingFor(solvedCell, CellGroupingType.Square); CleanOtherCells(sqrs, values); }
private void Print(SudokuCell[,] data) { for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { string print; if (data[col, row].Number == 0) { print = "- "; } else { print = String.Format("{0} ", data[col, row].Number); } Console.Write(print); } Console.WriteLine(); } Console.WriteLine("\t Number left: {0}", CountNumberLeft(data)); }
private void PrintBig(SudokuCell[,] data) { string longdash = new string('─', 11); Console.WriteLine("┌{0}┬{0}┬{0}┐", "───┬───┬───"); for (int row = 0; row < 9; row++) { for (int subrow = 1; subrow <= 3; subrow++) { Console.Write("│"); for (int col = 0; col < 9; col++) { for (int possibleNbr = (1 + (subrow - 1) * 3); possibleNbr <= (subrow * 3); possibleNbr++) { if (data[col, row].Number == 0) Console.Write((data[col, row].PossibleNumbers[possibleNbr]) ? (possibleNbr).ToString() : " "); else Console.Write(data[col, row].Number.ToString()); } Console.Write("│"); } Console.WriteLine(); //if (subrow < 3) // Console.WriteLine("│{0}│{0}│{0}│", longdash); } if ((row + 1) % 3 == 0) { if (row < 8) Console.WriteLine("├{0}┼{0}┼{0}┤", "───┼───┼───"); } else { Console.WriteLine("├{0}┼{0}┼{0}┤", "───┼───┼───"); } } Console.WriteLine("└{0}┴{0}┴{0}┘", "───┴───┴───"); Console.WriteLine(); }
private void LoadStringData(string raw) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { int idx = y * 9 + x; originalData[x, y] = new SudokuCell(raw.Substring(idx, 1), x, y); } } }
private List<SudokuCell> GetCellGroupingFor(SudokuCell cell, CellGroupingType type) { int col = cell.Col; int row = cell.Row; List<SudokuCell> cells = new List<SudokuCell>(); switch (type) { case CellGroupingType.Horizontal: for (int i = 0; i < 9; i++) { cells.Add(solvedData[i, row]); } break; case CellGroupingType.Vertical: for (int i = 0; i < 9; i++) { cells.Add(solvedData[col, i]); } break; case CellGroupingType.Square: int gridCol = col / 3; int gridRow = row / 3; int gridX = 3 * gridCol; int gridY = 3 * gridRow; for (int x = gridX; x - gridX < 3; x++) { for (int y = gridY; y - gridY < 3; y++) { cells.Add(solvedData[x, y]); } } break; } return cells; }
private int CountNumberLeft(SudokuCell[,] data) { int numLeft = 0; for (int row = 0; row < 9; row++) { for (int col = 0; col < 9; col++) { if (data[col, row].Number == 0) { numLeft++; } } } return numLeft; }
public bool SolveSudoku(int thisProblemNumber, bool debug) { PrintBig(originalData); // we'll start at the beginning and // use solvedData as our work area. for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { solvedData[x, y] = new SudokuCell(originalData[x, y].Number, x, y); } } int round = 1; int thisRoundNumLeft = -1; int lastRoundNumLeft = -1; do { //Check Horizontals for (int row = 0; row < 9; row++) { // get list of cells for this column List<SudokuCell> cells = GetCellGroupingFor(solvedData[0, row], CellGroupingType.Horizontal); // apply logic to this independant grouping NarrowDownIndependantCellGrouping(cells, CellGroupingType.Horizontal); } //Check Verticals for (int col = 0; col < 9; col++) { // get list of cells for this column List<SudokuCell> cells = GetCellGroupingFor(solvedData[col, 0], CellGroupingType.Vertical); // apply logic to this independant grouping NarrowDownIndependantCellGrouping(cells, CellGroupingType.Vertical); } // Check Square Groups for (int gridRow = 0; gridRow < 3; gridRow++) { for (int gridCol = 0; gridCol < 3; gridCol++) { // create a list of cells for this group List<SudokuCell> cells = GetCellGroupingFor(solvedData[gridCol * 3, gridRow * 3], CellGroupingType.Square); // apply logic to this independant grouping NarrowDownIndependantCellGrouping(cells, CellGroupingType.Square); } } // **** NOTE **** // SEE: http://www.sudokuessentials.com/sudoku_tips.html // **** NOTE **** if (debug) { Console.WriteLine("After Round {0}:", round); PrintBig(solvedData); } thisRoundNumLeft = CountNumberLeft(solvedData); round++; if (thisRoundNumLeft == lastRoundNumLeft) { Console.WriteLine("!!!!!!!!!!!!!!!!! Not making any headway on {0} !!!!!!!!", thisProblemNumber); if (debug) PrintBig(solvedData); if (CheckValid()) { bool guessedCorrect = false; // now make guesses and solve each guess for (int row = 0; row < 10; row++) { if (guessedCorrect) break; for (int col = 0; col < 10; col++) { if (guessedCorrect) break; if (solvedData[col, row].Number == 0) { for (int i = 1; i < 10; i++) { string theseUsed = solvedData[col, row].Possibilities; if (theseUsed.Substring(i, 1) != "-") { Sudoku newPuzzle = new Sudoku(solvedData); newPuzzle.originalData[col, row].Number = i; guessedCorrect = newPuzzle.SolveSudoku(thisProblemNumber, debug); if (guessedCorrect) { solvedData = newPuzzle.solvedData; } } if (guessedCorrect) break; } } } } } break; } lastRoundNumLeft = thisRoundNumLeft; } while (!IsCompletelySolved); if (!debug) PrintBig(solvedData); return CheckValid(); }
public Sudoku(SudokuCell[,] original_data) { for (int x = 0; x < 9; x++) { for (int y = 0; y < 9; y++) { int idx = y * 9 + x; originalData[x, y] = new SudokuCell(original_data[x, y].Number, x, y); } } }