日期:2014-05-18  浏览次数:21155 次

【开源】完美破解九宫格(数独)游戏
最近2年很少来社区活动,昨天机缘巧合写了个破解数独的程序,特拿来与大家分享,以示存在。

思路:
1、从第一个空格开始,计算出所有可能填充的数字,拿出第一个进行填充,将剩下的可能数字记录下来;
2、接着计算下一个空格所有可能的数字(在前边填充上的基础上),拿出第一个可能进行填充,将剩下的记录;
3、以此下去;
4、直到出现这样一个空格:所有的数字都没法填充(有冲突),就回到最后一次那个假设点,重新尝试其它的可能数字;
5、以此下去;
6、直到填充完所有空格。

附上核心代码
填充空格
C# code

        private void FillArray()
        {
            for (int m = 0; m < 3; m++)
            {
                for (int n = 0; n < 3; n++)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        for (int j = 0; j < 3; j++)
                        {
                            if (pArr[m][n][i][j].Default == false)
                            {//空白格
                                var pv = GetNumber(new int[4] { m, n, i, j });

                                if (!pv.Ok)
                                {
                                    m = pv.Position[0];
                                    n = pv.Position[1];
                                    i = pv.Position[2];
                                    j = pv.Position[3];
                                    ClearAfter(pv.Position);

                                }
                                pArr[m][n][i][j].Value = pv.Value;
                            }
                        }
                    }//end small
                }
            }//end big
        }


获取当前位置可能的数字
C# code

        private PosValues GetNumber(int[] pos)
        {
            List<int> nums = new List<int>();
            for (int n = 1; n <= 9; n++)
            {
                nums.Add(n);
            }
            //3宫格内
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    int a = pArr[pos[0]][pos[1]][i][j].Value;
                    if (a > 0 && nums.Contains(a))
                    {
                        nums.Remove(a);
                    }
                }
            }
            //横向
            for (int n = 0; n < 3; n++)
            {
                for (int j = 0; j < 3; j++)
                {
                    int a = pArr[pos[0]][n][pos[2]][j].Value;
                    if (a > 0 && nums.Contains(a))
                    {
                        nums.Remove(a);
                    }
                }
            }
            //纵向
            for (int m = 0; m < 3; m++)
            {
                for (int i = 0; i < 3; i++)
                {
                    int a = pArr[m][pos[1]][i][pos[3]].Value;
                    if (a > 0 && nums.Contains(a))
                    {
                        nums.Remove(a);
                    }
                }
            }

            if (nums.Count == 0)
            {
                if (posVals.Count == 0)
                {
                    return new PosValues()
                    {
                        Value = 0
                    };
                }
                var pv = posVals[posVals.Count - 1];

                pv.Ok = false;
                pv.Value = pv.Values[0];
                pv.Values.Remove(pv.Value);
                if (pv.Values.Count == 0)
                {
                    posVals.Remove(pv);
                }
                return pv;
            }
            else
            {
                var pv = new PosValues();
                pv.Position = pos;
                pv.Value = nums[0];
                nums.Remove(pv.Value);
                pv.Values = nums;
                if (nums.Count > 0)
                {
                    posVals.Add(pv);