Beispiel #1
0
 private void GetRCValue(int rc)
 {
     if (rc >= 80)
     {
         answerCount++;
         return;
     }
     if (avaFull.Contains(rc + 1))
     {
         GetRCValue(rc + 1);
     }
     else
     {
         int    r   = rc / 9;
         int    c   = rc % 9;
         Avails ava = GetOptional(r, c);
         for (int i = 0; i < ava.Count; i++)
         {
             int value = ava[i];
             int n     = r / 3 * 3 + c / 3;
             matrix[r, c] = value;
             //将值存入二进制状态中
             FillValue(r, c, n, value);
             if (!isError)
             {
                 GetRCValue(rc + 1);
                 ClearValue(r, c, n);
             }
             else
             {
                 GetRCValue(rc + 1);
             }
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// 利用一个随机序列重新打乱当前集合的顺序
        /// </summary>
        public void Random()
        {
            //随机序列
            Avails     rIndex = new Avails(this.Count, false);
            List <int> temp   = new List <int>();

            for (int i = 0; i < rIndex.Count; i++)
            {
                temp.Add(this[rIndex[i] - 1]);
            }
            this.Clear();
            this.AddRange(temp);
        }
Beispiel #3
0
        /// <summary>
        /// 获取指定行列的可选序列,该序列中的值不与所在行列宫中的任何一个值冲突
        /// </summary>
        /// <param name="r"></param>
        /// <param name="t"></param>
        /// <returns></returns>
        public Avails GetOptional(int r, int c)
        {
            //初始化一个随机的可选序列,随机是为了防止多次生成一样的数独
            Avails ava = new Avails(9, true);

            //将本行出现过的值从序列中删除
            for (var i = 0; i < 9; i++)
            {
                if (i == c)
                {
                    continue;
                }
                if (ava.Contains(matrix[r, i]))
                {
                    ava.Remove(matrix[r, i]);
                }
            }
            //将本列出现过的值从序列中删除
            for (var i = 0; i < 9; i++)
            {
                if (i == r)
                {
                    continue;
                }
                if (ava.Contains(matrix[i, c]))
                {
                    ava.Remove(matrix[i, c]);
                }
            }
            //将本宫出现过的值从序列中删除
            for (int i = r / 3 * 3; i < r / 3 * 3 + 3; i++)
            {
                for (int j = c / 3 * 3; j < c / 3 * 3 + 3; j++)
                {
                    if (i == r && j == c)
                    {
                        continue;
                    }
                    if (ava.Contains(matrix[i, j]))
                    {
                        ava.Remove(matrix[i, j]);
                    }
                }
            }
            return(ava);
        }
Beispiel #4
0
        /// <summary>
        /// 创建数独,并将部分格子置空
        /// </summary>
        /// <param name="num"></param>
        public void Create(int empty)
        {
            matrix = new int[9, 9];
            //生成一个数独
            CreateMatrix();
            //PrintMatrix();
            //实例一个无序的序列
            avaFull = new Avails(81, false);

            for (int i = 0; i < empty;)
            {
                for (int j = 0; j < avaFull.Count; j++)
                {
                    int v = avaFull[j] - 1;
                    int r = v / 9;
                    int c = v % 9;
                    int t = matrix[r, c];
                    matrix[r, c] = 0;
                    avaFull.Remove(v + 1);
                    if (i > 3 && GetAnswerCount() > 1)
                    {
                        avaFull.Insert(j, v + 1);
                        matrix[r, c] = t;
                    }
                    else
                    {
                        i++;
                        break;
                    }
                }
            }
            //int count = 0;
            ////按该序列的顺序删除 empty 个格子中的值
            //while (count < empty)
            //{
            //    int v = avaFull[count++] - 1;
            //    int r = v / 9;
            //    int c = v % 9;
            //    matrix[r, c] = 0;
            //    avaFull.Remove(count);
            //}
            PrintMatrix();
        }
Beispiel #5
0
 /// <summary>
 /// 为指定行列选择一个可选的值
 /// </summary>
 /// <param name="r">行</param>
 /// <param name="c">列</param>
 /// <returns>可选值</returns>
 private int RandInt(int r, int c)
 {
     if (matrix[r, c] == 0)
     {
         //初始化一个随机的可选序列,随机是为了防止多次生成一样的数独
         avas[r, c] = new Avails(9, false);
         //将本行出现在本列之前的值从序列中删除
         for (var i = 0; i < 9; i++)
         {
             if (avas[r, c].Contains(matrix[r, i]))
             {
                 avas[r, c].Remove(matrix[r, i]);
             }
         }
         //将本列出现在本行之上的值从序列中删除
         for (var i = 0; i < 9; i++)
         {
             if (avas[r, c].Contains(matrix[i, c]))
             {
                 avas[r, c].Remove(matrix[i, c]);
             }
         }
         //将本宫出现在本格子之前的值从序列中删除
         for (int i = r / 3 * 3; i < r / 3 * 3 + 3; i++)
         {
             for (int j = c / 3 * 3; j < c / 3 * 3 + 3; j++)
             {
                 //只需要遍历到当前格子
                 if (i == r && j == c)
                 {
                     i = 10;
                     j = 10;
                     break;
                 }
                 if (avas[r, c].Contains(matrix[i, j]))
                 {
                     avas[r, c].Remove(matrix[i, j]);
                 }
             }
         }
         //可选序列为空,返回 0
         if (avas[r, c].Count == 0)
         {
             return(0);
         }
         //avas[r, c].Random();
     }
     else
     {
         //上次选择的是最后一个可选值,将值清空,返回 0
         if (avas[r, c].IsLast)
         {
             matrix[r, c] = 0;
             return(0);
         }
         //回溯的时候从可选序列中选择下一个值
         avas[r, c].Index++;
     }
     //返回可选序列当前选定值
     return(avas[r, c].Value);
 }