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); } } } }
/// <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); }
/// <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); }
/// <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(); }
/// <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); }