计算机专业VC++课程设计.docx

上传人:b****8 文档编号:28015553 上传时间:2023-07-07 格式:DOCX 页数:13 大小:1.02MB
下载 相关 举报
计算机专业VC++课程设计.docx_第1页
第1页 / 共13页
计算机专业VC++课程设计.docx_第2页
第2页 / 共13页
计算机专业VC++课程设计.docx_第3页
第3页 / 共13页
计算机专业VC++课程设计.docx_第4页
第4页 / 共13页
计算机专业VC++课程设计.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

计算机专业VC++课程设计.docx

《计算机专业VC++课程设计.docx》由会员分享,可在线阅读,更多相关《计算机专业VC++课程设计.docx(13页珍藏版)》请在冰豆网上搜索。

计算机专业VC++课程设计.docx

计算机专业VC++课程设计

VisualC++谋程设计

题目名称:

数独游戏设计

班级:

信安1101

某某:

曹闯

学号:

1111290101

指导教师:

阎光伟

完成时间:

2013.1.18

1题目描述

利用VisualC++实现数独游戏的功能。

该程序能够设置不同难度等级的游戏,实现数

独游戏的多样化,采取有效的算法,保证答案的唯一解。

2功能分析

系统主要功能包括:

(1)游戏的生成

数独游戏的初始化,根据难度在格子里填上数量不同的数字,每种难度下的数字数量一样。

(2)游戏难度的选择

难度设置,从简单到困难,难度越大,生成游戏时数宁数量越少。

(3)游戏的提示

主对话框类

提示三次。

在计时削板上有暂停[钮,按下暂停[按钮后,游戏将进入不计时状态,同时界

~「难度选择:

钮类、

(6)游戏的帮助功能

I通过帮助文档的使用■人进

3界面分析

程序界面由棋盘和按钮组成,在棋盘内,通过单击鼠标选中方格时显示为问号,选中

数字时显为蓝色数字。

通过键盘在选中方格填入数字,假如填入的数字符合游戏规如此,显示为橙色,反之,显示为红色。

按钮处于选中状态时会变成亮色或者周围加上边框。

游戏光标在不同的游戏区域采用了不同的游戏光标。

4系统设计

4.1程序整体结构

4.1.1程序中的主要游戏类

在本程序中,主要分为三大根本类:

1、对话框类,2、游戏算法类,3、按钮类。

话框类包括游戏主对话框和选择难度对话框,自定义按钮类包括游戏主对话框的按钮类和

难度选择对话框的按钮类。

图1游戏主要框架

4.2主要模块设计

4.2.1游戏根本类设计

(1)游戏主话框类的实现过程

通过的按钮的响应函数来实现整个游戏的逻辑控制,当“新游戏'’按钮被单击后,游

戏界面将进展初始化,后续的操作才能继续进展,通过键盘响应函数来实现对输入数字的控制,通过鼠标移动函数OnMouseMove()来判断区域和加载不同的光标。

通过单击鼠标

函数OnLButtonDown()来判断单击的区域,实现整个节目的逻辑操作。

通过计时函数来实

现计时器的功能。

(2)按钮类ewButton和CMyButton类的实现过程

ewButton类是难度选择对话框的按钮类,CMyButton是主对话框的按钮类。

两个类

的实现方式一样,都是通过继承CButton类实现按钮的重绘功能,在按钮类里面通过

OnMouseHover()函数判断鼠标是否停留在按钮上,通过OnMouseLeave()判断鼠标是否离

开按钮。

当鼠标停在按钮上或者移开按钮,通过不同的返回值来调用DoGradientFill()函

数,自定义的实现了绘制按钮边框的功能。

然后再通过按钮重绘函数DrawItem()来实现

整个按钮的重绘。

(3)难度对话框的实现

定义CLevel类,通过四个单项选择按钮和两个控制按钮来构成难度选择对话框,通过重载CButton类来实现按钮的重绘。

通过主对话框的难度按钮选择,调用CLevel类,实现难度选择对话框的调用。

(4)算法流程图

r、

计算函数calculate。

2/10

假如为生成数独

时调用该计算函

跳过该格子,该格子继续在栈里

图2算法流程图

〔5〕游戏算法的实现过程

游戏算法类CSolvesoduku是数独游戏的核心算法,也是整个程序得以运行的中心。

图3游戏算法主要函数

4.2.2数据结构和函数的介绍

(1)数据结构

最主要的数据结构是4个整型数组,其中3个被设计成一维数组,还有1个二维数

组。

1)intsd[82]

该数组的用途是接收题目以与保存最终结果。

所有的9X9个数字被依次存储在该数

组中,空白处如此初始化为0。

之所以把数组X围设计成82而不是81,是为了程序的易读性,使得数组元素的最大下标可达81,下同。

2)intfix[82]

该数组的用途是:

假如sd数组中某位置的数字不为0,如此fix数组相应位置的元素

值记录为1,否如此记录为0。

即fix数组是用来记录哪些位置的数字是已经确定下来的。

3)intpossible[82][10]

该数组的用途是记录所有未确定数字的所有可能性。

可能性的记录方法是:

possible

数组各元素的值在初始化时被初始化为与其第二维的下标一致,即0-9(其中0是不会用

的);中间计算过程中,假如发现第一维某位置的某种可能性已不复存在,如此将第一维

下标是该位置而第二维下标是该不再可能的数字的元素值改为-1。

4)intstack[82]

该数组的用途类似于栈,在核心回溯过程中起到至关重要的作用。

回溯之前,要把所有fix数组中值为0的位置依次存放进stack数组;回溯中,由低到高依次逐渐确定这些位置数值,无法确定者(即1-9的数字都不适合者)如此应当回退到前一个位置,修改其

假设值,以此类推,直至stack数组所存放的所有位置的值都能确定,或回退到最初点的

前一个位置。

(2)三个重要函数

下面介绍几个在“有限递推"预处理和回溯过程中会用到的三个重要函数。

1)voidsetPb();

该函数是用来修订possible数组的。

其具体功能是:

对于fix数组中每一个值为0的位置(即对于每一个没有确定下数字的位置),考察其可能的数字是哪些,记录下来。

察的方法是:

在1-9这些数字中除去当前行、列、九宫中已有的数字。

2)boolfixAll();

该函数是用来修订fix数组和possible数组的,其返回值表示了在此次运行该函数过程中是否执行了修订。

其具体功能是:

对于fix数组中每一个值为0的位置(即对于每一

个没有确定下数字的位置),考察其可能的数字的个数,假如为1,如此将fix数组该位置

的值改为1且sd数组该位置的值改为该唯一可能的数字(即该位置的值已确定下来),

且返回真;假如没有只有一种可能性的位置,如此返回假。

3)boolExist(inti,intj);

其用途是:

判断sd数组中位置为i的元素的值是否可能为j,即判断的是:

位置i所

在的行、列以与九宫中是否已经存在数字j,假如存在如此返回真,否如此返回假。

(3)“有限递推"预处理

在执行一次fixAll函数之后,就可能会确定下一些原来没有确定的数字,那么此

时,possible数组的值必然也会变动!

因为确定下的数字越多,某些位置的可能数字的数

目就会减少。

那么就应当再执行setPb函数修订possible数组,而修订之后可能又会出现

一些只有一种可能性的位置,那么就应该再执行fixAll函数了...于是,只要如此循环往复

下去,就能最大限度地确定下由题目本身含义与规如此而确定下的内容。

确定的数字越多,

对于将来回溯也就越有利。

那么,有限递推的循环什么时候完毕呢?

只有两种情况,一是

推出了全部结果;二是fixAll函数返回值为假,即不存在只有一种可能性的位置。

预处理的函数

voidpreDo()

setPb();

FixAll();

if(isFull())

return;

}

(4)回溯算法

1)

按下标的由低到高扫描sd数组,将值为0的位置记录进stack数组,记录的顺序也由

低到高。

最后,整型量max记录下:

sd数组中为0位置的个数再加1。

2)

整型量top初始化为0,即把stack看作栈(虽然stack数组的内容永远不会变,但top的增减仍代表了进栈和出栈的操作),top记录的是栈顶。

3)

bool型变量flag初始化为true。

下面各步骤都将在一个条件始终为真的死循环中进

展,该循环由一条对flag进展真假判断的if-else语句分成两大局部。

flag所代表的意义是:

假如当前栈顶(top)是经过了回退操作而达到的,如此flag会已被记录为假;否如此

flag为真。

死循环完毕的条件是top与max的值相等,即解出最终结果,或者是无解,最

终top小于0(无解的情况根本上在最初做题目的合法性检查时已经排除了)。

在死循环

中:

假如flag为真,进入步骤(4),否如此进入步骤(5)。

4)

flag为真,说明栈顶(top)是经过正常的假设而达到的,并非由回退达到,那么:

根据

possible数组以与Exist函数,对栈顶所保存位置的可能出现的数字进展判断,把遇到的第

一个可能数字设置进sd数组,并判断top和max相等否,假如相等,退出死循环;假如发现1-9都不可能应用在栈顶所保存的位置,如此说明前面的假设有错误,此时应当回退,

即:

fix数组和sd数组的该位置重设为0,top减1,并将flag置为假。

本轮循环体完毕,继

续下一轮的循环。

5)

flag为假,说明是经过了回退才达到现在这个栈顶的,那么:

假如仍然没有可能的数

字可以应用在当前栈顶所保存的位置上,那么继续执行出栈操作,即:

sd数组的该位置重

设为0,top减1;否如此将遇到的第一个可能数字应用到该位置,即:

再设好sd数组,将

top加1,并将flag置为真。

本轮循环体完毕,继续下一轮的循环。

6)

假如start==1时,表示现在进展的是生成随机数独时求解,当start==0时,代表此

时验证是否有两解,函数不会直接退出循环。

而是在遍历完所有情况或者找到第二个解的时候退出程序。

(5)数独生成算法

通过该算法用以生成各种难度等级的数独题,通过对游戏规如此的分析,首先从以下

三个方面定义难度等级:

格总数和穷举搜索复杂度.该算法采用“挖洞"思想。

经过以下两步生成数独题:

1)运用上面的算法生成一个终盘;

2)“抹去"一局部数字来生成数独题:

1根据所需要的难度等级选取挖洞的个数;

2每次挖取改位置的数字时,首先检验挖去该数字后是否是唯一解,假如挖去该数字

后不是唯一解,如此禁止此次操作。

为了防止重复挖洞计算,对于一个不挖去的位置,用

一个新数组保存下来,每次到高位置时与跳过,经过剪枝后的算法速度会大幅的提高。

5运行与测试结果

5.1程序主要运行界面

图4游戏开始界面

2〕按下新游戏后的游戏界面,其中计时器开始计时,如图5所示。

3〕按下暂停后,界面将不可视,如图6所示。

5〕按下显示答案或者填入答案都正确,出现如图

图7难度选择界面

6)填入的数字违反游戏规如此时显示为红色,如图

图5游戏开始后运行界面

图6暂停后的界面

4〕按下难度选择后,出现难度选择界面,如图7所示:

8所示界面:

图8答案正确的界面

9所示:

图9违反规如此时数字界面

7〕点击右上角的帮助按钮,弹出帮助文档,界面如图10、11所示:

 

5.2系统测试

5.2.1界面操作测试

 

相应的功能。

5.2.2数独唯一解测试

 

解的情况存在。

5.2.3数独功能的完整性测试

的整体完整性。

如暂停时,擦出界面;不同的条件下,帮组文档会显示不同的解决方案。

6小结

该程序根本上实现了数独的功能。

通过此次的程序书写,加深我对mfc的理解和增强

了我对mfc的使用能力。

该程序偶尔会出现死机的情况,但在调试阶段已根本解决掉了内

存泄露的问题,死机的bug出现频率较低,且不知道原因何在,在以后的学习中,希望能进一步改善。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1