【开源】完美破解九宫格(数独)游戏

news/2024/11/15 1:23:42/

数独是一种比较费时费脑的游戏,一般难度的数独玩下来也得1个小时左右,本人是伪数独爱好者,碰到难点的数独需要花上若干个小时,于是偷懒写了一套破解程序,特拿出来分享,希望有人喜欢。


思路:

1、从第一个空格开始,计算出所有可能填充的数字,拿出第一个进行填充,将剩下的可能数字记录下来;

2、接着计算下一个空格所有可能的数字(在前边填充上的基础上),拿出第一个可能进行填充,将剩下的记录;

3、以此下去;

4、直到出现这样一个空格:所有的数字都没法填充(有冲突),就回到最后一次那个假设点,重新尝试其它的可能数字;

5、以此下去;

6、直到填充完所有空格。


实现代码:

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;}
}

调用代码:

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

运行截图:



下载地址:http://download.csdn.net/detail/sq_zhuyi/4411715


作者:朱会震


http://www.ppmy.cn/news/563446.html

相关文章

经典数独游戏+数独求解器—纯C语言实现

“心常乐数独小游戏”&#xff08;以下简称“本软件”&#xff09;是一款windows平台下的数独游戏软件。 本软件是开源、免费软件。 本软件使用纯C语言编写&#xff0c;MinGW编译&#xff0c;NSIS打包。 本软件主要特性如下&#xff1a; 支持“闯关模式”和“选关模式” 支…

python实现简易数独小游戏

起源 既然“数独”有一个字是“数”&#xff0c;人们也往往会联想到数学&#xff0c;那就不妨从大家都知道的数学家欧拉说起&#xff0c;但凡想了解数独历史的玩家在网络、书籍中搜索时&#xff0c;共同会提到的就是欧拉的“拉丁方块&#xff08;Latin square&#xff09;”。…

1.数独游戏(生成题目解唯一)

前几天在玩数独游戏的时候&#xff0c;产生了一个大胆的想法&#xff1a; 数独app上的题目都是现成的&#xff0c;干脆自己写一个可以随机生成数独的程序算了 一、需求提出&#xff1a; 1.随机生成数独题目&#xff0c;要求该题目有解&#xff08;有一个解最好&#xff09;&a…

(附代码)数独大作业【读取数独,解数独,生成唯一解数独(随机,特定形状,不同难度生成),玩数独】

注:未经同意不要转载。 上学期简单的做了一个数独程序&#xff0c;实现了一些功能&#xff0c;想简单的为大家提供的思路。 为了避免某些情况出现&#xff0c;具体代码暂时先不发了&#xff0c;有不太懂的地方可以评论提问啊。 下面是我的具体报告&#xff1a; 一&#xff…

让程序自动玩数独游戏让你秒变骨灰级数独玩家

程序自动填网页数独游戏 有个玩数独游戏的网站&#xff1a;https://www.sudoku.name/index-cn.php 当然这类玩数独游戏的网站很多&#xff0c;现在我们先以该网站为例进行演示。 玩过的都非常清楚数独的基本规则&#xff1a; 数字 1-9 在每一行只能出现一次。数字 1-9 在每一…

项目集活动—项目集交付阶段活动

项目集交付阶段活动包括协调和管理项目集实际交付所需执行的项目集活动。这些活动包括围绕 变更控制、报告和信息发布所开展的活动&#xff0c;以及围绕成本、采购、质量和风险所开展的活动。 这些活动提供了贯穿整个项目集生命周期的支持活动和流程&#xff0c;旨在提供项目集…

为什么要做数据治理

在数聚股份看来&#xff0c;数据治理是管理企业数据资源、提高数据价值的一种方法。它是一种综合性的管理方式&#xff0c;旨在帮助企业提高数据管理效率&#xff0c;加强数据安全管理&#xff0c;优化数据质量。随着企业数据规模的不断增大&#xff0c;数据治理越来越成为企业…

java中如何实现字符串反转

java中如何实现字符串反转 方式1&#xff1a;通过创建StringBuilder或StringBuffer对象&#xff0c;并使用其reverse()方法实现字符串的反转 上代码&#xff1a; /*** 给定一个字符串&#xff0c;通过创建SpringBuilder对象的方式将字符串进行反转* return*/public static …