示例#1
0
        public DTSudokuFrame(DTSudokuDifficultyValue initialDifficulty)
        {
            this.random = new SudokuRandom();

            this.sudokuBoardFrameSection = null;
            this.sudokuDifficultySelectionFrameSection = new DTSudokuDifficultySelectionFrameSection(initialDifficulty);
            this.sudokuNewGameButtonFrameSection       = new DTSudokuNewGameButtonFrameSection();
            this.sudokuLoadingBoardFrameSection        = new DTSudokuLoadingBoardFrameSection(initialDifficulty, this.random);
        }
示例#2
0
        public int[,] SolveForRandomSolution(int[,] board, ISudokuRandom random)
        {
            var solution = this.GetSolutions(board, 1, random);

            if (solution.Count == 0)
            {
                throw new Exception("Undefined behavior - board must have at least one solution");
            }
            return(solution[0]);
        }
示例#3
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;
 }
示例#4
0
        // Given a board, returns up to numSolutions solutions, chosen randomly.
        // If there are less than numSolutions solutions, the returned list's
        // length is the number of solutions the board has.
        private List <int[, ]> GetSolutions(int[,] board, int numSolutions, ISudokuRandom random)
        {
            if (numSolutions == 0)
            {
                return(new List <int[, ]>());
            }

            if (!this.NoConflicts(board))
            {
                return(new List <int[, ]>());
            }

            List <int[, ]> solutions = this.GetSolutionsRecursive(this.CopyBoard(board), numSolutions, random);

            if (solutions == null)
            {
                return(new List <int[, ]>());
            }

            return(solutions);
        }
示例#5
0
        public DTSudokuLoadingBoardFrameSection(DTSudokuDifficultyValue difficulty, ISudokuRandom random)
        {
            SudokuDifficulty sudokuDifficulty;

            if (difficulty == DTSudokuDifficultyValue.Easy)
            {
                sudokuDifficulty = SudokuDifficulty.Easy;
            }
            else if (difficulty == DTSudokuDifficultyValue.Normal)
            {
                sudokuDifficulty = SudokuDifficulty.Normal;
            }
            else if (difficulty == DTSudokuDifficultyValue.Hard)
            {
                sudokuDifficulty = SudokuDifficulty.Hard;
            }
            else
            {
                throw new Exception();
            }

            this.sudokuGenerator = new SudokuGenerator(new RandomizedSudokuSolver(), random);
            this.sudokuGenerator.StartGeneratingSudokuPuzzle(sudokuDifficulty);
        }
示例#6
0
        /*
         *      Unlike this.GetSolutions, this function requires that numSolutions > 0
         *      and that the board has no obvious conflicts. (An obvious conflict is two
         *      duplicate numbers on the same row, column, or 3x3 box.)
         *
         *      Also, unlike this.GetSolutions, if the board has no solutions, this function returns
         *      null instead of an empty list.
         */
        private List <int[, ]> GetSolutionsRecursive(int[,] board, int numSolutions, ISudokuRandom random)
        {
            int xEmpty = -1;
            int yEmpty = -1;

            int numEmptyCells = 0;

            for (int i = 0; i < 9; i++)
            {
                for (int j = 0; j < 9; j++)
                {
                    if (board[i, j] == 0)
                    {
                        xEmpty = i;
                        yEmpty = j;
                        numEmptyCells++;
                    }
                }
            }

            if (xEmpty == -1)
            {
                var list = new List <int[, ]>();
                list.Add(this.CopyBoard(board));
                return(list);
            }

            if (numEmptyCells > 50)
            {
                Tuple <int, int> mostConstrainedEmptyCell = this.GetMostConstrainedEmptyCell(board);
                xEmpty = mostConstrainedEmptyCell.Item1;
                yEmpty = mostConstrainedEmptyCell.Item2;
            }

            bool[] potentialValues = new bool[]
            {
                true,
                true, true, true,
                true, true, true,
                true, true, true
            };

            for (int i = 0; i < 9; i++)
            {
                int num = board[i, yEmpty];
                if (num != 0)
                {
                    potentialValues[num] = false;
                }
            }

            for (int j = 0; j < 9; j++)
            {
                int num = board[xEmpty, j];
                if (num != 0)
                {
                    potentialValues[num] = false;
                }
            }

            int boxX = (xEmpty / 3) * 3;
            int boxY = (yEmpty / 3) * 3;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    int num = board[boxX + i, boxY + j];
                    if (num != 0)
                    {
                        potentialValues[num] = false;
                    }
                }
            }

            if (!potentialValues[1] &&
                !potentialValues[2] &&
                !potentialValues[3] &&
                !potentialValues[4] &&
                !potentialValues[5] &&
                !potentialValues[6] &&
                !potentialValues[7] &&
                !potentialValues[8] &&
                !potentialValues[9])
            {
                return(null);
            }

            List <int> valuesToTry = new List <int>();

            for (int x = 1; x <= 9; x++)
            {
                if (potentialValues[x])
                {
                    valuesToTry.Add(x);
                }
            }

            List <int[, ]> solutions = null;

            while (valuesToTry.Count > 0)
            {
                int nextIndex = random != null?random.NextInt(valuesToTry.Count) : 0;

                int nextValueToTry = valuesToTry[nextIndex];
                valuesToTry.RemoveAt(nextIndex);

                board[xEmpty, yEmpty] = nextValueToTry;

                int numSolutionsNeeded = numSolutions - (solutions != null ? solutions.Count : 0);

                List <int[, ]> subsolutions = this.GetSolutionsRecursive(board, numSolutionsNeeded, random);

                if (subsolutions != null)
                {
                    if (solutions == null)
                    {
                        solutions = subsolutions;
                    }
                    else
                    {
                        foreach (int[,] subsolution in subsolutions)
                        {
                            solutions.Add(subsolution);
                        }
                    }
                }

                if (solutions != null && solutions.Count == numSolutions)
                {
                    board[xEmpty, yEmpty] = 0;
                    return(solutions);
                }
            }

            board[xEmpty, yEmpty] = 0;
            return(solutions);
        }