
题目:编制一个猜数字游戏的程序。
一、需求分析
(1)该软件为玩家提供猜数字游戏的基本功能,游戏用户可以选择开始游戏、排行榜察看、帮助等功能。
(2)当用户选择开始游戏时,系统会提示用户排行榜上猜数字成绩的最好纪录,并让用户逐次猜数字后系统会给出本次猜数字的结果提示(如1A2B表示一个数字和位置都正确2个数字正确位置不正确)。
(3)如果用户猜数字次数超过10次则提示用户游戏失败,如果在10次内猜出了4个数字和正确的位置则提示用户游戏成功,并到排行榜中进行比较,如果排名在前5名则计入排行榜中,以便其他用户查看。
(4)在排行榜查看中可以按姓名和分数查看。在帮助中可以查看游戏规则。
二、概要设计
游戏分为五个模块:游戏区、排行榜、产生新记录、读取新记录、帮助。
程序中使用的变量:
int randnum[4],guessnum[4]; /*猜数数组*/
int i,j/*循环变量*/,temp/*中间变量*/;
struct record{
char name[20];
int score;
}rec[5],reco;/*记录变量*/
三、详细设计
1、 读最好记录:
printf("%s_%d ",rec[j].name,rec[j].score);
2、主界面选择功能:
scanf("%d",&i);/*选择功能*/
switch(i){
case 1:game();break;/*进入游戏*/
case 2:showrecinscore();break;/*按分查看排行榜*/
case 3:showrecinname();break;/*按姓名查看排行榜*/
case 4:Initrecord();printf("Clean success!!!\n");getch();break;/*初始化排行榜*/
case 5:help();break;/*查看帮助*/
case 6:printf("Thank You!ByeBye~");getch();break;/*退出游戏*/
default:printf("Input Error,Retry!");getch();/*选择错误*/
3、 进行游戏时:
for(a=b=0;a!=4&&chances>0;chances--){
printf("Now you just have %d chance:",chances);/*提示剩余机会*/
for(i=0;i<4;i++){/*读取用户猜的数字*/
scanf("%d",&temp);
if(temp>-1&&temp<10) guessnum[i]=temp;/*数据正确*/
else if(temp==99){/*用户放弃,显示答案*/
printf("\n\nYou give up this game!The key is %d %d %d %d\n",randnum[0],randnum[1],randnum[2],randnum[3]);
printf("Press any key to go on...\n");
getch();
return 0;
}
else {printf("Input Error!Retry!");i--;}/*输入错误*/
}
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(guessnum[i]==randnum[j]&&i==j) a++;/*位置和数字正确*/
else if(guessnum[i]==randnum[j]&&i!=j) b++;/*位置正确数字不正确*/
if(a==4){/*游戏成功*/
printf("Congratulations!You win!The number you guess is right!\n");
if((11-chances)<(rec[4].score)){/*破记录*/
refresh(chances);/*刷新排行榜*/
showrecinscore();/*按分数显示排行榜*/
return 1;
}
else{/*未破记录*/
printf("But your score doesn't break the record!\n\nPress any key to go on...\n");
getch();
return 1;
}
}
else{
printf("Wrong:%dA%dB\n",a,b);/*提示用户上次的猜数结果*/
a=b=0;/*a、b归零*/
}
}
printf("Sorry man!You Lose!The key is %d %d %d %d\n\nPress any key to go on...",randnum[0],randnum[1],randnum[2],randnum[3]);/*游戏失败*/
getch();
4、 产生随机数:
int index;/*下标变量*/
int numpool[10]={0,1,2,3,4,5,6,7,8,9};/*数据池*/
srand(time(0));/*随机数发生器*/
for(i=0;i<4;i++){
index=random(10-i);/*随机产生下标*/
randnum[i]=numpool[index];/*在数据池中取下标对应的数*/
temp=numpool[index],numpool[index]=numpool[9-i],numpool[9-i]=temp;/*从数据池中删去已取的数*/
}
5、 刷新排行榜:
char *newname;
for(i=0;i<5;i++)
if((11-chances)<(rec[i].score))/*找插入位置*/{
for(j=4;j>i;j--)
rec[j].score=rec[j-1].score,strcpy(rec[j].name,rec[j-1].name); /*记录后移*/
printf("!!!New record!!!\nPlease input you name:");
newname=(char*)malloc(100*sizeof(char));/*创建新记录信息*/
scanf("%s",newname);/*新纪录姓名*/
strcpy(rec[i].name,newname);/*写入姓名*/
rec[i].score=11-chances;/*写入分数*/
return 1;
}
6、 按姓名显示排行榜:
struct record recname[5],temp;
clrscr();/*清屏*/
for(i=0;i<5;i++)
recname[i]=rec[i];/*转移排行信息到recname中*/
for(i=1;i<5;i++)
for(j=0;j<5-i;j++)
if(strcmp(recname[j].name,recname[j+1].name)>0){
temp=recname[j],recname[j]=recname[j+1],recname[j+1]=temp;
/*将recname中数据按姓名排序*/}
printf(" score name\n");
for(i=0;i<5;i++){/*输出*/
printf("%d ",i+1);
printf(" %d %s\n",recname[i].score,recname[i].name);
}
printf("Press any key to go on...");
getch();
7、 函数调用关系图:
见附图
四、 测试分析
(1)本次作业中难点是刷新排行榜,由于文件的操作未学习,所以存储和读取文件的操作也显得难了。
(2)刚开始我用指针存储字符串,没注意到指针未分配空间的危险,导致后面输入的字符记录覆盖先前保存的字符记录。后接受网友推荐使用字符数组,问题解决。
(3)字符串的赋值用strcpy函数,直接赋值到数组不行。
(4)文件保存无法实现保存到任意位置。老师说用Turbo C实现很难。
(5)产生随机数刚开始直接用random函数,发现会有重复出现,后使用数据池,用random产生数据池的下标,然后从数据池中读数据,再从数据池中删去该数据,这样就不会出现重复的情况。
(5)更新排行榜使用冒泡排序的思想,我用的是先找插入位置再插入,老师说先插到第五名再冒泡排序,其实后来计算发现二者时间复杂度一样。因为我的两层循环不会全部执行,因里面含有return语句。老师接受了此方法。
(6)程序用了过多的全局变量,有的完全可以变成局部变量。
五、使用说明
(1)本程序的运行环境为DOS操作系统,执行文件为:猜数字.exe
(2)进入程序后,程序读文件记录,按回车,进入主界面。
(3)输入1:开始游戏2:按分看排行3:按名看排行4:清空排行榜5:帮助6:退出
(4)进入“开始游戏”后,输入4个个位数,中间空格隔开。猜数正确且破记录进入排行榜,显示排行榜,每人10次机会。
六、测试结果
游戏界面:
暂无
猜数字过程:
暂无
按分显示排行榜:
暂无
按名显示排行榜:
暂无
七、附录
源程序文件名清单:
variable.txt/*变量*/
GAME.TXT/*开始游戏*/
help.txt/*帮助文件*/
INITREC.TXT/*初始化排行榜*/
MENU.TXT/*游戏界面*/
R_REC.TXT/*读记录到内存*/
randnum.txt/*产生随机数*/
refresh.TXT/*刷新排行榜*/
showrec1.txt/*按分看排行榜*/
showrec2.txt/*按名看排行榜*/
w_rec.txt/*写记录到硬盘*/
record.rec/*记录文件*/
main.c/*主程序*/
给个算法
int iInput[4];//Y输入的数字
int iNumber[4];//原数字
char cOutPut[4];//?A?B
int iA,iB;
iA = 0;
iB = 0;
for (int i=0;i<4;i++)//遍历Y所给的数字
{
if (iInput[i] == iNumber[i])//如果和原数字对应位相等
{
iA++;//A的数字自加
}
else//如果不等 遍历原数字 查找是否有相等的数字
{
for(int j = i;j<4)
{
if (iInput[i] == iNumber[j])//如果找到相等
{
iB++;//B的个数自加
}
}
}
}
cOutPut = iA + 'A'+iB+'B';