福建农林大学计算机与信息学院
计算机类
课程设计报告
20##年11月
面向对象程序设计(课程设计)成绩评定表
目 录
1. 课题来源.................................................................................................................. 1
2. 任务描述.................................................................................................................. 1
2.1. 课题的总体结构............................................................................................ 1
2.2. 核心功能模块与类设计................................................................................ 2
2.3. 任务分工与工作量说明................................................................................ 3
3. 程序(系统)详细设计.......................................................................................... 3
4. 程序(系统)实现与测试...................................................................................... 5
5. 分析与讨论............................................................................................................. 11
6. 结束语.................................................................................................................... 12
1. 课题来源
该作品为原创。
课题灵感是能否做一个小游戏,寻找了很多小游戏比如俄罗斯方块等,发现其太复杂以目前的水平无法完成,于是就选择了一个比较简单的猜数字游戏,编写益智类的游戏可以让我们日常生活中自己使用来达到增加乐趣的作用。
猜数字游戏的原游戏规则:通常由两个人玩,一方出数字,一方猜。出数字的人要想好一个没有重复数字的4位数,不能让猜的人知道。猜的人就可以开始猜。每猜一个数字,出数者就要根据这个数字给出几A几B,其中A前面的数字表示位置正确的数的个数,而B前的数字表示数字正确而位置不对的数的个数。
如正确答案为 5234,而猜的人猜 5346,则是 1A2B,其中有一个5的位置对了,记为1A,而3和4这两个数字对了,而位置没对,因此记为 2B,合起来就是 1A2B。
接着猜的人再根据出题者的几A几B继续猜,直到猜中(即 4A0B)为止。
原游戏规则是两个人玩,于是我们想到了将规则改为人机对战,电脑出题玩家来猜。
2. 任务描述
猜数字游戏:产生随机数,统计完全猜中的数字的个数以及统计猜中但位置错误数字的个数,并给出提示。最后计算积分。此程序体现了面向对象程序设计的继承性和封装性。
2.1.课题的总体结构
类层次结构图:
程序有三个类,
其中randNumber类用来产生随机数,
contrast类用来做对比并得出猜数字的结果,
score类用来读取文件内容并统计分数,
主函数进行循环输入猜数字,并将结果输入文件。
程序的功能结构图:
2.2.核心功能模块与类设计
采用表格的形式,按照类在课题中的作用,列出核心类的功能定义和主要函数接口。
2.3.任务分工与工作量说明
3. 程序(系统)详细设计
按照程序(系统)的总体结构,详细介绍程序中各个类和函数的设计思想和实现方法,并以图的方式说明程序的流程图。
randNumber类实现答案所需的随机数的产生
contrast类为核心类,继承至randNumber类,实现猜数字游戏主要玩法的设计
4. 程序(系统)实现与测试
(1) 给出典型的程序(系统)执行结果图。
开始界面:
猜数字界面:
猜对时的显示界面:
破纪录时的显示界面:
更新后的排行榜:
(2) 程序(系统)实现的功能
随机数字的产生:产生四个随机数字分别代表四位数的四个位
数字正误判断:给出既猜对位置也猜对的数字的个数以及猜对但是位置不对的数字的位置。
积分计算:猜错按0分算,一次就猜对100分,两次猜对90分,三次80分……以此类推,最后一次猜对得20分。
记录成绩的功能:给出排行榜记录前三名的成绩,保存在score.txt文件中。
(3) 根据课题的特性,列出带有详细注释的核心功能模块或类代码;
源程序代码:
随机数:
class randNumber{
int num1;
int num2;
int num3;
int num4;
int ran(){
srand( (unsigned)time( NULL ) );
for(int i=0;i<10;i++){
return (rand()%10);
}
}//返回0-9的一个随机数
public:
void randNum(){
cout<<"正在产生随机数..."<<endl;//大概因为算法的问题产生随机数这个过程比较慢所以做个提示
num1=-1;
num2=-1;
num3=-1;
num4=-1;//清除上次的随机数记录,使得下次产生随机数与上次不冲突
num1=ran();
do{
num2=ran();
}
while(num2==num1);
do{
num3=ran();
}
while(num3==num1||num3==num2);
do{
num4=ran();
}
while(num4==num1||num4==num2||num4==num3);
};//产生四个不同的随机数
int getnum1(){
return num1;
}
int getnum2(){
return num2;
}
int getnum3(){
return num3;
}
int getnum4(){
return num4;
}
};//获取随机数的方法
用于比较:
class contrast:public randNumber{
int A;
int B;//用于记录结果(几A几B)
int n1;
int n2;
int n3;
int n4;//(用于记录输入的数字)
public:
void setNum(int a1,int a2,int a3,int a4){
n1=a1;
n2=a2;
n3=a3;
n4=a4;
}
void count(){
A=0;
B=0;//每一次都重置A、B
if(n1==getnum1()){A++;}
if(n2==getnum2()){A++;}
if(n3==getnum3()){A++;}
if(n4==getnum4()){A++;}//统计完全猜中的数字的个数(A)
if(n1==getnum2()||n1==getnum3()||n1==getnum4()){B++;}
if(n2==getnum1()||n2==getnum3()||n2==getnum4()){B++;}
if(n3==getnum2()||n3==getnum1()||n3==getnum4()){B++;}
if(n4==getnum2()||n4==getnum3()||n4==getnum1()){B++;}//统计猜中但位置错误数字的个数(B)
}
int getA(){
return A;
}
int getB(){
return B;
}
void setA(int a){
A=a;
}
};
class score{
int s1;
int s2;
int s3;//用于记录前三名积分
public:
int getS1(){
return s1;
}
int getS2(){
return s2;
}
int getS3(){
return s3;
}//用于获取积分的方法
void setS1(int b1){
s1=b1;
}
void setS2(int b2){
s2=b2;
}
void setS3(int b3){
s3=b3;
}//用于最后修改积分排名
score(){
s1=0;
s2=0;
s3=0;
FILE *fp;
fp=fopen("score.txt","r");//打开文件
if(!fp){
cout<<"当前暂无积分排名"<<endl;
}
else{
cout<<"积分排行榜:"<<endl;
fscanf(fp,"%d",&s1);
cout<<" 第一名:"<<s1<<endl;//读取第一个数字存入变量s1
fscanf(fp,"%d",&s2);
cout<<" 第二名:"<<s2<<endl;//读取第二个数字存入变量s2
fscanf(fp,"%d",&s3);
cout<<" 第三名:"<<s3<<endl;//读取第三个数字存入变量s3
cout<<endl;
fclose(fp);
}
}
};
主函数:
void main(){
score score;//从文件读取并输出上次成绩
contrast number;
int s=0;//用于统计总分
do{
number.randNum();
int n1,n2,n3,n4;
int k=9;//用于统计剩余次数
do{
cout<<"请输入您所猜的四位数字"<<endl;
scanf("%1d%1d%1d%1d",&n1,&n2,&n3,&n4);//输入数字
while(n1==n2||n1==n3||n1==n4||n2==n3||n2==n4||n3==n4){//当输入的数字中含有相同的数字
cout<<"请重新输入正确格式的数字"<<endl;
scanf("%1d%1d%1d%1d",&n1,&n2,&n3,&n4);//若输入格式错误重新输入
}
number.setNum(n1,n2,n3,n4);
number.count();
cout<<endl;
cout<<number.getA()<<"A"<<number.getB()<<"B"<<endl;//输出结果(几A几B)
k--;//剩余次数减1
if(number.getA()==4){
cout<<"你猜对了"<<endl;
cout<<"你的本轮得分为"<<(20+10*k)<<"分"<<endl;//统计本轮得分
s+=(20+10*k);//统计总分
cout<<"你的总分为"<<s<<"分\n"<<endl;//统计总分
char yn;
cout<<"请输入Y(继续)或N(退出)"<<endl;
do{
cin>>yn;
if(yn=='N'||yn=='n'){number.setA(-1);}
}while(yn!='Y'&&yn!='y'&&yn!='N'&&yn!='n');//当输入格式正确时退出循环
}
if(number.getA()!=4&&number.getA()!=-1){
cout<<"你还有"<<k<<"次机会"<<endl;
}
cout<<endl;
}while(number.getA()!=4&&k!=0&&number.getA()!=-1);//次数用完或者猜对时选择N退出循环
if(number.getA()!=4&&number.getA()!=-1){
cout<<"机会用完了,游戏结束"<<endl;
cout<<"正确的数字为"<<number.getnum1()<<number.getnum2()<<number.getnum3()<<number.getnum4()<<endl;
cout<<"你的本轮得分为0分"<<endl;
}
}while(number.getA()==4);//当猜对时循环结束
cout<<endl;
cout<<"你的最终得分为"<<s<<"分"<<endl;
if(s>score.getS3()&&s<score.getS2()){
score.setS3(s);
}//当成绩介于第二名和第三名时替换第三名成绩
if(s>score.getS2()&&s<score.getS1()){
score.setS3(score.getS2());
score.setS2(s);
}//当成绩介于第一名和第二名时修改二、三名成绩
if(s>score.getS1()){
score.setS3(score.getS2());
score.setS2(score.getS1());
score.setS1(s);
}//当成绩大于第一名时修改第一、二、三名成绩
if (s>score.getS3()){
cout<<"你破记录了!你的成绩将写入新记录中"<<endl;
FILE *stream;
stream = fopen( "score.txt", "w" );
fprintf( stream, "%d %d %d",score.getS1(),score.getS2(),score.getS3());//将成绩写入文件
}
}
(4) 游戏开始之前会产生一个随机的4位数字,然后会让玩家输入自己猜的数字,在猜的数字为有重复的4位数或者不为4位数时会提示输入数字错误并返回重新输入。
比如输入错误格式的数字后(数字中有两个1,位数重复)
结果提示重新输入正确格式的数字
5. 分析与讨论
程序提供了一个猜数字的游戏,程序解决了产生随机数,判断猜中数字的位数、计算积分,保存成绩的问题。
但是在产生随机数的方面处理不够完善,随机数产生耗时过长。
在进行此程序设计的过程中,发现我们还有很多方面不会,必须一边查书一边进行设计,其中文件读取和写入功能还用到了百度,下次进行设计时会拓展自己的知识。
6. 结束语
进行此课程设计,让我们发现自己很多的不足,也在设计的过程中进行查询,得到很多以前不会的知识,并且发现团队合作的重要性,只有团队更好地合作才能写出更好,更精简的代码。