示例#1
0
        // Is there one and only one solution?
        private Ret TestUniqueness()
        {
            // Find untouched location with most information
            int xp = 0;
            int yp = 0;

            byte[] Mp  = null;
            int    cMp = 10;

            for (int y = 0; y < 9; y++)
            {
                for (int x = 0; x < 9; x++)
                {
                    // Is this spot unused?
                    if (m_sudoku[y, x] == 0)
                    {
                        // Set M of possible solutions
                        byte[] M = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

                        // Remove used numbers in the vertical direction
                        for (int a = 0; a < 9; a++)
                        {
                            M[m_sudoku[a, x]] = 0;
                        }

                        // Remove used numbers in the horizontal direction
                        for (int b = 0; b < 9; b++)
                        {
                            M[m_sudoku[y, b]] = 0;
                        }

                        // Remove used numbers in the sub square.
                        int squareIndex = m_subSquare[y, x];
                        for (int c = 0; c < 9; c++)
                        {
                            EntryPoint p = m_subIndex[squareIndex, c];
                            M[m_sudoku[p.x, p.y]] = 0;
                        }

                        int cM = 0;
                        // Calculate cardinality of M
                        for (int d = 1; d < 10; d++)
                        {
                            cM += M[d] == 0 ? 0 : 1;
                        }

                        // Is there more information in this spot than in the best yet?
                        if (cM < cMp)
                        {
                            cMp = cM;
                            Mp  = M;
                            xp  = x;
                            yp  = y;
                        }
                    }
                }
            }

            // Finished?
            if (cMp == 10)
            {
                return(Ret.Unique);
            }

            // Couldn't find a solution?
            if (cMp == 0)
            {
                return(Ret.NoSolution);
            }

            // Try elements
            int success = 0;

            for (int i = 1; i < 10; i++)
            {
                if (Mp[i] != 0)
                {
                    m_sudoku[yp, xp] = Mp[i];

                    switch (TestUniqueness())
                    {
                    case Ret.Unique:
                        success++;
                        break;

                    case Ret.NotUnique:
                        return(Ret.NotUnique);

                    case Ret.NoSolution:
                        break;
                    }

                    // More than one solution found?
                    if (success > 1)
                    {
                        return(Ret.NotUnique);
                    }
                }
            }

            // Restore to original state.
            m_sudoku[yp, xp] = 0;

            switch (success)
            {
            case 0:
                return(Ret.NoSolution);

            case 1:
                return(Ret.Unique);

            default:
                // Won't happen.
                return(Ret.NotUnique);
            }
        }
示例#2
0
        /// <summary>
        /// Solves the given Sudoku.
        /// </summary>
        /// <returns>Success</returns>
        public bool Solve()
        {
            // Find untouched location with most information
            int xp = 0;
            int yp = 0;

            byte[] Mp  = null;
            int    cMp = 10;

            for (int y = 0; y < 9; y++)
            {
                for (int x = 0; x < 9; x++)
                {
                    // Is this spot unused?
                    if (m_sudoku[y, x] == 0)
                    {
                        // Set M of possible solutions
                        byte[] M = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

                        // Remove used numbers in the vertical direction
                        for (int a = 0; a < 9; a++)
                        {
                            M[m_sudoku[a, x]] = 0;
                        }

                        // Remove used numbers in the horizontal direction
                        for (int b = 0; b < 9; b++)
                        {
                            M[m_sudoku[y, b]] = 0;
                        }

                        // Remove used numbers in the sub square.
                        int squareIndex = m_subSquare[y, x];
                        for (int c = 0; c < 9; c++)
                        {
                            EntryPoint p = m_subIndex[squareIndex, c];
                            M[m_sudoku[p.x, p.y]] = 0;
                        }

                        int cM = 0;
                        // Calculate cardinality of M
                        for (int d = 1; d < 10; d++)
                        {
                            cM += M[d] == 0 ? 0 : 1;
                        }

                        // Is there more information in this spot than in the best yet?
                        if (cM < cMp)
                        {
                            cMp = cM;
                            Mp  = M;
                            xp  = x;
                            yp  = y;
                        }
                    }
                }
            }

            // Finished?
            if (cMp == 10)
            {
                return(true);
            }

            // Couldn't find a solution?
            if (cMp == 0)
            {
                return(false);
            }

            // Try elements
            for (int i = 1; i < 10; i++)
            {
                if (Mp[i] != 0)
                {
                    m_sudoku[yp, xp] = Mp[i];
                    if (Solve())
                    {
                        return(true);
                    }
                }
            }

            // Restore to original state.
            m_sudoku[yp, xp] = 0;
            return(false);
        }
示例#3
0
        // Generate spots
        private bool Gen(int spots)
        {
            for (int i = 0; i < spots; i++)
            {
                int xRand, yRand;

                do
                {
                    xRand = Randomizer.GetInt(9);
                    yRand = Randomizer.GetInt(9);
                } while(m_sudoku[yRand, xRand] != 0);

                /////////////////////////////////////
                // Get feasible values for spot.
                /////////////////////////////////////

                // Set M of possible solutions
                byte[] M = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

                // Remove used numbers in the vertical direction
                for (int a = 0; a < 9; a++)
                {
                    M[m_sudoku[a, xRand]] = 0;
                }

                // Remove used numbers in the horizontal direction
                for (int b = 0; b < 9; b++)
                {
                    M[m_sudoku[yRand, b]] = 0;
                }

                // Remove used numbers in the sub square.
                int squareIndex = m_subSquare[yRand, xRand];
                for (int c = 0; c < 9; c++)
                {
                    EntryPoint p = m_subIndex[squareIndex, c];
                    M[m_sudoku[p.x, p.y]] = 0;
                }

                int cM = 0;
                // Calculate cardinality of M
                for (int d = 1; d < 10; d++)
                {
                    cM += M[d] == 0 ? 0 : 1;
                }

                // Is there a number to use?
                if (cM > 0)
                {
                    int e = 0;

                    do
                    {
                        // Randomize number from the feasible set M
                        e = Randomizer.GetInt(1, 10);
                    } while(M[e] == 0);

                    // Set number in Sudoku
                    m_sudoku[yRand, xRand] = (byte)e;
                }
                else
                {
                    // Error
                    return(false);
                }
            }

            // Successfully generated a feasible set.
            return(true);
        }