【揭秘!】这里有你从未听过的独特见解,快来点赞关注,开启智慧之旅
游戏要求
1.电脑自动生成1~100的随机数。
2.玩家猜数字,猜数字的过程中,根据猜测数据的大小给出“猜大了”还是“猜小了”,直到猜对为止。
3.可以加入次数限制。
要实现该游戏,我们首先需要知道随机数的生成方法,下面我们介绍随机数的生成方法。
随机数的生成方法
1.1 rand函数
C语言中提供了一个 rand 函数,这个函数可以生成随机数,函数的原型如下:
int main(void);
注:使用rand 函数需要包含头文件:<stdlib.h>
rand 函数会返回一个伪随机数,这个随机数的范围是:0 ~ RAND_MAX之间,这个RAND_MAX的大小是依赖于编译器实现的,但是大部分编译器上是32767。
我们在这测试一下 rand 函数,这里多调用几次,产生7个随机数:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
return 0;
}
两次运行结果:
在上面的代码中,我们可以发现在一次运行中产生的7个数字是相对随机的,但是运行两次程序生成的结果是一样的,那么这是为什么呢?下面我们对其进行分析。
上面说到,rand会生成一个伪随机数,它与真随机数有什么区别?
伪随机数是指看似随机实则是固定的周期性序列,也就是有规律的随机数。这些随机数是由确定的算法生成的,只能通过不断算法优化,使得随机数更接近随机。与真随机数不同,真随机数是通过真实随机事件取得的随机数,比如机器的硬件、CPU温度、当天天气、噪音等真随机事件产生的随机数。目前的随机数都是通过一个非常复杂的算法计算出来的,比如Java语言的随机数生成器或者整个计算机中的随机数函数,生成的都是伪随机数。如果想要产生真随机数,需要一定的物理手段,开销极大,或许得不偿失 。
所以伪随机数不是真正的随机数,而是通过某种算法生成的随机数。真正的随机数是无法预测下一个值是多少的。而 rand 函数是对一个叫 “种子” 的基准进行运算生成的随机数。如果种子一样的话(在上面的代码中种子默认值为1),程序运行的生成的随机数的序列每次都是一样的,所以我们需要一个可以变化的种子。
1.2 srand函数
C语言中又提供了一个 srand 函数,用来初始化随机数的生成器,srand 函数的原型如下:
void srand(unsigned int seed);
程序中在调用 rand 函数之前先调用 srand 函数,通过srand函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子发生变化时,每次生成的随机数序列也就发生变化了。
也就是说,如果给srand函数的种子是随机的,那么rand函数就能生成随机数;也就是说在生成随机数的时候我们又需要给入一个随机数 。
那怎样给rand函数一个随机数呢?我们可以用time函数。
1.3 time函数
在程序中我们一般使用程序运行的时间作为种子,因为时间时刻在发生变化,那么就相当于我们引入了一个随机的种子。
在C语言中提供了 time 函数,time 函数可以获得程序运行的时间,time 函数的原型如下:
time_t time(time_* timer);
注:使用 time 函数需要包含头文件 <time.h>
time函数会返回当前程序运行的时间,但他返回的并不是当前日历的时间,而是返回当前日历时间与1970年1月1日0时0分0秒之间的差值,单位是秒。返回的类型是 time_t 类型(32位或者64位的整型)。
如果 timer 是NULL,就只会返回这个时间的差值。返回的这个时间的差值也称为:时间戳。
如果只想让time函数返回时间戳,我们可以这么写:
time(NULL);//调用time函数返回的时间戳,这里没有接收返回值
我们在这将上述产生7个随机数的代码改写一下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
//在这使用time函数的返回值设置为种子
//因为srand的参数是unsigned int 类型,所以我们将time函数的返回值强制类型转换
srand((unsigned int)time(NULL));
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
printf("%d ",rand());
return 0;
}
在这截出两次运行结果:
在这个截图中,我们可以发现两次运行的结果不一样,所以我们成功的实现了随机数的生成。
注意的是,srand函数不需要频繁的调用,一次运行的程序中调用一次就够了。
1.4 设置随机数的范围
在上述代码中,我们不难发现生成的随机数范围很大,那么我们需要怎样控制这个范围呢?
在这我给大家一个通用公式: (生成a~b范围的随机数)
a + rand() % ( b - a + 1);
下面举几个例字让大家更加理解:
生成0~99之间的随机数:
rand()%100;//余数范围是0~99
生成1~100之间的随机数:
1+rand()%(100-1+1);//余数范围是0~99,0~99加1,范围变成1~100
生成100~200之间的随机数:
100 + rand()%(200-100+1);//余数范围0~100,加100,范围变成100~200
猜数字游戏的实现
结合上两篇讲的分支和循环语句,加上这次讲解的随机数的生成方法,下面我们就可以以实现猜数字游戏了。大家可以去浏览上两篇文章,对C语言的分支和循环介绍的也是非常的详细)
在这,我加入了7次猜不中就失败的游戏规则。
游戏实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game()
{
int r = rand() % 100 + 1;//见注:为什么放在这。
int guess = 0;
int count = 7;
while (count)
{
printf("你还有输入%d次机会\n", count);
printf("请输入你猜的数字:");
scanf("%d", &guess);
if (guess < r)
{
printf("输入小了\n");
}
else if (guess > r)
{
printf("输入大了\n");
}
else
{
printf("恭喜你,猜对咯\n");
break;
}
count--;
}
if (count == 0)
{
printf("很遗憾,7次你都没有猜对,正确的数字是:%d\n", r);
}
}
void menu()
{
printf("============================\n");
printf("||||||||| 1.开始 |||||||||\n");
printf("||||||||| 2.结束 |||||||||\n");
printf("============================\n");
}
int main()
{ int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("请选择数字进行游戏,1开始,2结束\n");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("游戏结束\n");
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}
注:随机数的生成应该放在循环之外,这样的话在整个循环内部这个值都不会变。如果将该随机数的生成放在while循环中去的话,循环每循环一次,随机数的值都将发生一次变化。
游戏运行的结果如下:
游戏的结果还有很多种类,大家有兴趣的话可以去开发环境下尝试运行该代码。
用心呈现,只为遇见更好的你!点赞关注,让我们的博客陪伴你成长!