/// <summary> /// 挖洞操作 /// </summary> private void EmptyMatrix() { 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]; this[r, c] = 0; avaFull.Remove(v + 1); if (i > 3 && GetAnswerCount() > 1) { avaFull.Insert(j, v + 1); this[r, c] = t; } else { i++; break; } creating(this, EventArgs.Empty); } } }
/// <summary> /// 用递归尝试填充单元格 /// </summary> /// <param name="rc"></param> 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]; this[r, c] = value; if (!isError) { GetRCValue(rc + 1); this[r, c] = 0; } else { GetRCValue(rc + 1); } } } }
private void FillOneOptional() { bool flag = true; while (flag && empty > 0) { flag = false; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (this[i, j] == 0) { Avails ava = this.GetOptional(i, j); if (ava.Count == 1) { this[i, j] = ava.Value; empty--; flag = true; if (empty == 0) { break; } } } } if (empty == 0) { break; } } } }
/// <summary> /// 完成游戏调用线程的方法 /// </summary> void Finish() { //改变每个格子的字体颜色和背景颜色 foreach (Pane pane in panes) { pane.ReadOnly = true; pane.BackColor = backNormalColor; } Avails ava = new Avails(81, false); //利用一个随机序列改变每个格子的字体颜色 foreach (int i in ava) { int x = (i - 1) / 9; int y = (i - 1) % 9; panes[x, y].ForeColor = GerColor(fontNormalColor, 96); Thread.Sleep(30); } ava.Random(); //利用另一个随机序列改变每个格子的背景颜色 foreach (int i in ava) { int x = (i - 1) / 9; int y = (i - 1) % 9; panes[x, y].BackColor = GerColor(backNormalColor, -48); Thread.Sleep(30); } }
/// <summary> /// 完成游戏调用线程的方法 /// </summary> void Finish() { try { //改变每个格子的字体颜色和背景颜色 ((FrmGame)this.Parent).menuStrip1.Enabled = false; foreach (Pane pane in panes) { pane.ReadOnly = true; pane.BackColor = backNormalColor; } Avails ava = new Avails(81, false); //利用一个随机序列改变每个格子的字体颜色 foreach (int i in ava) { int x = (i - 1) / 9; int y = (i - 1) % 9; panes[x, y].ForeColor = GerColor(fontNormalColor, 96); Thread.Sleep(30); } ava.Random(); //利用另一个随机序列改变每个格子的背景颜色 foreach (int i in ava) { int x = (i - 1) / 9; int y = (i - 1) % 9; panes[x, y].BackColor = GerColor(backNormalColor, -48); Thread.Sleep(30); } ((FrmGame)this.Parent).menuStrip1.Enabled = true; Thread.CurrentThread.Abort(); Thread.CurrentThread.Join(); } catch { } }
/// <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); }
private void TryFill(int rc) { if (rc < 0 || rc > 80) { return; } int i = rc / 9; int j = rc % 9; if (matrix[i, j] == 0) { Avails ava = this.GetOptional(i, j); for (int k = 0; k < ava.Count; k++) { matrix[i, j] = ava[k]; empty--; rc++; isGet = empty == 0; TryFill(rc); if (!isGet) { rc--; empty++; matrix[i, j] = 0; } else { break; } } } else { rc++; TryFill(rc); if (!isGet) { rc--; } } }
/// <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) { this[r, c] = 0; return(0); } //回溯的时候从可选序列中选择下一个值 avas[r, c].Index++; } //返回可选序列当前选定值 return(avas[r, c].Value); }