Exemplo n.º 1
0
        /// <summary>
        /// checks for if the puzzle is valid in the sense that is has more than 7 unique numbers at any point in the puzzle, more than 16 givens, and one solution
        /// </summary>
        /// <param name="grid"></param>
        /// <returns></returns>
        public bool CheckValidity(SudokuGrid grid)
        {
            bool        minOfEight = false;
            int         givens     = 0;
            List <char> numList    = new List <char> {
                '1', '2', '3', '4', '5', '6', '7', '8', '9'
            };

            for (int x = 0; x < 9; x++)
            {
                for (int y = 0; y < 9; y++)
                {
                    if (grid.Cells[x][y].Num != '0')
                    {
                        numList.Remove(grid.Cells[x][y].Num);
                        if (numList.Count <= 1)
                        {
                            minOfEight = true;
                        }
                        givens++;
                    }
                }
            }
            if (!minOfEight || givens < 17)
            {
                return(false);
            }
            char[][] sudokuArray = new char[9][] { new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9] };
            for (int r = 0; r < 9; r++)
            {
                for (int c = 0; c < 9; c++)
                {
                    sudokuArray[r][c] = grid.Cells[r][c].Num;
                }
            }
            PuzzleSolverAdvDS solve = new PuzzleSolverAdvDS();

            if (solve.CompileBacktracker(grid, 4))
            {
                string firstSol = GridToString(grid);
                grid = RestartPuzzle(grid, sudokuArray);
                if (solve.CompileBacktracker(grid, 1))
                {
                    string secSol = GridToString(grid);
                    if (firstSol == secSol)//valid puzzle
                    {
                        grid = RestartPuzzle(grid, sudokuArray);
                        return(true);
                    }
                    else
                    {
                        grid = RestartPuzzle(grid, sudokuArray);
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <returns>the puzzle in form of SudokuGrid</returns>
        public SudokuGrid Setter()
        {
            PuzzleSolverAdvDS solve = new PuzzleSolverAdvDS();
            SudokuGrid        grid  = ConstructGrid();
            //Using Backtracking Solver to fill in a blank grid to get a starting solution - possibly the part of the generator that causes performance issues
            bool testing = false;//testing condition

            if (!testing)
            {
                try
                {
                    if (!solve.CompileBacktracker(grid, 2))
                    {
                        MessageBox.Show("Generator did not find a puzzle to generate");
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Something has gone terribly wrong...\r\nError: " + ex);
                    return(grid);
                }
            }
            else
            {
                #region Manual Testing Puzzle
                StringToGrid(grid, "600438079900705080800000032200004060000000000040600003180000005070806001560941008");
                #endregion
            }
            RemoveNumbers(grid, solve);
            return(grid);
        }
Exemplo n.º 3
0
        public void RemoveNumbers(SudokuGrid grid, PuzzleSolverAdvDS solve)
        {
            ///This section consists of constantly removing parallel numbers, e.g. [0,0] and [8,8] or [2,5] and [5,2], and checking if the puzzle is still valid (i.e. still has only one solution)

            int           removed      = 0;
            List <string> cellsChecked = new List <string>(81);
            List <int>    rowList      = new List <int> {
                0, 1, 2, 3, 4, 5, 6, 7, 8
            };
            List <int> colList = new List <int> {
                0, 1, 2, 3, 4, 5, 6, 7, 8
            };

            rowList = Shuffler_intList(rowList);
            colList = Shuffler_intList(colList);
            foreach (int row in rowList)
            {
                if (removed >= g_MaxRemoves)
                {
                    break;
                }
                foreach (int col in colList)
                {
                    if (removed >= g_MaxRemoves)
                    {
                        break;
                    }
                    if (!cellsChecked.Contains(row.ToString() + col.ToString()))
                    {
                        int altRow = NumberSwitch(row);
                        int altCol = NumberSwitch(col);

                        if (grid.Cells[altRow][altCol].Num != '0' && grid.Cells[row][col].Num != '0')
                        {
                            bool        valid   = false;
                            List <char> numList = new List <char> {
                                '1', '2', '3', '4', '5', '6', '7', '8', '9'
                            };
                            for (int x = 0; x < 9 && !valid; x++)//checks for if the puzzle is valid in the sense that is has more than 7 unique numbers at any point in the puzzle
                            {
                                for (int y = 0; y < 9 && !valid; y++)
                                {
                                    if (grid.Cells[x][y].Num != '0')
                                    {
                                        if ((x == altRow && y == altCol) == false && (x == row && y == col) == false)
                                        {
                                            numList.Remove(grid.Cells[x][y].Num);
                                        }
                                        if (numList.Count <= 1)
                                        {
                                            valid = true;
                                        }
                                    }
                                }
                            }
                            if (valid)
                            {
                                char[][] sudokuArray = new char[9][] { new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9] };
                                for (int r = 0; r < 9; r++)
                                {
                                    for (int c = 0; c < 9; c++)
                                    {
                                        sudokuArray[r][c] = grid.Cells[r][c].Num;
                                    }
                                }
                                grid.Cells[row][col].Num       = '0';
                                grid.Cells[altRow][altCol].Num = '0';
                                if (solve.CompileBacktracker(grid, 4))
                                {
                                    string firstSol = GridToString(grid);
                                    grid = RestartPuzzle(grid, sudokuArray);
                                    grid.Cells[row][col].Num       = '0';
                                    grid.Cells[altRow][altCol].Num = '0';
                                    if (solve.CompileBacktracker(grid, 1))//tries Backtracking algorithm using reversed candidate lists so that if a solution that is different to the previous solution exists, it will be found, invalidating the puzzle
                                    {
                                        string secSol = GridToString(grid);
                                        if (firstSol == secSol)//valid puzzle
                                        {
                                            grid = RestartPuzzle(grid, sudokuArray);
                                            grid.Cells[row][col].Num       = '0';
                                            grid.Cells[altRow][altCol].Num = '0';
                                            if (grid.Cells[row][col] == grid.Cells[altRow][altCol])
                                            {
                                                removed++;
                                            }
                                            else
                                            {
                                                removed += 2;
                                            }
                                        }
                                        else//Multiple solutions
                                        {
                                            grid = RestartPuzzle(grid, sudokuArray);
                                        }
                                    }
                                }
                                else//Invalid puzzle, should never occur
                                {
                                    grid = RestartPuzzle(grid, sudokuArray);
                                }
                            }
                            if (grid.Cells[row][col] == grid.Cells[altRow][altCol])
                            {
                                cellsChecked.Add(row.ToString() + col.ToString());
                            }
                            else
                            {
                                cellsChecked.Add(row.ToString() + col.ToString());
                                cellsChecked.Add(altRow.ToString() + altCol.ToString());
                            }
                        }
                    }
                }
            }
            if (removed < g_MaxRemoves)
            {
                cellsChecked = new List <string>();
                foreach (int row in rowList)
                {
                    if (removed >= g_MaxRemoves)
                    {
                        break;
                    }
                    foreach (int col in colList)
                    {
                        if (removed >= g_MaxRemoves)
                        {
                            break;
                        }
                        if (!cellsChecked.Contains(row.ToString() + col.ToString()))
                        {
                            if (grid.Cells[row][col].Num != '0')
                            {
                                bool        valid   = false;
                                List <char> numList = new List <char> {
                                    '1', '2', '3', '4', '5', '6', '7', '8', '9'
                                };
                                for (int x = 0; x < 9 && !valid; x++)//checks for if the puzzle is valid in the sense that is has more than 7 unique numbers at any point in the puzzle
                                {
                                    for (int y = 0; y < 9 && !valid; y++)
                                    {
                                        if (grid.Cells[x][y].Num != '0')
                                        {
                                            if ((x == row && y == col) == false)
                                            {
                                                numList.Remove(grid.Cells[x][y].Num);
                                            }
                                            if (numList.Count <= 1)
                                            {
                                                valid = true;
                                            }
                                        }
                                    }
                                }
                                if (valid)
                                {
                                    char[][] sudokuArray = new char[9][] { new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9], new char[9] };
                                    for (int r = 0; r < 9; r++)
                                    {
                                        for (int c = 0; c < 9; c++)
                                        {
                                            sudokuArray[r][c] = grid.Cells[r][c].Num;
                                        }
                                    }
                                    grid.Cells[row][col].Num = '0';
                                    if (solve.CompileBacktracker(grid, 4))
                                    {
                                        string firstSol = GridToString(grid);
                                        grid = RestartPuzzle(grid, sudokuArray);
                                        grid.Cells[row][col].Num = '0';
                                        if (solve.CompileBacktracker(grid, 1))
                                        {
                                            string secSol = GridToString(grid);
                                            if (firstSol == secSol)//valid puzzle
                                            {
                                                grid = RestartPuzzle(grid, sudokuArray);
                                                grid.Cells[row][col].Num = '0';
                                                removed++;
                                            }
                                            else
                                            {
                                                grid = RestartPuzzle(grid, sudokuArray);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        grid = RestartPuzzle(grid, sudokuArray);
                                    }
                                }
                            }
                            cellsChecked.Add(row.ToString() + col.ToString());
                        }
                    }
                }
            }
        }