1、*大学数据结构课程设计报告题目: 纸牌游戏院(系): 计算机工程学院 学生姓名: 班级: 学号:起迄日期: 2011.6.21-2011.7.1指导教师: 20102011 年度 第 2 学期 一、需求分析1.问题描述:随机产生 52 个数按照某一规则计算正面牌数。编号为 1-52 张牌,正面向上,从第 2 张开始,以 2 为基数,是 2 的倍数的牌翻一次,直到最后一张牌;然后,从第 3 张开始,以 3为基数,是 3 的倍数的牌翻一次,直到最后一张牌;然后从第 4 张开始,以 4 为基数,是 4 的倍数的牌翻一次, 直到最后一张牌;.再依次 5 的倍数的牌翻一次,6 的,7 的 直到 以 52
2、 为基数的 翻过,输出:这时正面向上的牌有哪些。2.基本功能: 选择纸牌是顺序排序还是随机排序随机,1 为随机排序,其他数字为顺序排序,输入一个数使程序运行,随机产生 52 张纸牌,运行之后输出正面向上的牌。之后输入 1 重新运行,输入其他数字回车停止3.输入输出:1)输入一个数字选择是使用顺序放牌还是随机放牌,1 为随机放牌,其他数字为顺序放牌,输入一个正整数种子值,程序运行,输出 52 张纸牌的排列顺序,列出纸牌序列,输出正面向上的牌,进入选择语句,是否再玩一局,输入 1,程序从新运行,输入其他,程序运行结束。二、 概要设计1.设计思路:当每个号码每次遇到是某个数的倍数的时候,都会相应的翻
3、一次牌,这样,每张牌翻得次数就个不一样,可能很多次,也可能只有一两次,结果就只是要输出在经过各个不同次数的反派后,正面向上的牌都有哪几个。例如 24,第一次他是 2 的倍数时要从背面翻到背面,当进行到 3 时,又要从背面返回来。如果他在多次翻拍后,正面还向上了,那么他就是要输出的结果之一。/操作函数void operate(void)rcard rc;int i,j;rc=Random();/获得纸牌不同排序方式/翻面游戏for(j=2;j| ai-1,ai D,i=1,2,3,,nADT rcard数据对象:D=a i| ai rc,i=1,2,3,n,n0数据关系:R1=| ai-1,ai
4、 D,i=1,2,3,,n基本操作:h_bian(void)操作结果:构成输出纸牌的两边纵向边框。l_bian(void)操作结果:构成输出纸牌的横向边框。void information(int info)初始条件:info 已存在。操作结果: 输出构成所选定纸牌的编号。z_picture(int info)操作结果:输出所选定纸牌Random()初始条件:线性表 num 已存在。操作结果:形成随机链表序列。shunxu()初始条件:线性表 num 已存在。操作结果:形成顺序链表序列。 void operate1(void)初始条件:随机数列存在。操作结果:输出正面向上的纸牌。void op
5、erate2(void)初始条件:顺序数列存在。操作结果:输出正面向上的纸牌。select(void)操作结果:判断调用两个操作函数中的一个。5.软件结构设计:1. 按需求分析中的功能进行模块划分:1) 定义两个实数体。2) 构造输出纸牌的外观和信息。3) 形成顺序或随机数列4) 对选择数据进行操作5) 选择操作函数6) 主函数6.函数原型:定义两个实体 struct : card rcard图形输出函数: z_picture() 调用函数 l_bian()、h_bian()和information()选择函数: select()操作函数: operate1() 调用函数 random()Op
6、erate2() 调用函数 shunxu()排序函数:random()Shunxu()三、 详细设计 1.详细算法模块1. /定义两个实体,其中 card 为 52 张纸牌,rcard 为被选中操作的纸牌structint info; /纸牌编号int postion; /纸牌位置,从 1 开始计int state; /纸牌状态,1 表示纸牌正面向上,0 表示纸牌背面向上card;#define NUM 52 /定义常量,方便调试和验证。typedef structcard cNUM;rcard;2构造纸牌输出界面,形成输出的纸牌形。/纸牌横向边框void h_bian(void)int i;
7、printf(“nt“); for(i=0;i10;i+)printf(“*“);/纸牌列向边框void l_bian(void)int i,j;for(i=0;i2;i+)printf(“nt“);printf(“*“);for(j=0;j8;j+)printf(“ “);printf(“*“);3输出正面向上的纸牌信息。/纸牌序号信息void information(int info)printf(“nt“);if(info10)printf(“* %d *“,info);elseprintf(“* %d *“,info);/纸牌正面void z_picture(int info)h_bi
8、an();l_bian();information(info);l_bian();h_bian();printf(“nn“);4被调用函数,分别由 operate1 和 operate2 调用其中 random 形成 52 张随机数列,shunxu 形成 52 张顺序序列。/获得纸牌不同排序方式rcard Random()rcard rc;int contNUM; /将需要的数存放到数组中,然后通过调换数组中数的位置,达到随机排列目的。unsigned int seed; /申明初始化器的种子,注意是 usigned int 型的int index, i,t; /初始化纸牌状态for(i=0;
9、iNUM;i+)rc.ci.state=1;/对数组进行初始化for (i=0; iNUM; i+)conti = i+1;/提供随机种子printf(“请输入一个正整数种子值: n“);scanf(“%u“,srand(seed);/生成随机序列for (i=0; iNUM-1; i+)/交换 NUM-1 次index=(rand()%(NUM-i-1)+i+1;/产生从 i+1 到 NUM-1 的一个随机数/交换t=conti;conti=contindex;contindex=t;printf(“纸牌编号按顺序排列为:n“);for(i=0;iNUM;i+)rc.ci.info=cont
10、i; /纸牌编号rc.ci.postion=i+1; /对应纸牌位置printf(“%d “, rc.ci.info);return rc;5对选定操作对象进行操作,即进行选择和翻面。/ /操作函数void operate1(void)/操作函数 1,实现随机序列翻牌操作rcard rc;int i,j;rc=Random();/获得纸牌不同排序方式/翻面游戏for(j=2;j=NUM;j+) /j 为基数,也是开始翻面的位置for(i=j;i=NUM;i+)/i 为纸牌位置 if(rc.ci-1.info%j=0) rc.ci-1.state=rc.ci-1.state?0:1;/打印,用纸
11、牌图形打印。printf(“n 正面向上的牌有:“); for(i=0;iNUM;i+) if(rc.ci.state) z_picture(rc.ci.info);printf(“n“);void operate2(void)/操作函数 2,实现顺序序列翻牌操作rcard rc;int i,j;rc=shunxu();/获得纸牌不同排序方式/翻面游戏for(j=2;j=NUM;j+) /j 为基数,也是开始翻面的位置for(i=j;i=NUM;i+)/i 为纸牌位置 if(rc.ci-1.info%j=0) rc.ci-1.state=rc.ci-1.state?0:1;/打印,用纸牌图形打
12、印。printf(“n 正面向上的牌有:“); for(i=0;iNUM;i+) if(rc.ci.state) z_picture(rc.ci.info);printf(“n“);6选择函数,用于程序运行结束后选择是否再来一局或者结束游戏。/选择设计void select(void)char c;while(1)system(“cls“);/清屏char a;printf(“请输入要选择的初始放牌序列输入 1 为随机,其他为顺序n“);scanf(“%c“,if(a=1)operate1();/判断输入else operate2();fflush(stdin);printf(“再玩一局?按
13、1 继续,按其他键退出!n 请输入选择:“);c=getchar();fflush(stdin);switch(c)case 1:select();default:exit(0);7主函数/定义主函数int main(int argc, char* argv)select();system(“color 3e“);return 0;2.实现主函数的流程图。.NN设一个一维数组 card52,并将所有变量赋初值为 1,表示直拍正面向上2=jj52jii52 j+开始YNY4. 函数之间的调用关系图i%j=0翻牌,如果 cardi-1为 0,则变为 1;如果为 1,则变为 0i+输出 card数组
14、中正面向上的序号结束Main()operate1 Operate2select() system(“color 3e“)l_bian()z_picture()shunxu()random()a=1l_bian()结束information(int info)四、 调试分析 1.这题的时间复杂度是 O(52)。按照操作指示,可以选择顺序放牌很随机放牌,选择后运行程序即可输出相应放牌顺序下的正面向上的牌。2.虽然本次程序的题目难度与其他问题想必不是很高,但是仍有很多问题我们是很容易忽视的,其一:在理解题目要求时,应注意翻拍次数可能很多次;其二:for 循环的嵌套使用在书写是很容易漏掉大括号。3.在
15、程序调试期间根据提示还是很容易找出问题,但是自己编写时就不会发现,应注意培养自己的严谨认真,4.编写完程序之后,发现程序要求很简单,但是我应该编写更多的玩法,由于刚接触MFC 感觉是个很好的工程,以后有机会可以利用 MFC 自己开发一个真正可以玩起来的纸牌游戏。五、测试结果1.其输入要选择的初始放排序列 1 为随机,其他为顺序。输入:1其输入一个正整数种子值。输入:1纸牌序列按顺序排列为。47 19 45 21 15 18 4 51 6 34 42 30 916 26 46 24 3 22 25 48 33 52 44 41 8 29 20 10 28 38 17 12 14 47 13 37
16、 32 5011 36 35 31 27 5 23 7 43 1 39 2正面向上的纸牌47 19 40 15 4 42 9 31 7 43 1 39再玩一局?按 1 继续,按其他键退出!n 请输入选择:输入:1(从新开始游戏)输入:其他(程序运行结束)2. 其输入要选择的初始放排序列 1 为随机,其他为顺序。输入:2其输入一个正整数种子值。输入:1纸牌序列按顺序排列为。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
17、 42 43 44 45 46 47 48 49 50 51 52 正面向上的牌。1 4 9 16 25 36 49再玩一局?按 1 继续,按其他键退出!n 请输入选择:输入:1(从新开始游戏)输入:其他(程序运行结束)六、用户手册1.输入摆放纸牌的顺序,1 为随机摆放,其他为顺序摆放。并输入一个种子值使程序运行。2.输出纸牌的摆放顺序,3.对应输出正面向上的纸牌。4.如果选择其他数字则纸牌为顺序摆放。5.顺序摆放时输出正面向上的纸牌。6.程序运行到最后,输入 1,重新运行程序。7.输入其他数字,例如 3 程序运行结束七、体会与自我评价 在为期不到两周的课程设计中,我体会颇多,学到很多东西。我
18、对如何用 MFC 编写可视化界面的应用程序还没有完全掌握,否则我相信这次程序我可以做得更加完美,留下了一点遗憾,但是自己亲自动手的机会还是使我加强了对C 的认识,复习了自己以前的知识,自己的逻辑思考能力也提高不少。从而对Microsoft Visual C+ 6.0 又有了更深入的认识!在这次课程设计中,我还懂得了程序开发的一些比较重要的步骤,比如需求分析、总体设计、数据库设计(含概念设计、逻辑设计、物理设计)、程序模块设计(含功能需求、用户界面设计、程序代码设计与分析、运行结果)、系统使用说明等。总之,通过这次课程设计,我收获颇丰,相信会为自己以后的学习和工作带来很大的好处。最重要的还是激发
19、了我编程的兴趣和热情,让我从一个只懂理论变成了能做一些小型程序,让我对编程更加热爱了。整体地评价这次课程设计,我认为收获很大,正如上面所说的那样,通过课程设计,既复习了以前的旧知识,又学到了一些新的知识;设计增强了我们用所学知识去解决具体问题的能力,进一步培养了我们独立思考问题和解决问题的能力。特别是学会了在 Visual C+ 集成开发环境中如何调试程序的方法。当然,老师的悉心指导和同学的帮助也是不可忽视的,在此感谢本次课程设计中所有辅导老师对我的关心和帮助,诚心诚意感谢他们对我的鼓励与教导,是她们在我迷茫的时候给了我些许提示,激发了我编程的灵感;在编写过程中遇到的问题也不再是翻不过去的大山
20、,在亲手写程序的过程中我真正体会到动手的乐趣,我慢慢学会了利用编程思想解决现实中的问题,把理论运用于实践,对于我们这些计算机学院的本科生来说,实际能力培养远至关重要,而这种实际能力的培养只从课堂上学习是远远不够的,必须从课堂组向实践,也是我们学习的目的。数据结构及其算法在解决现实生活中的常见问题和书写软件设计方面上都有着重要的意义,我们应该好好掌握它的相关知识,在以后的学习过程中,更多的学会如何与用知识。 源代码/ strong_poker.cpp : Defines the entry point for the console application./#include “stdafx.h
21、“#include “stdlib.h“#include “stdio.h“#include “iostream.h“typedef structint info; /纸牌编号int postion; /纸牌位置,从 1 开始计int state; /纸牌状态, 1 表示纸牌正面向上,0 表示纸牌背面向上card;#define NUM 52 /定义常量,方便调试和验证。typedef structcard cNUM;rcard;/纸牌横向边框void h_bian(void)int i;printf(“nt“); for(i=0;i10;i+)printf(“*“);/纸牌列向边框void
22、l_bian(void)int i,j;for(i=0;i2;i+)printf(“nt“);printf(“*“);for(j=0;j8;j+)printf(“ “);printf(“*“);/纸牌序号信息void information(int info)printf(“nt“);if(info10)printf(“* %d *“,info);elseprintf(“* %d *“,info);/纸牌正面void z_picture(int info)h_bian();l_bian();information(info);l_bian();h_bian();printf(“nn“);/获得
23、纸牌不同排序方式rcard Random()/ 产生随机序列rcard rc;int contNUM; /将需要的数存放到数组中,然后通过调换数组中数的位置,达到随机排列目的。unsigned int seed; /申明初始化器的种子,注意是 usigned int 型的int index, i,t; /初始化纸牌状态for(i=0;iNUM;i+)rc.ci.state=1;/对数组进行初始化for (i=0; iNUM; i+)conti = i+1;/提供随机种子printf(“请输入一个正整数种子值: n“);scanf(“%u“,srand(seed);/生成随机序列for (i=0
24、; iNUM-1; i+)/交换 NUM-1 次index=(rand()%(NUM-i-1)+i+1;/产生从 i+1 到 NUM-1 的一个随机数/交换t=conti;conti=contindex;contindex=t;printf(“纸牌编号按顺序排列为:n“);for(i=0;iNUM;i+)rc.ci.info=conti; /纸牌编号rc.ci.postion=i+1; /对应纸牌位置printf(“%d “, rc.ci.info);return rc;rcard shunxu()/产生顺序序列 rcard rc;int i;for(i=0;iNUM;i+)rc.ci.sta
25、te=1;printf(“纸牌编号按顺序排列为:n“);for(i=0;iNUM;i+)rc.ci.info=i+1; /纸牌编号rc.ci.postion=i+1; /对应纸牌位置printf(“%d “, rc.ci.info);return rc;void operate1(void)/操作函数 1,实现随机序列翻牌操作rcard rc;int i,j;rc=Random();/获得纸牌不同排序方式/翻面游戏for(j=2;j=NUM;j+) /j 为基数,也是开始翻面的位置for(i=j;i=NUM;i+)/i 为纸牌位置 if(rc.ci-1.info%j=0) rc.ci-1.st
26、ate=rc.ci-1.state?0:1;/打印,用纸牌图形打印。printf(“n 正面向上的牌有:“); for(i=0;iNUM;i+) if(rc.ci.state) z_picture(rc.ci.info);printf(“n“);void operate2(void)/操作函数 2,实现顺序序列翻牌操作rcard rc;int i,j;rc=shunxu();/获得纸牌不同排序方式/翻面游戏for(j=2;j=NUM;j+) /j 为基数,也是开始翻面的位置for(i=j;i=NUM;i+)/i 为纸牌位置 if(rc.ci-1.info%j=0) rc.ci-1.state=
27、rc.ci-1.state?0:1;/打印,用纸牌图形打印。printf(“n 正面向上的牌有:“); for(i=0;iNUM;i+) if(rc.ci.state) z_picture(rc.ci.info);printf(“n“);/选择设计void select(void)char c;while(1)system(“cls“);/清屏char a;printf(“请输入要选择的初始放牌序列输入 1 为随机,其他为顺序n“);scanf(“%c“,if(a=1)operate1();/判断输入else operate2();fflush(stdin);printf(“再玩一局?按 1 继续,按其他键退出!n 请输入选择: “);c=getchar();fflush(stdin);switch(c)case 1:select();default:exit(0);int main(int argc, char* argv)system(“color 3e“);select();return 0;