/* Solver */ /// <summary> /// The SuDoku Solver's algorithm only uses logical arguments to solve the puzzles. /// It does not use 'trial and error' methods. For anybody interested in an explanation /// of the algorithm it employs to solve your SuDoku then please read on. The Solver /// stores two grids (as arrays), one is the actual SuDoku grid itself, and the second /// contains all the 'possible values' for each square. Initially all values (1-9) would /// be possible for all squares of course. The algorithm then tries a number of steps to /// solve the puzzle, stopping when it either solves the SuDoku or all the following steps /// fail to find any new values. /// </summary> public bool SolveBoard() { // Initialize fields possibleValues = new List <int> [_board.GetBoardSize(), _board.GetBoardSize()]; // Create a list of all possible values for (int i = 0; i < _board.GetBoardSize(); i++) { for (int j = 0; j < _board.GetBoardSize(); j++) { if (_board.IsNumberBlank(i, j)) { possibleValues[i, j] = new List <int>().GenerateAllPossibleValues(_board.GetBoardSize()); } else { possibleValues[i, j] = new List <int>(); } } } // Find new numbers until the board is solved while (true) { // Perform step 1, noting any new numbers int foundNumbers = SolverStep1(); if (Validator.ValidateBoard(_board, true)) { return(true); } // Perform step 2, noting any new numbers foundNumbers += SolverStep2(); if (Validator.ValidateBoard(_board, true)) { return(true); } // If neither of step 1 nor 2 finds a number, move to step 3 and 4 if (foundNumbers == 0) { // Perform step 3, noting any changes to possible values bool foundInvalidValues = SolverStep3(); // Perform step 4, noting any changes to possible values foundInvalidValues |= SolverStep4(); // If no new information is found, try brute force if (!foundInvalidValues) { return(BruteForce()); } } } }
/* Parsers */ public static string ParseDataFromBoard(AbstractBoard board) { StringBuilder text = new StringBuilder(); for (int i = 0; i != board.GetBoardSize(); i++) { // Add newline separators after the first line if (i > 0) { text.Append(Environment.NewLine); } for (int j = 0; j != board.GetBoardSize(); j++) { // Add comma separators after the first number if (j > 0) { text.Append(","); } // Add non-blank numbers if (!board.IsNumberBlank(i, j)) { text.Append(board.GetNumber(i, j)); text.Append(board.IsNumberPredefined(i, j) ? "T" : "F"); } } } return(text.ToString()); }
/* Parsers */ public static string ParseDataFromBoard(AbstractBoard board) { StringBuilder text = new StringBuilder(); for (int i = 0; i != board.GetBoardSize(); i++) { // Add newline separators after the first line if (i > 0) text.Append(Environment.NewLine); for (int j = 0; j != board.GetBoardSize(); j++) { // Add comma separators after the first number if (j > 0) text.Append(","); // Add non-blank numbers if (!board.IsNumberBlank(i, j)) { text.Append(board.GetNumber(i, j)); text.Append(board.IsNumberPredefined(i, j) ? "T" : "F"); } } } return text.ToString(); }
public static bool ValidateSection(AbstractBoard board, IEnumerable<Coordinate> cells, bool completeCheck = false) { HashSet<int> previousValues = new HashSet<int>(); foreach (Coordinate cell in cells) { // Get current value int value = board.GetNumber(cell.Row, cell.Column); // Check if the current value is blank if (board.IsNumberBlank(cell.Row, cell.Column)) { // For a complete check; none of the numbers are allowed to be blank // Otherwise skip to next cell if (completeCheck) return false; else continue; } // Check if the current value is duplicated if (previousValues.Contains(value)) return false; // Store the current value previousValues.Add(value); } // No duplicates return true; }
public bool IsNumberBlank(int row, int column) { if (_board != null) { return(_board.IsNumberBlank(row, column)); } else { throw new GameNotStartedException(); } }
private void RemoveNumbersInCell(int CellsToClear) // clear cells { int j = 0; do { int randomRow = RandomNumberGen(0, _board.GetBoardSize()); int randomColumn = RandomNumberGen(0, _board.GetBoardSize()); if (!_board.IsNumberBlank(randomRow, randomColumn)) { _board.ClearNumber(randomRow, randomColumn); j++; } } while (j < CellsToClear); }
public static bool ValidateSection(AbstractBoard board, IEnumerable <Coordinate> cells, bool completeCheck = false) { HashSet <int> previousValues = new HashSet <int>(); foreach (Coordinate cell in cells) { // Get current value int value = board.GetNumber(cell.Row, cell.Column); // Check if the current value is blank if (board.IsNumberBlank(cell.Row, cell.Column)) { // For a complete check; none of the numbers are allowed to be blank // Otherwise skip to next cell if (completeCheck) { return(false); } else { continue; } } // Check if the current value is duplicated if (previousValues.Contains(value)) { return(false); } // Store the current value previousValues.Add(value); } // No duplicates return(true); }