示例#1
0
 public SudokuBoard(IEnumerable <Cell> cells, SudokuDifficulty difficulty = SudokuDifficulty.None) : this(difficulty)
 {
     foreach (var cell in cells)
     {
         this[cell.Row, cell.Col] = cell.Val;
     }
 }
        /// <summary>
        /// Generates a new <see cref="SudokuPuzzle"/> by filling it with numbers and then removing numbers according to <c><paramref name="difficulty"/></c>.
        /// </summary>
        /// <param name="size">The number of elements that the new <see cref="SudokuPuzzle"/> can store in each row, column and block.</param>
        /// <param name="difficulty">The difficulty associated with the <see cref="SudokuPuzzle"/>.</param>
        /// <returns>A new <see cref="SudokuPuzzle"/>.</returns>
        /// <exception cref="ArgumentException"><c><paramref name="size"/></c> is not a positive, square integer - or - <c><paramref name="difficulty"/></c> is equal to <see cref="SudokuDifficulty.None"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><c><paramref name="size"/></c> is less than or equal to 0 or greater than <see cref="SudokuPuzzle.MaximumSupportedSize"/>.</exception>
        public static SudokuPuzzle Generate(int size, SudokuDifficulty difficulty)
        {
            SudokuPuzzle sudoku = SudokuGenerator.AddNumbers(size, difficulty);

            SudokuGenerator.RemoveNumbers(sudoku);
            return(sudoku);
        }
示例#3
0
        public void StartGeneratingSudokuPuzzle(SudokuDifficulty difficulty)
        {
            int[,] solvedBoard = this.solver.SolveForRandomSolution(new int[9, 9], this.random);

            Func <int[, ], int[, ]> copyBoard = board =>
            {
                var newBoard = new int[9, 9];
                for (int i = 0; i < 9; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        newBoard[i, j] = board[i, j];
                    }
                }

                return(newBoard);
            };

            this.numRemoved = 0;
            this.numTries   = 0;

            this.currentPuzzle = copyBoard(solvedBoard);

            this.isDone = false;

            this.difficulty = difficulty;

            this.cellsThatCannotBeRemoved = new List <Tuple <int, int> >();
        }
示例#4
0
 public SudokuBoard(SudokuDifficulty difficulty = SudokuDifficulty.None)
 {
     Difficulty = difficulty;
     _grid      = Enumerable.Range(0, SIZE)
                  .Select(_ => new int[SIZE])
                  .ToArray();
 }
示例#5
0
        private void SolveSudoku(object sender, RoutedEventArgs e)
        {
            var sudokuSolver    = new SudokuDifficulty();
            var sudokuValidator = new SudokuSolver();
            var sudokuToSolve   = new SudokuCell[9, 9];

            var counter = 0;

            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    var textBox = this.FindName("TextBox" + counter) as TextBox;
                    sudokuToSolve[row, col] = new SudokuCell(row, col);
                    if (textBox.Text != string.Empty)
                    {
                        sudokuToSolve[row, col].Value = int.Parse(textBox.Text);
                    }
                    counter++;
                }
            }

            if (lastSudokuDifficulty == 0)
            {
                MessageBox.Show("You must first generate a sudoku!");
                return;
            }

            if (!sudokuValidator.CheckIfSudokuIsValid(sudokuToSolve))
            {
                MessageBox.Show("This sudoku is not valid! Please check for errors!", "Warning");
                return;
            }

            try
            {
                sudokuToSolve = sudokuSolver.SolveSudoku(sudokuToSolve);
            }
            catch (ArgumentException)
            {
                MessageBox.Show("This sudoku is not valid! Please check for errors!", "Warning");
                return;
            }

            counter = 0;

            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    var textBox = this.FindName("TextBox" + counter) as TextBox;
                    textBox.Text      = string.Empty;
                    textBox.Text      = sudokuToSolve[row, col].Value.ToString();
                    textBox.IsEnabled = false;
                    counter++;
                }
            }
            stopWatch.Stop();
        }
示例#6
0
        private void EnterTextBox(object sender, MouseEventArgs e)
        {
            ColorAnimation animation = new ColorAnimation();
            var            textBox   = sender as TextBox;

            var sudokuDifficulty = new SudokuDifficulty();
            var sudoku           = new SudokuCell[9, 9];

            if ((FindName("checkBoxHints") as CheckBox).IsChecked == true)
            {
                if (textBox.IsReadOnly == false && lastSudokuDifficulty != 0 && textBox.Text == string.Empty)
                {
                    try
                    {
                        var counter  = 0;
                        var inputRow = 0;
                        var inputCol = 0;
                        for (int row = 0; row < 9; row++)
                        {
                            for (int col = 0; col < 9; col++)
                            {
                                var box = this.FindName("TextBox" + counter) as TextBox;
                                sudoku[row, col] = new SudokuCell(row, col);
                                if (box.Text != string.Empty)
                                {
                                    sudoku[row, col].Value = int.Parse(box.Text);
                                }
                                if ("TextBox" + counter == textBox.Name)
                                {
                                    inputCol = col;
                                    inputRow = row;
                                }
                                counter++;
                            }
                        }
                        var outputList = sudokuDifficulty.GetAllPossibleNumbers(inputRow, inputCol, sudoku).PossibleValues;

                        var result = string.Join(" ", outputList);

                        var toolTip = new ToolTip();
                        toolTip.Background = new SolidColorBrush(Color.FromRgb(255, 250, 252));
                        toolTip.Content    = string.Format("You can put those numbers: {0}!", result);
                        textBox.ToolTip    = toolTip;
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
            }



            animation.To       = Color.FromRgb(227, 232, 234);
            animation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
            textBox.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
        }
示例#7
0
        public static SudokuBoard NewSudoku(SudokuDifficulty difficulty, ISudokuSolver solverGenerator = null)
        {
            _solverGenerator = solverGenerator ?? new DeepFirstSearchSolver();

            var blankboard = new SudokuBoard(difficulty);

            return(_solverGenerator
                   .Solve(blankboard)
                   .CreateBlankCells());
        }
示例#8
0
 public SudokuGenerator(IRandomizedSudokuSolver s, ISudokuRandom r)
 {
     this.solver                   = s;
     this.random                   = r;
     this.currentPuzzle            = null;
     this.numRemoved               = -1;
     this.numTries                 = -1;
     this.isDone                   = false;
     this.difficulty               = SudokuDifficulty.Easy;
     this.cellsThatCannotBeRemoved = null;
 }
        /// <summary>
        /// Creates a new <see cref="SudokuPuzzle"/> and fills it with numbers.
        /// </summary>
        /// <param name="size">The number of elements that the new <see cref="SudokuPuzzle"/> can store in each row, column and block.</param>
        /// <param name="difficulty">The difficulty associated with the <see cref="SudokuPuzzle"/>.</param>
        /// <returns>A new <see cref="SudokuPuzzle"/> filled with numbers.</returns>
        /// <exception cref="ArgumentException"><c><paramref name="size"/></c> is not a positive, square integer - or - <c><paramref name="difficulty"/></c> is equal to <see cref="SudokuDifficulty.None"/>.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><c><paramref name="size"/></c> is less than or equal to 0 or greater than <see cref="SudokuPuzzle.MaximumSupportedSize"/>.</exception>
        public static SudokuPuzzle AddNumbers(int size, SudokuDifficulty difficulty)
        {
            if (difficulty == SudokuDifficulty.None)
            {
                throw new ArgumentException(nameof(difficulty));
            }

            SudokuPuzzle sudoku = new SudokuPuzzle(size, difficulty);

            SudokuGenerator.AddNumbers(sudoku);
            return(sudoku);
        }
        /// <summary>
        /// Parses the text representing a single <see cref="SudokuPuzzle"/>.
        /// </summary>
        /// <param name="s">The text to parse.</param>
        /// <returns>A <see cref="SudokuPuzzle"/> representation of <c><paramref name="s"/></c>.</returns>
        /// <exception cref="ArgumentNullException"><c><paramref name="s"/></c> is <c>null</c>.</exception>
        /// <exception cref="FormatException"><c><paramref name="s"/></c> is not in the correct format.</exception>
        public static SudokuPuzzle Deserialize(String s)
        {
            if (s is null)
            {
                throw new ArgumentNullException(nameof(s));
            }

            String[] split = s.Split(',');

            if (split.Length != 5)
            {
                throw new FormatException();
            }

            try
            {
                int size    = Int32.Parse(split[0]);
                int squared = size * size;

                if (!SudokuPuzzle.VerifySize(size))
                {
                    throw new FormatException();
                }

                SudokuDifficulty difficulty = (SudokuDifficulty)Enum.Parse(typeof(SudokuDifficulty), split[1], true);
                int[]            numbers    = new int[squared], solutions = new int[squared];
                bool[]           readOnly   = new bool[squared];

                if (split[2].Length != squared || split[3].Length != squared || split[4].Length != squared)
                {
                    throw new FormatException();
                }

                for (int i = 0; i < squared; i++)
                {
                    numbers[i]   = split[2][i] - '0';
                    solutions[i] = split[3][i] - '0';
                    readOnly[i]  = split[3][i] == '1';
                }

                SudokuPuzzle puzzle = SudokuPuzzle.Parse(size, difficulty, numbers, solutions, readOnly);
                puzzle.ResetPossible();
                return(puzzle);
            }

            catch
            {
                throw new FormatException();
            }
        }
示例#11
0
        internal static SudokuPuzzle Parse(int size, SudokuDifficulty difficulty, int[] numbers, int[] solutions, bool[] readOnly)
        {
            SudokuPuzzle puzzle = new SudokuPuzzle(size, difficulty);

            for (int i = 0; i < size; i++)
            {
                int row = i * size;

                for (int j = 0; j < size; j++)
                {
                    int        index = row + j;
                    SudokuCell cell  = puzzle.Cells[i, j];
                    cell.Number     = numbers[index];
                    cell.Solution   = solutions[index];
                    cell.IsReadOnly = readOnly[index];
                }
            }

            return(puzzle);
        }
示例#12
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SudokuPuzzle"/> class that is empty and has the specified <c><paramref name="size"/></c> and <c><paramref name="difficulty"/></c>.
        /// </summary>
        /// <param name="size">The number of elements that the new sudoku can store in each row, column and block.</param>
        /// <param name="difficulty">The difficulty associated with the <see cref="SudokuPuzzle"/>.</param>
        /// <exception cref="ArgumentException"><c><paramref name="size"/></c> is not a positive, square integer.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><c><paramref name="size"/></c> is less than or equal to 0 or greater than <see cref="SudokuPuzzle.MaximumSupportedSize"/>.</exception>
        public SudokuPuzzle(int size, SudokuDifficulty difficulty)
        {
            if (size <= 0 || size > SudokuPuzzle.MaximumSupportedSize)
            {
                throw new ArgumentOutOfRangeException(nameof(size));
            }

            if (!MathExtensions.IsSquare((ulong)size))
            {
                throw new ArgumentException(nameof(size));
            }

            this.LockObject      = new Object();
            this._Changed        = null;
            this.Cells           = new SudokuCell[size, size];
            this.Difficulty      = difficulty;
            this.DisablePossible = false;
            int[] numbers = new int[size];

            for (int i = 0; i < size; i++)
            {
                numbers[i] = i + 1;
            }

            for (int i = 0; i < size; i++)
            {
                for (int j = 0; j < size; j++)
                {
                    this.Cells[i, j] = new SudokuCell();

                    foreach (int number in numbers)
                    {
                        this.Cells[i, j].AddPossible(number);
                    }
                }
            }

            this.Size      = size;
            this.BlockSize = (int)Math.Sqrt(size);
        }
示例#13
0
        /// <summary>
        /// Converts the string representation to its <see cref="SudokuPuzzle"/> equivalent.
        /// </summary>
        /// <param name="s">A string containing a puzzle to convert.</param>
        /// <param name="difficulty">An optional difficulty to associate with the <see cref="SudokuPuzzle"/>.</param>
        /// <returns>A <see cref="SudokuPuzzle"/> equivalent to the puzzle contained in <c><paramref name="s"/></c>.</returns>
        /// <exception cref="ArgumentNullException"><c><paramref name="s"/></c> is <c>null</c>.</exception>
        /// <exception cref="FormatException"><c><paramref name="s"/></c> is not in the correct format.</exception>
        public static SudokuPuzzle Parse(String s, SudokuDifficulty difficulty = SudokuDifficulty.None)
        {
            if (s is null)
            {
                throw new ArgumentNullException(nameof(s));
            }

            s = Regex.Replace(s, @"[^0-9]", "");
            int size = (int)Math.Sqrt(s.Length);

            if (!SudokuPuzzle.VerifySize(size))
            {
                throw new FormatException();
            }

            SudokuPuzzle sudoku;

            try
            {
                sudoku = new SudokuPuzzle(size, difficulty);
            }

            catch
            {
                throw new FormatException();
            }

            for (int i = 0; i < size; i++)
            {
                int currentRow = i * size;

                for (int j = 0; j < size; j++)
                {
                    sudoku[i, j] = s[currentRow + j] - '0';
                }
            }

            return(sudoku);
        }
示例#14
0
        private void CheckIfSudokuIsValid(object sender, RoutedEventArgs e)
        {
            var sudokuSolver    = new SudokuDifficulty();
            var sudokuValidator = new SudokuSolver();
            var sudokuToSolve   = new SudokuCell[9, 9];

            var counter = 0;

            for (int row = 0; row < 9; row++)
            {
                for (int col = 0; col < 9; col++)
                {
                    var textBox = this.FindName("TextBox" + counter) as TextBox;
                    sudokuToSolve[row, col] = new SudokuCell(row, col);
                    if (textBox.Text != string.Empty)
                    {
                        sudokuToSolve[row, col].Value = int.Parse(textBox.Text);
                    }
                    counter++;
                }
            }

            if (lastSudokuDifficulty == 0)
            {
                MessageBox.Show("You must first generate a sudoku!");
                return;
            }

            if (!sudokuValidator.CheckIfSudokuIsValid(sudokuToSolve))
            {
                var inputCells = new bool[9, 9];
                var sudoku     = new SudokuCell[9, 9];

                counter = 0;
                for (int row = 0; row < 9; row++)
                {
                    for (int col = 0; col < 9; col++)
                    {
                        var element = this.FindName("TextBox" + counter) as TextBox;
                        int number;
                        var isParsed = int.TryParse(element.Text, out number);
                        sudoku[row, col] = new SudokuCell(row, col);
                        if (isParsed && element.IsReadOnly == false)
                        {
                            sudoku[row, col].Value = number;
                        }
                        else
                        {
                            sudoku[row, col].Value = number;
                            inputCells[row, col]   = true;
                        }
                        counter++;
                    }
                }

                var listWithCellsWithError = sudokuSolver.GetAllCellsWithError(sudoku, inputCells);

                ColorTheCellsWithError(listWithCellsWithError);

                MessageBox.Show("You have some errors!");
                return;
            }

            try
            {
                sudokuToSolve = sudokuSolver.SolveSudoku(sudokuToSolve);
            }
            catch (ArgumentException)
            {
                var inputCells = new bool[9, 9];
                var sudoku     = new SudokuCell[9, 9];

                counter = 0;
                for (int row = 0; row < 9; row++)
                {
                    for (int col = 0; col < 9; col++)
                    {
                        var element = this.FindName("TextBox" + counter) as TextBox;
                        int number;
                        var isParsed = int.TryParse(element.Text, out number);
                        sudoku[row, col] = new SudokuCell(row, col);
                        if (isParsed && element.IsReadOnly == false)
                        {
                            sudoku[row, col].Value = number;
                        }
                        else
                        {
                            sudoku[row, col].Value = number;
                            inputCells[row, col]   = true;
                        }
                        counter++;
                    }
                }

                var listWithCellsWithError = sudokuSolver.GetAllCellsWithError(sudoku, inputCells, false);

                ColorTheCellsWithError(listWithCellsWithError);
                MessageBox.Show("You have some errors!");
                return;
            }

            MessageBox.Show("You are doing great!");
        }
示例#15
0
 public SudokuBoard(IEnumerable <int> values, SudokuDifficulty difficulty = SudokuDifficulty.None)
     : this(GetCellsFromValues(values), difficulty)
 {
 }