C++课程设计报告
( 20## -- 20## 年度第二学期)
猜数游戏
目 录
目 录. 2
1 概 述. 1
1.1 课程设计目的. 1
1.2 课程设计内容. 1
2 系统总体设计. 1
2.1 系统目标. 1
2.2 主体功能. 2
2.3 系统流程. 3
2.4 开发环境. 5
3系统详细设计. 5
3.1系统主界面设计. 5
3.2 提示键H、K的模块设计. 6
3.3统计分数模块设计. 8
4 测试. 9
4.1 测试方案. 9
4.2 测试结果. 10
5 小结. 11
参考文献. 13
附 录. 14
附录1 源程序清单. 14
猜数游戏的设计与实现
1 概 述
1.1 课程设计目的
a)巩固并加深学生对C++语言程序设计知识的理解;
b)培养学生面向对象的程序设计思想,使学生认识面向过程和面向对象两种设计方法的区别;
c)进一步掌握和应用VC++ 6.0集成开发环境;
d)提高运用C++语言解决实际问题的能力;
e)初步掌握开发小型实用软件的基本方法,能独立设计、实现具有实际功能的小系统;
f)掌握书写程序设计开发文档的能力(书写课程设计实验报告)
1.2 课程设计内容
课程名称:猜数游戏
说明:用户从键盘输入4位不重复的数,来匹配计算机给出的4位随机数,若数字和位置均等同,表示用户赢了。每猜一次,计算机均给出提示信息(x,y),x表示数字、位置都匹配的个数,y表示数字匹配但位置不匹配的个数。
要求:
a)设计友好的中文用户交互界面。
b)按H键,可得到更详细的帮助信息。
c)按K键后,可以查看计算机所给的4位数,但查看前需要输入密码,密码自定。
d)猜的结果以分值的形式给出,每猜错1次扣100分,若猜对1个数,奖励20分。
e)每次游戏结束后将分值存盘,文件名自定。
2 系统总体设计
2.1 系统目标
该题目是一个通过自己的推断猜数字小游戏。编写该程序要完成实现系统自定义四位不同数字、输入四位不同数字、判断输入的四位不同数字的对错情况的功能以及玩游戏时的提示功能、管理功能和与退出功能。
这次课设是要求用C++编写程序,实现数字之间的相互比较,让玩家找出电脑写的四位数字,而玩家在找出四位数字中,电脑需要给出玩家一些提示信息,用以帮助玩家找出答案。对于猜位数不等的四位数,电脑需要在程序刚运行时,确定一个随机的四位数,且各个位数不相等。而在玩家输入数字时,也需要检验玩家输入的数字是否满足条件,即一个各个位数不重复的四位数。只有玩家输入正确的数字后,电脑才能进行比较数字的运算,如果玩家输入的数字和电脑的不相等,输出提示信息,并应从新读取玩家的数字进行判断,直到玩家放弃猜数字或数字猜对为止。
当玩家在玩游戏时每输入一次四位不同数字电脑都会给出位置数字对错的的信息,并对此算出所得分数(每猜错1次扣100分,若猜对1个数,奖励20分。
)。但玩家经过多次猜测还没猜出答案可以使用提示的功能即比较详细的叙述玩家所猜的数字的数字和位置的对错情况。当玩家想知道电脑给出的数字时可以使用管理功能输入正确的密码可以知道电脑所给的正确答案。当玩家不想玩此游戏可是使用退出键并且在退出时电脑会给玩家正确的答案。
2.2 主体功能
该游戏的主体功能主要有以下几个重要的模块:电脑实现自定义模块、电脑对玩家所猜数字进行处理的模块、电脑处理玩家游戏排名模块以及电脑处理玩家退出游戏的模块。
其中电脑自定义模块在玩家开始玩游戏时电脑事先确定好四位不同数字作为正确数字供玩家猜测;对玩家数字所猜测的数字处理模块主要就是把玩家所猜测的数字与正确答案做个比较然后反馈给玩家;玩家排名模块就是把各个玩家玩的游戏统计所得分数并且做出比较排列出前三名;退出模块主要是玩家想放弃游戏时做游戏作出处理并与此同时告诉玩家答案。
该游戏的各个模块功能如下图所示:
图2-1 系统功能模块图
2.3 系统流程
如下图所示我画的总体流程图想要展现的是,开始玩家进入游戏电脑自定义一组四位不同数字供玩家猜测,接着开始游戏玩家输入四位不同数字电脑会对这组数字与正确答案做出比较并告知玩家,接着玩家可有两种选择一是是否继续猜数,二是是否需要提示。其中如果需要提示通过使用快捷键电脑会给玩家详细的错误提醒。如果继续游戏那么回到开始输入四位不同数字阶段,但是如果玩家想退出游戏可以使用快捷键退出游戏。在玩游戏的过程玩家每猜一次电脑都会给玩家所得分数
2.4 开发环境
该程序是在windows系统下的C++语言开发和应用VC++ 6.0集成开发环境。
3系统详细设计
3.1系统主界面设计
该界面清晰易懂,主要包括游戏的前三名、游戏的汉字提醒以及键盘输入提醒。游戏名次排序可以展现玩家玩此游戏的熟练程度以及玩此游戏能力,说已设立了游戏的名次排序可以激发游戏者竞争意识。游戏界面的提醒部分可以使游戏者熟练的玩此游戏,以及游戏的功能。
主要代码有:
cout<<"输入您所猜测的4位不同的数字(输入9999退出,输入H帮助,输入K管理):"<<endl;
cout<<"****************游戏金榜****************"<<endl;
cout<<"**第1名"<<mark1<<endl<<"**第2名"<<mark2<<endl<<"**第3名"<<mark3<<endl;
其主要界面如下:
3.2 提示键H、K的模块设计
玩家在玩游戏时通过H、K键完成游戏的帮助和管理。当玩家想放弃玩游戏想知道正确答案时可以使用K键,但是因为属于管理者的捷径所以要输入密码。当密码输入错误时界面会提示输入错误玩家会再次进入游戏状态。但玩家玩游戏时觉得比较难不好猜测可以使用H键,电脑会给出详细的提示(例如:玩家要猜测的数字4369可是玩家猜测是3568这时使用H键电脑会给出提示“您的第一位数字猜对,但位置不对;您的第三位数字猜对,位置猜对”)
其详细的流程图如下:
3.3统计分数模块设计
玩家在玩游戏输入四位不同数字之后电脑系统会为玩家做一次分数统计。游戏开始时电脑给玩家自定义分数为1000分,当玩家开始猜数的游戏时没猜错一次扣100分,若猜对一个数,奖励20分。(例如:玩家要猜数9852,但玩家输入1234时玩家得分为960分当玩家再次输入数字1235时玩家得分为920分)
其流程图如下所示:
4 测试
4.1 测试方案
测试方案一:测试执行时出现重复的情况
图4-1 错误输入数字执行图
测试方案二:测试在需要帮助时键盘输h及H的情况
图4-2 在键盘输入小写字母错误时执行情况
4.2 测试结果
测试结果一:但玩家想知道游戏答案时可以输入大写字母K并输入密码得以实现
图4-3 玩家进行管理状态执行情况
测试结果二:玩家如果想结束游戏输入9999来实现
图4-4 玩家终止游戏的情况
测试结果三:玩家想知道游戏答案是密码输入密码错误。
图4-5玩家执行公布游戏答案密码错误的情况
5 小结
这周的课程设计就要结束了。从最开始的做题到现在的报告总结我完成一个过程。在这个过程里我领悟了很多。
在最开始的做实验报告时感觉挺难的之前根本就没有写过关于游戏的实验报告,不过还好我以前没事的时候玩过这游戏,所以比较了解这个游戏各个部分。虽然在中间写的过程中还有很多不会的东西,但是通过查看书本和资料还有问同学和老师,基本上都解决了。其中有一部分的程序无法满足题目的要求 在老师的帮助下最后得到了解决,通过这件事我感觉自己还有还有很多不足,仍然有一些有待提高的地方。
我觉得课程设计的作用一方面是最基本的就是要完成这一科目,差不多也是对自己的一个阶段性的总结;还有就是在整个设计的过程中,让我们认真的独立思考,在和同学交流的过程中也增强了我们的语言组织能力和彼此之间的友谊。通过课程设计让我们不断的发现自己的不足从而去改善,这是一种学习的态度,不仅仅是在这次的课程设计中,在以后的无论生活还是学习方面都应该注意和努力改善。通过这次比较完整的一个程序的设计,我摆脱了单纯的理论知识学习状态,和实际设计的结合锻炼了我的综合运用所学的基础知识,解决实际问题的能力,同时也提高我查阅文献资料、对程序整体的把握等其他能力水平,而且通过对整体的掌控,对局部的取舍,以及对细节的斟酌处理,都使我的能力得到了锻炼,经验得到了丰富。这是我们都希望看到的也正是我们进行课程设计的目的所在。虽然设计内容繁多,过程繁琐但我的收获却更加丰富。各种组件的运用,各种算法的应用,各种控件的利用我都是随着设计的不断深入而不断熟悉并逐步掌握的。和老师以及同学的沟通交流更使我对程序整体的规划与设计有了新的认识也对自己提出了新的要求。提高是有限的但提高也是全面的,正是这一次设计让我积累了许多实际经验,也必然会让我在未来的工作学习中表现出更高的应变能力和理解力。
参考文献
[1]谭浩强.C++程序设计(第二版)[M].北京:清华大学出版社,2012.
[2]谭浩强.C++程序设计题解与上机指导(第二版)[M].北京:清华大学出版社,2012.
附 录
附录1 源程序清单
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <cstdlib>
using namespace std;
int x1,x2,x3,x4;
int y1,y2,y3,y4; //定义全局变量来记录玩家猜数的情况
void FetchHisGuess(int&,int&,int&,int&);
void CompNumber(int&,int&,int&,int&);
bool End(int,int,int,int);
bool Help(int,int,int,int,int&,int&,int&,int&,int&,int&,int&,int&);
bool Manage(int,int,int,int,int,int,int,int);
void TextX(int,int,int,int,int,int,int,int,int&,int&,int&,int&);
void TextY(int,int,int,int,int,int,int,int,int&,int&,int&,int&);
bool Begin(int,int,int);
void rank();
void ReadMark(); //输出保存得分的前三名
int nCount=1000;
static int mark1=0,mark2=0,mark3=0;
int main()
{
ReadMark();
int iHisA,iHisB,iHisC,iHisD; //用户输入值
int iComA,iComB,iComC,iComD;
bool bDone=false;
bool bEnd=false;
int iGuessCounter=1;
while (bEnd==false)
{
iHisA=0,iHisB=0,iHisC=0,iHisD=0;
iComA=0,iComB=0,iComC=0,iComD=0;
x1=0,x2=0,x3=0,x4=0;
y1=0,y2=0,y3=0,y4=0;
bDone=false;
int iGuessCount=1;
CompNumber(iComA,iComB,iComC,iComD);
while(bDone==false)
{
nCount-=40;
FetchHisGuess(iHisA,iHisB,iHisC,iHisD);
nCount+=(x1+x2+x3+x4)*20; //每猜对1个数的位置加20
bEnd=End(iHisA,iHisB,iHisC,iHisD);
if(Help(iHisA,iHisB,iHisC,iHisD,x1,x2,x3,x4,y1,y2,y3,y4)==true)
continue;
if(Manage(iHisA,iHisB,iHisC,iHisD,iComA,iComB,iComC,iComD)==true)
continue;
x1=0,x2=0,x3=0,x4=0;
y1=0,y2=0,y3=0,y4=0;
TextY(iHisA,iHisB,iHisC,iHisD,iComA,iComB,iComC,iComD,y1,y2,y3,y4);
TextX(iHisA,iHisB,iHisC,iHisD,iComA,iComB,iComC,iComD,x1,x2,x3,x4);
if(bEnd==true)
{
cout<<"[正确的结果]"<<iComA<<iComB<<iComC<<iComD<<endl;
cout<<"您的最终得分:"<<nCount<<"欢迎下次再玩!"<<endl;
bDone=true;
rank();
}
else
{
if((x1+x2+x3+x4)==4)
{
cout<<"正确"<<endl<<"您一共猜了"<<iGuessCounter<<"次"<<endl;
nCount+=100;
bDone=true;
}
else
{
cout<<"您有"<<x1+x2+x3+x4<<"位数字位置匹配,"<<y1+y2+y3+y4<<"位数字数字匹配,"<<4-(x1+x2+x3+x4)-(y1+y2+y3+y4)<<"位数字不对"<<endl;
cout<<"您的得分是"<<nCount<<endl;
rank();
iGuessCounter++;
}
}
}
}
return 0;
}
void FetchHisGuess(int&iHisGuess1,int&iHisGuess2,int&iHisGuess3,int&iHisGuess4)
{
while(true)
{
cout<<"输入您所猜测的4位不同的数字(输入9999退出,输入H帮助,输入K管理):"<<endl;
scanf("%c",&iHisGuess1);
//10代表换行,去除上一次输入之后的换行符
if(iHisGuess1==10)
{
scanf("%c",&iHisGuess1);
}
if(iHisGuess1==10)
{
scanf("%c",&iHisGuess1);
}
if(iHisGuess1=='K')
{
iHisGuess1=iHisGuess2=iHisGuess3=iHisGuess4=7;
return;
}
if(iHisGuess1=='H')
{
iHisGuess1=iHisGuess2=iHisGuess3=iHisGuess4=8;
return;
}
iHisGuess1=iHisGuess1-0x30;
scanf("%1d%1d%1d",&iHisGuess2,&iHisGuess3,&iHisGuess4);
if((iHisGuess1==9&&iHisGuess2==9&&iHisGuess3==9&&iHisGuess4==9)||(iHisGuess1==8&&iHisGuess2==8&&iHisGuess3==8&&iHisGuess4==8)||(iHisGuess1==7&&iHisGuess2==7&&iHisGuess3==7&&iHisGuess4==7))
{
return;
}
if(iHisGuess1==iHisGuess2||iHisGuess1==iHisGuess3||iHisGuess1==iHisGuess4||iHisGuess2==iHisGuess3||iHisGuess2==iHisGuess4||iHisGuess3==iHisGuess4)
{
cout<<"错误的输入,请重新输入[需要输入4位不同的数字]"<<endl;
continue;
}
return;
}
}
void CompNumber(int&a,int&b,int&c,int&d)
{
srand(time(0));
bool bIS=false;
while(bIS==false)
{
a=1+(rand()%9);
b=1+(rand()%9);
c=1+(rand()%9);
d=1+(rand()%9);
if(a!=b&&a!=c&&a!=d&&b!=c&&b!=d&&c!=d)
{
bIS=true;
}
else{bIS=false;}
}
}
bool End(int a,int b,int c,int d)
{
if(a==9&&b==9&&c==9&&d==9)
{
return true;
}
else
{
return false;
}
}
bool Help(int a,int b,int c,int d,int &x1,int &x2,int &x3,int &x4,int &y1,int &y2,int &y3,int &y4)
{
if(a==8&&b==8&&c==8&&d==8)
{
if(x1) cout<<"您的第1位数字和位置均不对"<<endl;
if(x2) cout<<"您的第2位数字和位置均不对"<<endl;
if(x3) cout<<"您的第3位数字和位置均不对"<<endl;
if(x4) cout<<"您的第4位数字和位置均不对"<<endl;
if(y1) cout<<"您的第1位数字猜对,但位置不对"<<endl;
if(y2) cout<<"您的第2位数字猜对,但位置不对"<<endl;
if(y3) cout<<"您的第3位数字猜对,但位置不对"<<endl;
if(y4) cout<<"您的第4位数字猜对,但位置不对"<<endl;
if(!(x1||x2||x3||x4||y1||y2||y3||y4))
cout<<"您输入的位置与数字均未猜对"<<endl;
return true;
}
else
return false;
}
bool Manage(int a,int b,int c,int d,int iComA,int iComB,int iComC,int iComD)
{
int iPasswd;
if(a==7&&b==7&&c==7&&d==7)
{
cout <<"请输入密码:"<<endl;
scanf("%d",&iPasswd);
if(iPasswd==1234)
{
cout<<"正确的数字为"<<iComA<<iComB<<iComC<<iComD<<endl;
}
else{cout<<"密码错误"<<endl;}
return true;
}
else {return false;}
}
void ReadMark()
{
ifstream infile;
infile.open("Game.dat",ios::in);
if(infile) infile>>mark1>>mark2>>mark3; //输出前三名
cout<<"****************游戏金榜****************"<<endl;
cout<<"**第1名"<<mark1<<endl<<"**第2名"<<mark2<<endl<<"**第3名"<<mark3<<endl;
infile.close();
}
void rank()
{
if(nCount>=mark1)
{
mark3=mark2;
mark2=mark1;
mark1=nCount;
}
else if(nCount>=mark2)
{
mark3=mark2;
mark2=nCount;
}
else if(nCount>=mark3)
mark3=nCount;
ofstream outfile;
outfile.open("Game.dat",ios::out);
outfile<<mark1<<"\n"<<mark2<<"\n"<<mark3<<"\n";
outfile.close();
}
void TextX(int iHisA,int iHisB,int iHisC,int iHisD,int iComA,int iComB,int iComC,int iComD,int &x1,int &x2,int &x3,int &x4)
{
if(iHisA==iComA) x1++; //第一位的数字判断
if(iHisB==iComB) x2++;
if(iHisC==iComC) x3++;
if(iHisD==iComD) x4++;
}
void TextY(int iHisA,int iHisB,int iHisC,int iHisD,int iComA,int iComB,int iComC,int iComD,int &y1,int &y2,int &y3,int &y4)
{
if(iHisA==iComB||iHisA==iComC||iHisA==iComD) y1++; //第一位的位置判断
if(iHisB==iComA||iHisB==iComC||iHisB==iComD) y2++;
if(iHisC==iComA||iHisC==iComB||iHisD==iComD) y3++;
if(iHisD==iComA||iHisD==iComB||iHisD==iComC) y4++;
}