资源下载地址:https://download.csdn.net/download/sheziqiong/85660211
资源下载地址:https://download.csdn.net/download/sheziqiong/85660211
一、实验题目与要求
本次实验主要内容是实现一个简单的数独软件,具体要求如下:
基本功能部分
程序说明信息以及交互
程序的基本交互由图形化界面实现。
说明信息见 “关于” 功能按钮。
打印数独
通过图形化界面表示。
黑色表明是初始状态(被锁定,玩家无法修改),蓝色是玩家自行填入的数字,绿色是当前提示的数字(如果再进行提示等操作,则会变为蓝色)。
输入数独
初始化一个数独的方式有两种:
支持玩家生成一个大小为0的空白数独
之后可以通过底端操作区域填入数字。填入数字完成后,点击锁定,即可初始化。填入数字过程如果矛盾会有提示。(详见后面错误处理部分)。
可以通过读档的方式完成
详见后面读档部分。
生成数独
程序的第一个输入框可以输入指定数目的数字,指定初始生成的数独带有多少数字。如果数字范围异常(0到40之外),则会报错提示。
输出数独的解
点击解数独按钮,即可获得当前局面的解。如果无解,本程序会提示。
填入数字合法情况
采用下列方式向数独中填入数字
- 点击下方9个候选数字或代表删除的“X”。
- 点击要填入或删除数字的格子
对于合法输入,填入/删除数字会直接反馈在图形界面上。
填入数字异常情况
处理以下异常输入:
- 如果试图修改题目固定的数字此时,会出现以下提示:
-
如果填入的数字过大
这一情况不会发生。图形界面仅允许输入1-9的数字或者删除数字。
-
如果输入的填入位置不合法
这一情况不会发生。图形界面仅允许填入该81个格子。
-
如果填入的数字和已有数字重复此时会提示具体重复的行列。
数独提示信息
点击提示按钮。此时,如果数独有解,会检查是否存在逻辑上一步可以推理出唯一解的格子,如果有,则填入,否则填入可填入可能性最少的格子。
如果数独无解,则会给出无解提示。
保存游戏状态
点击保存。会调用Windows提供的文件选择界面。指定文件夹,填入文件名后即可保存文件状态。
加载游戏状态
可以加载存档文件。效果同上。
存档文件格式:
首先是一个9*9的矩阵,记录了数独每个位置上的数字。没有放置计为0。
其次的9*9矩阵,如果为0代表这一位不是初始的数字,如果不为0则代表这一位是初始的数字。
所以可以通过输入两遍相同的矩阵,通过读档功能完成数独的初始化。
扩展部分
图形化界面
已经通过qt实现。
高级搜索技巧
实现了迭代加深dfs以及A*搜索。
具体介绍见下文。
搜索模式可以通过下拉栏切换。
多线程优化
实现使用多线程技术并行搜索输出数独全部的解。保存入指定文件中。
仅保存前100万个搜索到的解,以避免文件过大。
100万这个数字通过宏定义,可以方便地修改。
二、具体设计
该部分将简单介绍实验中的函数拆分与图形化实现的细节,例如,包括哪些函数,函数参数是什么,作用是什么等。扩展功能的介绍等。
包含函数
为了方便说明,这里再列出本程序的一些基本数据:
char sudoku_num[9][9] = { 0 }; //数独当前状态数字
char sudoku_solu[9][9] = { 0 }; //数独解
bool fixed[9][9] = { 0 }; //是否被固定(是否是初始状态)
-
槽函数对应了各个控件,在控件发生对应的事件时(本程序中,除了更改搜索模式,均是点击按钮操作),会触发槽函数。槽函数和触发它的信号之间通过connect函数连接。
-
图形化辅助函数中,initial()用于建立初始界面,包含了控件位置,大小的处理以及信号和槽函数的连接。
create_widget()用于创建窗口,两个参数指定创建窗口的标题和内容。通常用于处理各种报错。
sudoku_paint()的调用是在解完数独后,需要更新所有数独格子的显示。
-
计算函数中,search()是搜索函数。返回值1代表有解,并且解会被储存在sudoko_solu中,返回值0代表无解。这个函数会依据当前的搜索模式,调用不同的函数完成搜索任务。也就对应了search_dfs(),search_dfs_ID(),search_astar()这三个函数,也就是普通dfs,迭代加深dfs 和Astar搜索。这三个搜索函数同样返回1代表有解,0代表无解。search_dfs_get_tree(),search_dfs_all(),output_to_file功能上是并行输出所有的解,与以上搜索函数略有不同。
generate()作用是随机生成指定个数字的数独(但是不保证有解,仅保证不出现矛盾)存放到 sudoku_num中,并更新fixed数组。
-
错误处理函数主要是重复的处理。需要单独判断是哪一行哪一列出现了重复。
拓展功能——迭代加深dfs
在介绍 高级搜索方法 之前,先对搜索数独的过程做一个抽象:取每个局面作为一个结点。
资源下载地址:https://download.csdn.net/download/sheziqiong/85660211
资源下载地址:https://download.csdn.net/download/sheziqiong/85660211