接下来我将带领大家用C语言实现简单的猜数字游戏,并一步一步实现和排错,希望能帮助到大家
首先我们先确定一下猜数字游戏都有哪些功能
- 电脑随机生成一个数字
- 玩家猜数字
- 玩家猜小了,就告知猜小了
- 玩家猜大了,就告知猜大了
- 直到猜对为止
- 游戏可以一直玩
void menu()
{
printf("**********************\n");
printf("*********1.play*******\n");
printf("*********0.exit*******\n");
printf("**********************\n");
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
第一步完成,接下来就该实现猜数字最重要的部分,游戏的实现。
C语言中提供了一个生成随机数的函数 "rand()" 头文件 #include
"rand()"函数本身不要参数,并返回一个int类型的随机值,该值的范围在0~RAND_MAX
当我们引入#include
可见RAND_MAX的大小为32767,所以rand 函数返回的随机数的范围是(0~32767)
我们可以调试一下看看效果
void game()
{
int ret = rand();
printf("%d\n", ret);
}
这是就会出现一个问题,我们测试两次生成的随机数完全一样。如果玩家真的要玩第二次的话,完全可以记着第一次的结果。
所以这种用法不对,需要改正
我们再重新读一下rand()的用法
图中标记的那句话的意思是:在调用 rand 之前需要先调用 srand函数去设置随机数的生成器。
也就是说在调用rand之前要先调用srand。
现在出现在我们面前的问题是srand又是何方神圣呢?我们看文档
我们发现srand需要一个整型,那就让我们在srand里面加入整型试一试。
我们分别把srand函数中的值改为200和100,并调试观察结果。
void game()
{
srand(200);//srand(100);
int ret = rand();
printf("%d\n", ret);
}
可以发现随机数随着srand里面的参数而改变,问题来了,我们需要一个随机数而srand告诉我们需要投入进去一个随机数,天啊这不就是套娃问题吗。
为了解决此问题我们需要找到一个一直变化的东西,但是什么是变化的东西呢?
时间!
这里引入一个概念叫“时间戳”,它的含义就是:这个时间相较于相较于计算机的起始时间(1970年1月1日0时0分0秒)的差值,单位是秒。
时间戳可以转换为时间,同样时间也可以转换成时间戳。
如果我们把“时间戳”作为参数传递给srand,那么就能随机生成一个随机数啦。但是怎么传呢? 别急,C语言提供了一个函数time,可以返回一个时间戳。
time 函数有一个参数参数叫timer,类型为“time_t *”, 头文件为#include
什么意思呢,就是我们可以在函数外面可以创建一个参数例如: time_t* t;我们可以把‘t’的地址传给time函数,然后time函数就把时间戳的时间放到‘t’里面 。当然这个参数我们也可以不用,可以传入空指针NULL。
所以返回时间戳有两种方法
1、用参数:我们可以把时间戳放到 't'里面,当然这个't'是我们自己创建的。
2、用返回值:例如 srand(time(NULL)) 直接把time函数的返回值传出去。(注意要传入空指针)
现在又涉及到一个问题,time函数返回的数类型是什么?
这里我们直接查看time_t 的定义
发现是一个长整型或一个整型,而srand参数需要的是unsigned int (可以翻看上面图片)。
使用传参的时候就应该这样写
srand((unsigned int)time(NULL));
我们再一次测试结果
发现数字已经发生变化了,但是生成还是有问题,当我们快速按两次1,会发现两次生成随机数一样。
所以在调用rand函数之前要调用srand,但是不需要频繁调用。只要在整个程序运行起来之前调用一次就可以了。我们只需要把它放到主函数里面。
void game()
{
//1.生成一个随机数
int ret = rand();
printf("%d\n", ret);
//2.猜数字
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}
测试两次,发现随机数不一样了,终于解决这个问题了呼~
在生成随机数之前主要注意
1、在调用rand之前要先调用srand
2、srand需要一个变化的值 time函数返回的时间戳
3、srand只需要调用一次就可以了,不需要频繁调用
我们在介绍rand生成的随机数的范围在(0~32767),而在开头我们要猜的数在(1~100),所以我们要控制随机数生成的范围。
让rand()%100,因为任何数模上100的余数必为(0~99),再加上1,这样就能生成(1~100)的数啦。
int ret = rand()%100+1;
当玩家在猜数字的时候,我们不能把生成的随机数让玩家看见,所以我们不能打印随机数
同时,我们也不可能只让玩家猜一猜,所以要用上while循环,只有猜对了才能结束
void game()
{
int guess = 0;
//1.生成一个随机数
int ret = rand()%100+1;
/*printf("%d\n", ret);*/
//2.猜数字
while (1)
{
printf("请猜数字:>\n");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
}
至此猜数字游戏圆满完成,下面是完整的代码,希望可以为各位提供帮助
#include
#include
#include
void menu()
{
printf("**********************\n");
printf("*********1.play*******\n");
printf("*********0.exit*******\n");
printf("**********************\n");
}
//猜数字游戏的实现
void game()
{
int guess = 0;
//1.生成一个随机数
int ret = rand()%100+1;
/*printf("%d\n", ret);*/
//2.猜数字
while (1)
{
printf("请猜数字:>\n");
scanf("%d", &guess);
if (guess < ret)
{
printf("猜小了\n");
}
else if (guess > ret)
{
printf("猜大了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
}
int main()
{
srand((unsigned int)time(NULL));
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,重新选择\n");
break;
}
} while (input);
return 0;
}