打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
破解九宫格数独游戏
数独是一种比较费时费脑的游戏,一般难度的数独玩下来也得1个小时左右,本人是伪数独爱好者,碰到难点的数独需要花上若干个小时,于是偷懒写了一套破解程序,特拿出来分享,希望有人喜欢。
思路:
从第一个空格开始,计算出所有可能填充的数字,拿出第一个进行填充,将剩下的可能数字记录下来;
接着计算下一个空格所有可能的数字(在前边填充上的基础上),拿出第一个可能进行填充,将剩下的记录;
以此下去;
直到出现这样一个空格:所有的数字都没法填充(有冲突),就回到最后一次那个假设点,重新尝试其它的可能数字;
以此下去;
直到填充完所有空格。
实现代码
// C#using System;using System.Collections.Generic;using System.Text;/* ===================================== * Author: 朱乙 * Blog: http://blog.csdn.net/sq_zhuyi * Email: sqzhuyi@gmail.com======================================== */namespace SudokuResponder{ public class SudokuService { Number[][][][] pArr = null;//存储数独数字 public SudokuService(string numStr) { string s = numStr.Replace(",", ""); if (s.Length != 81) { throw new Exception("初始数独错误,必须是81个数字"); } int[] numArr = new int[81]; for (int i = 0; i < s.Length; i++) { numArr[i] = Convert.ToInt32(s[i].ToString()); } pArr = GetArray(numArr); } public SudokuService(int[] numArr) { if (numArr.Length != 81) { throw new Exception("初始数独错误,必须是81个数字"); } pArr = GetArray(numArr); } /// <summary> /// 获取结果 /// </summary> /// <returns></returns> public string GetResult() { FillArray(); StringBuilder sb = new StringBuilder(); for (int m = 0; m < 3; m++) { for (int i = 0; i < 3; i++) { for (int n = 0; n < 3; n++) { for (int j = 0; j < 3; j++) { sb.Append(pArr[m][n][i][j].Value); } } sb.Append(","); } } return sb.ToString().TrimEnd(','); } /// <summary> /// 打印结果 /// </summary> public void PrintResult() { for (int m = 0; m < 3; m++) { if (m == 0) Console.WriteLine("".PadLeft(25, '-')); for (int i = 0; i < 3; i++) { for (int n = 0; n < 3; n++) { if (n == 0) Console.Write("| "); for (int j = 0; j < 3; j++) { var pv = pArr[m][n][i][j]; if (pv.Default) Console.ForegroundColor = ConsoleColor.Red; Console.Write("{0} ", pv.Value); Console.ForegroundColor = ConsoleColor.White; } Console.Write("| "); } Console.WriteLine(); } Console.WriteLine("".PadLeft(25, '-')); } } private Number[][][][] GetArray(int[] defVal) { Number[][][][] pArr = new Number[3][][][]; for (int m = 0; m < 3; m++) { pArr[m] = new Number[3][][]; for (int n = 0; n < 3; n++) { pArr[m][n] = new Number[3][]; for (int i = 0; i < 3; i++) { pArr[m][n][i] = new Number[3]; for (int j = 0; j < 3; j++) { pArr[m][n][i][j] = new Number() { Value = 0, Default = false }; } } } } int c = 0; for (int m = 0; m < 3; m++) { for (int i = 0; i < 3; i++) { for (int n = 0; n < 3; n++) { for (int j = 0; j < 3; j++) { int val = defVal[c++]; pArr[m][n][i][j].Value = val; if (val > 0) pArr[m][n][i][j].Default = true; } } } } return pArr; } 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 } //清空该位置后边的空格 private void ClearAfter(int[] pos) { int min = pos[0] * 1000 + pos[1] * 100 + pos[2] * 10 + pos[3]; 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 (m * 1000 + n * 100 + i * 10 + j > min) { if (pArr[m][n][i][j].Default == false) { pArr[m][n][i][j].Value = 0; } } } } } } } //记录每个位置的可能数字 private List<PosValues> posVals = new List<PosValues>(); //获取当前位置的可能数字 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); } return pv; } } } public struct Number { public int Value; public bool Default; } public class PosValues { public int[] Position; public List<int> Values; public bool Ok = true; public int Value; }}
调用代码
// C#using System;using System.Collections.Generic;namespace SudokuResponder{ class Program { static void Main(string[] args) { string s = "000000007,008000400,003801600,804306201,000000000,105407908,007603800,006000100,400000005"; SudokuService service = new SudokuService(s); DateTime start = DateTime.Now; string result = service.GetResult(); TimeSpan span = DateTime.Now - start; service.PrintResult(); Console.WriteLine("计算结束,用时 {0} 毫秒", span.Milliseconds); Console.WriteLine("press enter to exit"); Console.ReadLine(); } }}
运行截图
破解九宫格运行结果
作者:朱会震
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
1一一9九宫格数独口诀
玩九宫格有什么技巧?快速数独解答法
用js实现打印九九乘法表
五年级:美妙数学之“好玩的数独游戏”(0625五)
风水先生不会填这个九空格,一定是半桶水的。
C#判断字符串中是否含有汉字
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服