예제 #1
0
 /// <summary>
 /// FillSingleChoices iterates through empty cells. For any empty cell
 /// with only one possible value, it fills in that value.
 /// </summary>
 /// <param name="grid">Current state of grid</param>
 private void FillSingleChoices(PuzzleGrid grid)
 {
     bool anyChanges = false;                    //Set if cell value set
     int numChoices;                           //Number of choices found
     do            //While changes have been made AND grid is not solved
     {
         anyChanges = false;
         for (int i = 0; i < 9; i++)         //Iterate through every row
         {
             for (int j = 0; j < 9; j++)  //Iterate through every column
             {
                 if (grid.Grid[i, j] == 0)
                 {       //Get number of choices available in grid[i, j]
                     numChoices = ListPossible(i, j, grid);
                     if (numChoices == 1) //If only one choice set value
                     {
                         grid.UserSetCell(i, j, FirstTrue());
                                       //Changes made, anyChanges = true
                         anyChanges = (grid.Grid[i, j] != 0);
                     }
                 }
             }
         }
     } while(anyChanges == true && !IsSolved(grid));
 }
예제 #2
0
        /// <summary>
        /// SolveGrid attempts to solve a puzzle by checking through all
        /// possible values for each cell, discarding values that do not lead
        /// to a valid solution. On a try, it recursively calls itself to
        /// maintain previous states of the grid to back track to if the
        /// current path fails. It creates a local version of the grid to
        /// facilitate this. It also checks if the puzzle is uniquely solvable.
        /// </summary>
        /// <param name="g">Current state of the grid</param>
        /// <param name="checkUnique">Do we care if it has unique soln?</param>
        /// <returns></returns>
        public bool SolveGrid(PuzzleGrid g, bool checkUnique)
        {
            PuzzleGrid grid = new PuzzleGrid();
            grid = (PuzzleGrid)g.Clone();                 //Copy the input grid
            int i, choice, r, c, numChoices;
            bool done, got_one, solved, result;
            got_one = false;
            recursions++;
            FillSingleChoices(grid);  //First, fill in all single choice values
            if (IsSolved(grid))                        //If it's already solved
            {
                if (numSolns > 0)               //If another soln already found
                {
                    stoplooking = true;                   //Don't look for more
                    result = false;              //Return false, no UNIQUE soln
                }
                else                               //If no other soln found yet
                {
                    numSolns++;
                    final[numSolns] = (PuzzleGrid)g.Clone();  //Save found soln
                    result = true;
                    SolutionGrid = grid;
                }
            }
            else                                            //If not solved yet
            {
                if (!FindFewestChoices(grid, out r, out c, out numChoices))
                {
                    result = false;                          //Invalid solution
                }
                else                                 //Current grid still valid
                {
                    i = 1;
                    done = false;
                    got_one = false;
                    while (!done && i <= numChoices)
                    {
                        choice = PickOneTrue();         //Pick a possible value
                        list[choice] = false;      //Won't want to use it again
                        grid.UserSetCell(r, c, choice);

                        if (recursions < MaxDepth)
                        {
                       //-----------We must go deeper. SUDCEPTION!-----------//
                             solved = (SolveGrid(grid, checkUnique)); //Recurse
                        }
                        else
                        {
                            solved = false;
                        }
                        if (stoplooking == true)
                        {
                            done = true;
                            got_one = true;
                        }
                        else
                        {
                            got_one = (got_one || solved);
                            if (!checkUnique)  //If not looking for unique soln
                            {
                                done = got_one;       //Then we have a solution
                            }
                        }
                        i++;
                    }
                    result = got_one;
                }
            }
            return result;
        }