+c+程序设计 扑克牌游戏大学毕设论文.docx
《+c+程序设计 扑克牌游戏大学毕设论文.docx》由会员分享,可在线阅读,更多相关《+c+程序设计 扑克牌游戏大学毕设论文.docx(14页珍藏版)》请在冰豆网上搜索。
![+c+程序设计 扑克牌游戏大学毕设论文.docx](https://file1.bdocx.com/fileroot1/2023-2/3/0b5b62a2-fb53-4c71-a3d1-715bcab76b7f/0b5b62a2-fb53-4c71-a3d1-715bcab76b7f1.gif)
+c+程序设计扑克牌游戏大学毕设论文
齐鲁理工学院VC++课程设计报告
课程:
VC++课程设计
系别:
计算机科学与信息工程学院
班级:
学号:
选题2名称:
扑克牌游戏
选题2难易级别:
起止时间:
指导教师:
扑克牌游戏
一课题目标
1.1程序功能介绍创建一副扑克,并完成洗牌等操作。
1.2程序设计要求
(1)创建一副扑克,显示一副扑克,洗牌,依次分发给4个人并显示。
(2)删去一张扑克后,余牌显示。
(3)增加大小王
1.3评定难易级别:
A级
二具体实现
2.1程序总体方案
2.1.1开发平台操作系统:
Windows7开发工具:
VC++6.0
2.2源程序结构流程框图与说明(含新增子函数的结构框图以及界面)
洗牌
依次分发给4个人并显示
删去一张扑克后,余牌显示
Y
N
2.3课程设计的解答说明
创建一副扑克,并完成洗牌、发牌、显示、花色排序、面值排序、删除一张牌、删除一轮牌等操作。
本程序新建了PerDeck和PlayDeck两个类,类PerDeck表示某个人拿的牌,类PlayDeck表示四个人玩牌的过程,对原程序的修改较小。
程序中用到了包含在头文件stdlib.h中的函数srand(),用来初始化随机数种子,以使每次执行程序时函数rand()产生不同的随机数,从而使程序每次产生不同的运行结果,用到了包含在头文件time.h中的函数time(),用到了包含在头文件conio.h中的函数getch()用来接收用户从键盘键入的任意键,以起到暂停程序供用户查看运行结果的作用,还用到了包含在头文件stdlib.h中的函数system(),其参数为字符串,字符串cls代表清屏操作。
1.课程设计的任务分解
为了完成要求
(1)增加大小王,须将类Deck中的成员数据m_cardarray[]由52增加到54,用来创建一副包含大小王在内54张牌的扑克,并在创建扑克时为大小王重新赋值,如果num=52,则这张牌为小王并将这张牌的花色赋为1,面值赋为S,实际面值赋为14。
如果num=53,则这张牌为大王并将这张牌的花色赋为2,面值赋为B,实际面值赋为15。
为了完成要求
(2)删去一张牌后显示余牌,需先定义intDeleteAll(int,int,int,int)、intDeleteOne(int,int)、intDelete(int)和voidPerDeck:
:
Show()、voidPlayDeck:
:
Show()函数,并在程序执行期间调用intDeleteAll(int,int,int,int)、intDeleteOne(int,int)、intDelete(int)函数后调用voidPerDeck:
:
Show()、voidPlayDeck:
:
Show()函数。
为了完成要求(3)显示一副扑克,需在原来的基础上把函数ShowDeck()改成显示54张牌,洗牌函数也应改成对54张牌进行洗牌,用函数voidPlayCard(Deck&)来给玩家发牌,并调用函数voidPerDeck:
:
Show()、voidPlayDeck:
:
Show()显示玩家牌面。
2.课程设计的新增函数
voidPerDeck:
:
MakeperDeck(Deck&,int)
函数用来给每个玩家发牌,给第一个玩家和第二个玩家发14张牌,第三和第四个玩家发13张牌,其整型参数是发给玩家牌的张数,另一个引用参数是洗好的那副牌的对象,用来给玩家发牌。
voidPerDeck:
:
Show()//函数用来显示当前玩家手中的牌。
intPerDeck:
:
Delete(int)//函数用来删除一张牌
voidPerDeck:
:
SortFace()//函数用来把玩家手中的牌进行面值排序
voidPerDeck:
:
SortSuit()//函数用来把玩家手中的牌进行花色排序
PerDeck:
:
PerDeck(){}//类PerDeck的构造函数
voidPlayDeck:
:
PlayCard(Deck&)//函数用来调用函数
MakeperDeck(Deck&,int)//给玩家发牌,参数为洗好的那副牌的对象的引用。
voidPlayDeck:
:
Show()//用来显示四个玩家手中的牌。
intPlayDeck:
:
DeleteAll(int,int,int,int)//用来删除一轮牌,参数分别为四个玩家的第几张牌。
intPlayDeck:
:
DeleteOne(int,int)//用来删除一张牌,参数分别为第几个玩家的第几张牌。
voidPlayDeck:
:
SortDeckFace()//完成对四个玩家手中的牌按面值排序。
voidPlayDeck:
:
SortDeckSuit()//完成对四个玩家手中的牌按花色排序。
PlayDeck:
:
PlayDeck(){}//类PlayDeck的构造函数
三调试报告
3.1调试时界面显示情况
(1)显示完整的一副牌
(2)洗牌后分发给四个玩家并显示
(3)选择功能1时
(4)选择功能2时
(5)选择功能3时
(6)选择功能4时
(7)选择功能5时
3.2调试报告:
日期
遇到的问题
解决方法
9月25日
程序所需数据及函数较多,比较混乱
多增添两个类PerDeck和PlayDeck
10月05日
添加大小王时,产生整副牌时大小王的产生位置。
需要首先生成大小王,再产生其他牌,不然会产生多一张A和2
10月08日
发给四个人时分牌困难。
通过this指针来处理
10月10号
对书上的代码中的产生随机数及计算机洗牌不理解
上网查找类似的代码看注解以及问同学
10月15日
函数的界面太单调,不知道怎样创建程序主菜单
使用Program_Init();
Center_Text(char[]);
Get_Key()等函数实现
10月18日
对程序中的扑克牌的花色、面值赋值有点不理解
看书上的知识及问同学
四总体小结
问题1:
如何洗牌。
解决方法:
创建洗牌函数voidDeck:
:
DeckShuff(inttimes)//洗牌,参数为洗牌次数。
其中包括随机的实现,运用生成随机数的方法:
包含了头文件stdlib.h、time.h。
srand((unsigned)time(NULL));//time.h。
每个伪随机数都是通过在内部定义的一个特殊“数字压碎函数”由上一个伪随机数生成的,第一个伪随机数是由一个内部定义的变量生成的,该变量称为这个序列的种子。
在默认情况下,在程序每次运行时种子由计算机初始化为同一个值(默认为1),为了避免这种破坏随机性的现象,可以用srand()函数来选择自己的种子。
代码srand(seed)将定量seed的值赋给内部的“种子”,函数rand()使用该种子来初始化所产生的伪随机数序列,不同的种子会生成不同的结果。
必须输入一个seed的值的问题,可以使用计算机的系统时钟来解决,系统时钟以秒为单位跟踪当前的时间。
在头文件中定义的函数time()以一个unsigned整数返回当前时间,可以作为rand()函数的种子。
这样就能保证每次都能生成不同的随机数了。
intgetRandInt(intmin,intmax)//返回两个参数之间的一个整型随机值
{
intnumToReturn;
numToReturn=rand();//取得随机值
numToReturn=numToReturn%(max-min+1)+min;/*将随机值的范围调
整到两个参数之间*/
returnnumToReturn;
}
利用计算机的系统时钟做种子只能解决每次生成不同的随机数的问题,而作为扑克牌,每次生成的随机数应该是有一个严格的范围的。
所以设计了getRandInt函数来解决这个问题,代码如上。
但要完成洗牌不仅仅如此,洗牌需要将牌大致(随机函数)一分为二,然后交叉洗牌,重复N次。
代码如下:
voidDeck:
:
DeckShuff(inttimes)//洗牌,参数为洗牌次数
{
intx,split;//split是分开成两部分的位置,如上部分、下部分,即随机给两方分别发一副牌
Center_Text("洗牌……");
cout<for(x=0;x<=times;x++)//开始循环,每循环一次将牌全部重排一遍
{
split=getRandInt(20,35);//生成介于20和35之间的随机数,赋值给split,
Decktopdeck;//1副扑克牌类的对象topdeck,代表上部分的牌
Deckbottomdeck;//1副扑克牌类的对象bottomdeck,代表下部分的牌
inti;
intbottomdeckindex=1;//记录上部分发了多少张牌
inttopdeckindex=1;//记录下部分发了多少张牌
for(i=0;i<=split-1;)/*将初始的那副扑克牌的上边部分的张数赋值到
新生成的扑克牌对象中*/
{
topdeck.m_cardarray[topdeckindex]=this->m_cardarray[i];
topdeckindex++;
i++;
}
for(i=(split);i<54;)/*同样将初始那副扑克牌的下边部分的张数赋值到
新生成的扑克牌对象中*/
{
bottomdeck.m_cardarray[bottomdeckindex]=this->m_cardarray[i];
bottomdeckindex++;
i++;
}
intdeckoutindex=0;
intnumcardstomovetop;
intnumcardstomovebottom;
intj;
inth=0;
bottomdeckindex=54-split;//下部分那副扑克牌的张数
topdeckindex=split;//上部分那副扑克牌的张数
while(deckoutindex<=53)
{
numcardstomovetop=getRandInt(2,7);//从上部分抽取的张数,是2-7之间的随机数
numcardstomovebottom=getRandInt(2,7);//同样从下部分抽取的张数,是2-7之间的随机数
for(j=0;j<=numcardstomovebottom;j++)//从0开始循环numcardstomovebottom次
{
if(bottomdeckindex>0)//当下部分那副牌没有循环完时继续
{
this->m_cardarray[deckoutindex]=bottomdeck.m_cardarray[bottomdeckindex];
/*从下部分那副牌的最后张数开始,依次向初始的扑克牌赋值*/
deckoutindex++;
bottomdeckindex--;
}
for(h=0;h<=numcardstomovetop;h++)/*下部分的那副扑克牌赋值完成后,对
上部分的那副牌做同样的操作*/
{
if((topdeckindex>0)&&(deckoutindex<=54))
{
this->m_cardarray[deckoutindex]=topdeck.m_cardarray[topdeckindex];
deckoutindex++;
topdeckindex--;
}
}
}
}
}
this->m_lastdelt=-1;//将删除牌的张数复原为-1(未删除)
}
问题2:
如何实现花色排序和面值的排序。
解决方法:
可以使用冒泡排序法和选择排序法。
代码如下:
voidPerDeck:
:
SortFace()//按面值排序,使用了选择排序法
{
Playing_Cardrecord;//产生一个临时对象
for(intj=0;jfor(inti=j+1;iif(m_Card[j].m_Value>m_Card[i].m_Value)
{record=m_Card[i];m_Card[i]=m_Card[j];m_Card[j]=record;}
}
voidPerDeck:
:
SortSuit()//按花色排序,使用了冒泡排序法
{
Playing_Cardrecord;//产生一个临时对象
for(inti=0;ifor(intj=0;jif(m_Card[j].m_Suit>m_Card[j+1].m_Suit)
{record=m_Card[j];m_Card[j]=m_Card[j+1];m_Card[j+1]=record;}
}
心得体会:
开始进行设计时,总觉得无从下手,感觉这是一个不可能完成的任务。
后来在同学的建议下,将这学期C++所学的c++知识仔细的看了几遍,再开始看C++课程设计书。
鉴于对抗游戏和扑克牌游戏接近生活,对它们的设计要求理解比较透彻,所以选择了它们。
首先,先发了五天的时间看设计要求和源代码,然后才进行编写,经过对所编程序的不断调试和改写以及与他人编写的进行对比,最后终于使程序能正常运行了。
为了更好的进行更改,我把所编的程序打印下来,仔细的查看每个函数,用笔进行修改,然后再到程序上修改调试。
当然,在整个实验过程中,不断遇到各种问题,在同学的帮助下和自己的努力下,不断的解决问题,一次次的不断尝试,不断调节,使解决问题的能力有了提高。
并对程序的编写有了一定的了解,对将来的学习方向有了进一步的认识。
总之,课程设计可以充分发挥我的编程综合能力,将自己的编程知识串联起来,综合利用,自己的编程能力。
很高兴有这个机会促使我编程。
总之,在这个程序设计中的收获还是非常多的。
五分工介绍独立完成