本文清晰的介绍了猜数字游戏的实现,完全是由浅入深的例子,如果只需要某些部分的指导,只需要跳转到那一部分即可,且内容仅供参考。
一、游戏大体思路
首先我们需要对该游戏有一个清晰地认识:具体的玩法是在一个数范围内,游戏会自动生成一个随机数,我们需要在他的条件下,找出这个数,当所猜的数字大于随机数时,需要报出“猜大了”,当所猜的数字小于这个随机数时,需要报出“猜小了”。
1.1、需要具备的条件
由上面的条件可以看出,我们的代码需要具备以下条件
1.系统自动生成随机数
2.猜大时——系统提示猜大了;猜小时——系统提示猜小了
该游戏可能不止玩一次,所以可能会用到循环方面的知识。
1.2、相关的内容
1.2.1 随机数的生成
在C语言当中提供了一个函数rand可生成随机数
在此处对rand有一个详细的介绍Reference - C++ Reference (cplusplus.com)可以在这个网站上查找相关的函数。
在此,说明一下使用rand函数需要注意的问题
1.rand是一个库函数,使用时需要包含对应的头文件#include<stdlib.h>才可以进行使用。
2.rand并不是真正的生成随机数,而是生成的是伪随机数,且这个随机数是有范围的(0~RAND_MAX(32767)),rand一般是在srand=1情况下调用生成的随机数,因此如果直接利用rand,就会发现你能够猜出他的下一个的数字是什么。
3.且在使用rand时,srand函数并不需要调用很多次,只需要调用一次就可以了。
举例:(如果你自己实验就会发现,一次与一次执行的命令结果都是相同的)
所以为了能够使所得到数字是真正的随机数,我们需要对他的初始值srand进行优化,需要达到的效果是srand每一时刻的初始值都是不同的,而此时我们需要注意的是我们不是给他输入相应的值,而是让他自己做到每时每刻都在变。
那么现在问题来了——如何能实现每时每刻的直都在变呢?
仔细想一想在我们的电脑当中——什么是我们能看到的无时无刻都在变的事物——时间
而有一个东西叫做时间戳——计算机当前这个时间与计算机起始时间(1970年01月01日00时00分00秒)这个差值转化成秒,这个秒数就是当前的时间戳,时间在发生变化,而秒数就在发生变化,将时间戳传递给srand就能实现每个时刻是不一样的数据。
这时我当时的时间戳——可以在百度当中直接搜索到
那么如何将他在代码当中应用呢
C语言当中有一个time函数返回的就是一个时间戳
此刻,我们将原理搞清楚了之后,看一下srand如何具体使用
int main()
{
srand((unsigned int)time(NULL));
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
这便是关于随机数生成的代码
需要注意:srand与time的返回类型是不一样的,我们需要对time进行强制转换一下所以写法是上面得描述,此时就能达到我们想要的效果,随机生成不同的数
但此时还要注意:我们需要将他这个数限定在1~100之间
Rand%100+1,就在1-100之间的数了,将这个打印出来便能够得到想要的结果。
将这个结果进行推广一下
生成a~b之间的随机数
A+rand()%(b-a+1)
此刻,才算是将随机数的生成部分完成。
1.2.2判断输入值与随机数
在这个部分当中我们需要用到条件判断语句和循环,直至将游戏全部实现——这也是我们这次游戏的主体部分
int main()
{
```
if(语句)
printf("猜大了");
else if(语句)
printf("猜小了");
else
printf("恭喜你,猜对了");
return 0;
}
在上述代码上,我使用的伪代码,仅做参考。
现在准备工作基本完成。
二、代码的实现
1.在一个游戏当中,开始需要做一个菜单,只要执行程序游戏,该菜单就会被执行,所以最好使用do~while循环的方式打印菜单。
在此时将菜单便打印了出来
2.需要判断输入的是什么,游戏的执行或者是结束
int main()
{
int input = 0;
do
{
printf("******************\n");
printf("******1.play******\n");
printf("******2.exit******\n");
printf("******************\n");
printf("请输入:>");
scanf("%d",& input);
switch (input)
{
case 1:
printf("游戏主体");
break;
case 2:
break;
default:
printf("输入错误,请重新输入");
}
}
while (input);
}
此时整个游戏的大致框架便有了雏形
3.将游戏的主体部分实现,因为这一部分很长,不建议直接写在整体的框架之中,所以我们可以写一个函数,对他进行一个调用即可
void game()
{
int a = 1;
int r = rand() % 100 + 1;
while (a)
{
printf("请输入数字:>");
scanf("%d", &a);
if (a < r)
printf("猜小了\n");
else if (a > r)
printf("猜大了\n");
else
{
printf("恭喜你,猜对了");
break;
}
}
return 0;
}
4.最后我们将代码进行整合,在这个过程中可能会发现前面的一些地方是有一些小问题的在进行细微的调整,便会得到一个很不错的结果。
void game()
{
int a = 1;
int r = rand()%100 + 1;
while (a)
{
printf("请输入数字:>");
scanf("%d",&a);
if (a < r)
printf("猜小了\n");
else if (a > r)
printf("猜大了\n");
else
{
printf("恭喜你,猜对了");
break;
}
}
return 0;
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
printf("******************\n");
printf("******1.play******\n");
printf("******2.exit******\n");
printf("******************\n");
printf("请输入:>");
scanf("%d",& input);
switch (input)
{
case 1:
game();
break;
case 2:
goto next;
default:
printf("输入错误,请重新输入\n");
}
}
while (input);
next:
return 0;
}
这边是游戏的初步设计好了。
三、调整与优化
目前在这个系统当中可能会觉得最核心的部分有一些冗长,可以将他放在函数当中进行调用,就会减少这样的情况。
调整最终版本:
void menu()
{
printf("******************\n");
printf("******1.play******\n");
printf("******2.exit******\n");
printf("******************\n");
printf("请输入:>");
}
void game()
{
int a = 1;
int r = rand() % 100 + 1;
while (a)
{
printf("请输入数字:>");
scanf("%d", &a);
if (a < r)
printf("猜小了\n");
else if (a > r)
printf("猜大了\n");
else
{
printf("恭喜你,猜对了");
break;
}
}
return 0;
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d",& input);
switch (input)
{
case 1:
game();
break;
case 2:
goto next;
default:
printf("输入错误,请重新输入\n");
}
}
while (input);
next:
return 0;
}
在这个版本当中函数的主体是没有那么长的,将复杂的问题放在外面。
优化:
1.我们可以将他所答的次数进行限制,例如5次完了之后没有猜对直接一局游戏就会退出
2.在规定的次数内不能猜对,可以进行惩罚(具体措施可以自行验证,我在此不适合说出来)
3.在Windows系统当中有一个清理屏幕的命令cls,在这个游戏当中也可以将他实现出来
这个是基于优化一做出的改进,仅供参考:
void menu()
{
printf("******************\n");
printf("******1.play******\n");
printf("******2.exit******\n");
printf("******************\n");
printf("请输入:>");
}
void game()
{
int a = 1;
int chance = 5;
int r = rand() % 100 + 1;
while (chance<=5&&chance>0)
{
printf("你还有%d次机会\n", chance);
printf("请输入数字:>");
scanf("%d", &a);
if (a < r)
printf("猜小了\n");
else if (a > r)
printf("猜大了\n");
else
{
printf("恭喜你,猜对了\n");
goto x;
break;
}
chance--;
}
printf("很抱歉,你未能在规定次数内才出结果\n");
x:
return 0;
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
scanf("%d",& input);
switch (input)
{
case 1:
game();
break;
case 2:
goto next;
default:
printf("输入错误,请重新输入\n");
}
}
while (input);
next:
return 0;
}
四、可能遇到的问题及可执行方案
在代码实现的过程当中,可能会遇到和我有相同问题的时刻,小编将这些整理出来
1.在使用srand和time函数时,由于这两者的返回类型并不相同所以直接用,编译器可能会报错,需要将time函数的类型强制转换一下<unsigned int>才能顺利进行使用
2.在使用rand生成随机数时,需要调用srand,这个函数是只需要调用一次的,所以将srand放在最前面的位置(最好不要将他放在循坏当中)
3.在打印菜单时,最后是需要选择的,所以用printf进行必要的文字说明,scanf只是仅仅输入数字
4.在使用do······while循环时,由于选择2需要将整个程序结束,所以使用的是goto语句,如果直接使用break;他还是会进入到循环当中,不是我们想要的结果;
在猜数字的主体部分,由于已经猜正确,所以我们需要直接跳出循坏,所以使用的是goto语句。
5.在用if···else语句时,需要注意多条语句将他用大括号的方式括起来
6.如在遇到其他问题试着用调试的方式,进行细节的修改
五、小编
在此,本章节的内容已全部介绍完
如果大家还遇到什么问题,我们一同探讨,只要下功夫,铁杵磨成针,加油吧!