public void SolvesSudokus()
        {
            SudokuPuzzle unsolved = SudokuPuzzle.CreateFromStream(GetStreamFromFileName(GOODSINGLEPUZZLEFILE));
            //One more time!
            SudokuPuzzle unsolved2 = SudokuPuzzle.CreateFromStream(GetStreamFromFileName(GOODSINGLEPUZZLEFILE));

            Assert.IsFalse(unsolved.IsSolved());
            SudokuPuzzle solved = new SudokuPuzzle("Solved1")
            {
                PuzzleMatrix = new int[][]
                {
                    new int[] { 4, 8, 3, 9, 2, 1, 6, 5, 7 },
                    new int[] { 9, 6, 7, 3, 4, 5, 8, 2, 1 },
                    new int[] { 2, 5, 1, 8, 7, 6, 4, 9, 3 },
                    new int[] { 5, 4, 8, 1, 3, 2, 9, 7, 6 },
                    new int[] { 7, 2, 9, 5, 6, 4, 1, 3, 8 },
                    new int[] { 1, 3, 6, 7, 9, 8, 2, 4, 5 },
                    new int[] { 3, 7, 2, 6, 8, 9, 5, 1, 4 },
                    new int[] { 8, 1, 4, 2, 5, 3, 7, 6, 9 },
                    new int[] { 6, 9, 5, 4, 1, 7, 3, 8, 2 },
                }
            };
            SudokuRoot totest = new SudokuRoot();

            totest.SolveSudoku(unsolved);
            totest.SolveSudoku(unsolved2);
            Assert.IsTrue(unsolved.IsSolved());
            Assert.IsTrue(unsolved2.IsSolved());
        }
        public void TestPuzzleIsSolved()
        {
            int        dimension  = 3;
            List <int> cellValues = new List <int>();

            // Test a row
            for (int i = 0; i < dimension * dimension * dimension * dimension; ++i)
            {
                cellValues.Add(0);
            }

            SudokuPuzzle puzzle = new SudokuPuzzle(dimension, cellValues);

            Assert.IsFalse(puzzle.IsSolved());

            for (int i = 0; i < puzzle.Rows.Count; ++i)
            {
                for (int k = 0; k < puzzle.Rows[i].Count; ++k)
                {
                    puzzle.Rows[i][k].RemoveAllExcept(1);
                }
            }

            Assert.IsTrue(puzzle.IsSolved());
        }
        /// <summary>
        /// Solves the given <see cref="SudokuPuzzle"/>
        /// </summary>
        /// <param name="puzzle">The <see cref="SudokuPuzzle"/> being solved</param>
        /// <returns>A list of <see cref="SudokuPuzzle"/>s that are solutions to the given <see cref="SudokuPuzzle"/></returns>
        public List <SudokuPuzzle> Solve(SudokuPuzzle puzzle)
        {
            List <SudokuPuzzle>  solutions   = new List <SudokuPuzzle>();
            Stack <SudokuPuzzle> puzzleStack = new Stack <SudokuPuzzle>();

            puzzleStack.Push(puzzle.Clone());

            while (puzzleStack.Count > 0)
            {
                try
                {
                    SudokuPuzzle puzzleToSolve = puzzleStack.Pop();
                    if (puzzle.IsValid())
                    {
                        bool puzzleAdvanced = false;
                        do
                        {
                            puzzleAdvanced = false;
                            for (int i = 0; i < this.strategies.Count; ++i)
                            {
                                while (this.strategies[i].AdvancePuzzle(puzzleToSolve))
                                {
                                    puzzleAdvanced = true;
                                }
                            }
                        }while (puzzleAdvanced);

                        if (puzzleToSolve.IsSolved() && puzzleToSolve.IsValid())
                        {
                            solutions.Add(puzzleToSolve);
                            if (solutions.Count > 1)
                            {
                                break;
                            }
                        }
                        else
                        {
                            foreach (SudokuPuzzle guess in this.Guess(puzzleToSolve))
                            {
                                puzzleStack.Push(guess);
                            }
                        }
                    }
                }
                catch (Exception)
                {
                }
            }

            return(solutions);
        }
        private bool SolvePuzzle(SudokuPuzzle sudokuPuzzle)
        {
            if (sudokuPuzzle.IsSolved())
            {
                return(true);
            }

            var unsolvedCells = sudokuPuzzle.Cells.OfType <Cell>().Where(x => !x.HasValue).OrderBy(x => x.CanBe.Count).ToArray();

            // for each cell
            foreach (var cell in unsolvedCells)
            {
                var row        = sudokuPuzzle.Rows[cell.RowIndex];
                var column     = sudokuPuzzle.Columns[cell.ColumnIndex];
                var blockIndex = sudokuPuzzle.GetBlockIndex(cell);
                var block      = sudokuPuzzle.Blocks[blockIndex.RowIndex, blockIndex.ColumnIndex];

                var potentialCellValues = new List <int>(cell.CanBe);

                // for each potential value
                foreach (var value in potentialCellValues)
                {
                    var usedInRow    = row.Cells.Count(x => x.Value == value) > 0;
                    var usedInColumn = column.Cells.Count(x => x.Value == value) > 0;
                    var usedInBlock  = block.Cells.OfType <Cell>().Count(x => x.Value == value) > 0;

                    // if potential value already used in row, column or block, skip it
                    if (usedInRow || usedInColumn || usedInBlock)
                    {
                        continue;
                    }

                    // try to recursively solve the puzzle
                    cell.Value = value;
                    if (SolvePuzzle(sudokuPuzzle))
                    {
                        return(true);
                    }
                    // if puzzle cannot be solve, revert the value
                    else
                    {
                        cell.Value = 0;
                        cell.CanBe.AddRange(potentialCellValues);
                    }
                }
                return(false);
            }
            return(false);
        }
        /// <inheritdoc />
        public SudokuPuzzle Solve(int[,] sudoku)
        {
            var sudokuPuzzle = new SudokuPuzzle(sudoku);

            while (!sudokuPuzzle.IsSolved())
            {
                var solution = SolveSingleStep(sudokuPuzzle);
                if (solution == null)
                {
                    // Sudoku cannot be solved :(
                    sudokuPuzzle = _sudokuPuzzleAfterFailedSolveSingleStep;
                    break;
                }
                else
                {
                    sudokuPuzzle.ApplySingleStepSolution(solution);
                    _sudokuPuzzleAfterFailedSolveSingleStep = sudokuPuzzle;
                }
            }

            return(sudokuPuzzle);
        }
        public void IsSolvedIsCorrect()
        {
            SudokuPuzzle unsolved = SudokuPuzzle.CreateFromStream(GetStreamFromFileName(GOODSINGLEPUZZLEFILE));

            Assert.IsFalse(unsolved.IsSolved());
            SudokuPuzzle solved = new SudokuPuzzle("Solved1")
            {
                PuzzleMatrix = new int[][]
                {
                    new int[] { 4, 8, 3, 9, 2, 1, 6, 5, 7 },
                    new int[] { 9, 6, 7, 3, 4, 5, 8, 2, 1 },
                    new int[] { 2, 5, 1, 8, 7, 6, 4, 9, 3 },
                    new int[] { 5, 4, 8, 1, 3, 2, 9, 7, 6 },
                    new int[] { 7, 2, 9, 5, 6, 4, 1, 3, 8 },
                    new int[] { 1, 3, 6, 7, 9, 8, 2, 4, 5 },
                    new int[] { 3, 7, 2, 6, 8, 9, 5, 1, 4 },
                    new int[] { 8, 1, 4, 2, 5, 3, 7, 6, 9 },
                    new int[] { 6, 9, 5, 4, 1, 7, 3, 8, 2 },
                }
            };

            Assert.IsTrue(solved.IsSolved());
        }
        /// <inheritdoc />
        public SingleStepSolution SolveSingleStep(SudokuPuzzle sudokuPuzzle)
        {
            if (sudokuPuzzle.IsSolved())
            {
                return(null);
            }

            foreach (var strategy in _strategies)
            {
                var elimination = _basicElimination.SolveSingleStep(sudokuPuzzle);
                if (elimination != null)
                {
                    return(elimination);
                }

                var solution = strategy.SolveSingleStep(sudokuPuzzle);
                if (solution != null)
                {
                    return(solution);
                }
            }

            return(null);
        }