/// <summary> /// Convert the puzzle grid to string /// </summary> /// <param name="puzzleGrid"></param> /// <returns>Grid</returns> string PuzzleGrid(Cell[,] puzzleGrid) { StringBuilder puzzle = new StringBuilder(); for (int row = 0; row < 9; row++) for (int column = 0; column < 9; column++) if (string.IsNullOrEmpty(puzzleGrid[row, column].Digit)) puzzle.Append("0"); else puzzle.Append(puzzleGrid[row, column].Digit); return puzzle.ToString(); }
/// <summary> /// Remove the current cell /// </summary> /// <param name="currentCell"></param> public void Dig(Cell currentCell) { string digit = currentCell.Digit; currentCell.Digit = string.Empty; currentCell.IsGiven = false; if (!IterateGrid()) { currentCell.IsGiven = true; currentCell.Digit = digit; } CleanGrid(); }
/// <summary> /// Get the digits valid for the current cell /// </summary> /// <param name="currentCell"></param> /// <returns>Valid digits</returns> string ValidDigits(Cell currentCell) { string startSequence = Utility.START_SEQUENCE; if (currentCell.RestrictedDigits.Length < 9) { for (int i = 0; i < currentCell.RestrictedDigits.Length; i++) currentCell.ValidDigits = startSequence = startSequence.Replace(currentCell.RestrictedDigits.Substring(i, 1), string.Empty); return currentCell.ValidDigits; } else return currentCell.ValidDigits = string.Empty; }
/// <summary> /// Validate if the current cell fits in the pattern /// </summary> /// <param name="currentCell"></param> /// <returns>True if the pattern is valid</returns> bool ValidatePattern(Cell currentCell) { if (!string.IsNullOrEmpty(this.Last.Digit)) return true; if (ValidateCell(currentCell)) { while (currentCell.ValidDigits.Length > 0) { currentCell.Digit = currentCell.ValidDigits.Substring(r.Next(currentCell.ValidDigits.Length), 1); currentCell.ValidDigits = currentCell.ValidDigits.Replace(currentCell.Digit, string.Empty); if (ValidatePattern(GetCell(currentCell))) return true; } } currentCell.RestrictedDigits = currentCell.Digit; currentCell.Digit = string.Empty; currentCell.ValidDigits = Utility.START_SEQUENCE; if (string.IsNullOrEmpty(Last.Digit)) this.PreviousCell(currentCell).Digit = string.Empty; return false; }
/// <summary> /// Validate if the current cell value fits the pattern /// </summary> /// <param name="currentCell"></param> /// <returns>True if the cell fits</returns> bool ValidateCell(Cell currentCell) { if (RestrictedDigits(currentCell).Length == 9) return false; ValidDigits(currentCell); return true; }
/// <summary> /// Get the digits not allowed in the current cell /// </summary> /// <param name="currentCell"></param> /// <returns>Invalid digits</returns> string RestrictedDigits(Cell currentCell) { int row = currentCell.Index.Row; int column = currentCell.Index.Column; StringBuilder combination = new StringBuilder(); for (int i = 0; i < 9; i++) { if (combination.ToString().IndexOf(this.Puzzle[row, i].Digit) == -1) combination.Append(this.Puzzle[row, i].Digit); if (combination.ToString().IndexOf(this.Puzzle[i, column].Digit) == -1) combination.Append(this.Puzzle[i, column].Digit); if (i == column) { if (combination.ToString().IndexOf(this.Puzzle[row + CUBE_LOOKUP[row % 3], i + CUBE_LOOKUP[i % 3]].Digit) == -1) combination.Append(this.Puzzle[row + CUBE_LOOKUP[row % 3], i + CUBE_LOOKUP[i % 3]].Digit); if (combination.ToString().IndexOf(this.Puzzle[row + CUBE_LOOKUP[(row % 3) + 3], i + CUBE_LOOKUP[i % 3]].Digit) == -1) combination.Append(this.Puzzle[row + CUBE_LOOKUP[(row % 3) + 3], i + CUBE_LOOKUP[i % 3]].Digit); } if (i == row) { if (combination.ToString().IndexOf(this.Puzzle[i + CUBE_LOOKUP[i % 3], column + CUBE_LOOKUP[(column % 3) + 3]].Digit) == -1) combination.Append(this.Puzzle[i + CUBE_LOOKUP[i % 3], column + CUBE_LOOKUP[(column % 3) + 3]].Digit); if (combination.ToString().IndexOf(this.Puzzle[i + CUBE_LOOKUP[(i % 3) + 3], column + CUBE_LOOKUP[(column % 3) + 3]].Digit) == -1) combination.Append(this.Puzzle[i + CUBE_LOOKUP[(i % 3) + 3], column + CUBE_LOOKUP[(column % 3) + 3]].Digit); } } return currentCell.RestrictedDigits = combination.ToString(); }
/// <summary> /// Create easy puzzle /// </summary> /// <param name="currentCell"></param> void GenerateEasyGrid(Cell currentCell) { string digit; currentCell.IsGiven = true; digit = currentCell.Digit; currentCell.RestrictedDigits = RestrictedDigits(currentCell); if (currentCell.RestrictedDigits.Length == 9) { currentCell.Digit = string.Empty; currentCell.IsGiven = false; } }
/// <summary> /// Get the cell previous to the current cell /// </summary> /// <param name="currentCell"></param> /// <returns>Cell</returns> public Cell PreviousCell(Cell currentCell) { int row = currentCell.Index.Row; int column = currentCell.Index.Column; if (column > 0) return this.Puzzle[row, column - 1]; else return this.Puzzle[row - 1, 8]; }
/// <summary> /// Get the next cell to the current cell /// </summary> /// <param name="currentCell"></param> /// <returns>Cell</returns> public Cell NextCell(Cell currentCell) { int row = currentCell.Index.Row; int column = currentCell.Index.Column; if (column == 8) return this.Puzzle[row + 1, 0]; else return this.Puzzle[row, column + 1]; }
/// <summary> /// Get the next empty cell /// </summary> /// <param name="currentCell"></param> /// <returns>Cell</returns> public Cell GetCell(Cell currentCell) { int row = currentCell.Index.Row; int column = currentCell.Index.Column; if (row == 0 && column == 0) return this.Puzzle[row, column + 1]; if (row == 8 && column == 8) return this.Last; Cell previousCell = PreviousCell(currentCell); if (string.IsNullOrEmpty(previousCell.Digit)) return previousCell; else if (string.IsNullOrEmpty(currentCell.Digit)) return currentCell; else return NextCell(currentCell); }
/// <summary> /// Generate the terminal pattern /// </summary> /// <param name="terminalPattern"></param> /// <returns>Solution</returns> string TerminalPattern(Cell[,] terminalPattern) { StringBuilder solution = new StringBuilder(); for (int row = 0; row < 9; row++) { for (int column = 0; column < 9; column++) { solution.Append(terminalPattern[row, column].Digit); } } return solution.ToString(); }