猜数字游戏
1. 项目要求
- 电脑随机生成数字,要求在0~100
- 显示选择菜单
- 进行猜数字游戏
- 猜大了,提示,并且继续
- 猜小了,提示,并且继续
- 猜对了,提示,并且结束本轮游戏,显示选择菜单
- 一轮游戏结束之后可以继续游玩
2. 过程解析
4. 随机数生成
在生成随机数时,我们需要使用到两个库函数rand()
和srand()
4.1 伪随机数
rand()
用法:
int rand(void);
作用:返回一个伪随机数
参数:无参数
返回值:An integer value between 0 and RAND_MAX.(取值范围在0到RAND_MAX之间的整数)
RAND_MAX是定义在头文件<stdlib.h>中的一个宏,指定了rand()函数能返回的最大值
对于rand()函数,我们可以看到其用法中表明,其会返回一个伪随机数,这是为什么?
这是因为,rand()函数生成的随机数是有规律可循的。我们可以用一个小程序来验证这一点。
#include<stdlib.h>
#include<stdio.h>
int main()
{
int i = 3;
while (i)
{
printf("%d\n", rand());
i--;
}
return 0;
}
多次执行上述程序,我们会发现,每次输出的数字都是一样的,尽管更改随机次数,也是如此。所以我们得出,rand()函数生成的是伪随机数。
为什么随机函数生成的随机数字并不是随机的呢?
实际上,rand()函数产生的随机数是伪随机数,是根据一个数值按照某个公式推算出来的,这个数值我们可以称之为种子。种子和随机数之间的关系是一种正态分布。种子在每次启动计算机时是随机的,但是一旦计算机启动以后它就不再发生变化了。
也就说明,每次启动计算机之后,种子就成为了定值,所以根据公式推算出来的结果,也就是返回的”随机数“就是固定顺序了。
从上文我们了解到让随机数不随机的原因是因为种子是固定的,那么我们让种子不再固定是否就解决了伪随机的问题呢?而如何解决上述情况呢?这就需要用到了**srand()**函数了。
4.2 随机的"种子"
srand()
用法:
void srand(unsigned int seed);
名称:初始化随机数生成器
作用:将伪随机数生成器使用的作为种子传递的参数初始化
参数:种子:伪随机数生成器用作种子的整数值
返回值:无
通过对srand()函数的介绍,我们了解到使用srand()函数需要一个unsigned int类型的参数,而且这个参数我们希望也是随机的,即每一次执行srand()函数的时候“种子都是不同的”,这样我们才可以在每次运行程序的时候得到不同的随机数,所以我们需要一个不断变化的整数去充当这个参数。
细想生活中什么数字是不断变化的并且,即使你人都不再了,这个数字还是在变化的?
时间!
time()
用法:time_t time(time_t* timer);
作用:获取当前时间;以time_t为类型获取当前电脑日历的值
参数:Pointer to an object of type time_t, where the time value is stored.Alternatively, this parameter can be a null pointer, in which case the parameter is not used (the function still returns a value of type time_t with the result).(指向time_t类型对象的指针,时间值存储在该对象中。或者,这个参数可以是一个空指针,在这种情况下不使用参数(函数仍然返回一个time_t类型的值和结果).)
返回值:将当前日历的时间作为time_t类型的返回对象;如果参数不是空指针,则返回值与存储在参数计时器所指向的位置中的值相同;如果该参数无法检索日历时间,则返回-1;
综上,我们只需要使用下面的方法就可以更改“种子”
srand((unsigned)time(NULL));
4.3 一定范围内的随机数
猜数字游戏,如果我们没有规定范围的情况下,生成的随机数可能是无限大,那么我们要怎么才能猜到呢?所以要实现这个游戏,一定要限定随机数的生成范围。
而在确定的范围内生成简单的随机数的典型方法是使用范围跨度对返回值取模。
例如我们生成了一个随机数字为986,而我们需要的数字范围是0~100,那么我们只需要对986进行取模;
986%100 = 86;
而如果是要得到0~3之间的数字,则只需要对随机数字进行模3运算
986%3 = 2;
公式:rand()%100;
rand()%3;
3. 代码实现(C)
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void Menu()
{
printf("*************************\n");
printf("**** 1.play 0.exit ****\n");
printf("*************************\n");
}
void GuessNumber()
{
printf("游戏开始\n");
int rng = rand() % 100;
//printf("%d\n", rng);
int my_num = 0;
do
{
printf("请输入您所猜想的数字:");
scanf("%d", &my_num);
if (my_num > rng)
{
printf("很遗憾,您猜错了,您猜想的数字比较大!\n");
}
else if (my_num < rng)
{
printf("很遗憾,您猜错了,您猜想的数字比较小!\n");
}
else
{
printf("恭喜您,猜对了!!!\n");
printf("随机数字为:%d\n", rng);
break;
}
} while (1);
}
int main()
{
int select = 0;
do
{
srand((unsigned int)time(NULL));
Menu();
printf("请选择(1/0):");
scanf("%d", &select);
switch (select)
{
case 1:
GuessNumber();
break;
case 0:
printf("退出游戏成功!\n");
break;
default:
printf("选择错误,请重新选择!\n");
};
} while (select);
return 0;
}