1. 前言
在学习完分支与循环语句后,我们就可以进行一些简单的应用了,本篇文章将简要介绍猜数字游戏。
2. 设计程序
我们这样思考:
假如让电脑可以生成一个随机数,我们输入一个数字进行猜数字,当我们猜大了,提示:“猜大了,继续猜”。当我们猜小了,提示:“猜小了,继续猜”,当我们猜对了。提示:“恭喜你,猜对了,结束游戏”。我们发现这样就进行了一次游戏了,那我们肯定不止玩一把,于是继续玩,不用退出程序。
我们整理一下思路:
我们发现,这个程序还要有提示菜单去指引玩家,并且我们想要让玩家自行选择开始游戏和退出游戏,我们可以用’1’来表示开始游戏,用’0’表示结束游戏,玩家选择1开始,玩家选择0退出。当玩家选择的不是1或者0时,提示"选择错误请,重新选择"。
菜单设计逻辑:
2.1 生成随机数(难点)
我们想要引入一个随机数,怎么办?不要慌张,在这里我们介绍一个函数rand()函数,我们可以在网站上查询到它的使用方法rand介绍,通过查询我们可以知道rand()返回介于0和RAND_MAX之间的整数值。而RAND_MAX的值在任何标准库中为32767。
在VS2019环境同样如此,选中RAND_MAX转到定义,可以看到RAND_MAX的值。所以rand()可以生成随机数随机数范围是0~32767
选中RAND_MAX,右击,再点击转到定义:
那我们是不是可以用它生成随机数了呢?
#include <stdio.h>
#include <stdlib.h>
void game()
{
int ret = rand();
printf("%d\n", ret);
}
int main()
{
for(int i=0;i<10;i++)
game();
return 0;
}
通过上面代码我们可以看到,确实是生成了十个随机数
在一次运行时确实是随机数,但这些随机数在每次运行程序时都是一样的,那我们该怎么正确使用rand()函数,使每次运行时生成的数都不一样呢,我们这时就需要使用srand配合rand使用。
srand是初始化随机数的生成器,不需要返回值。
我们发现当我们传给srand的值变化时,随机数的值也在变,所以我们只需要让这个数是一个随时变化的数就行了。
这里我们引入时间戳概念,每时每刻的时间都可以转化为一个数字,我们就叫它时间戳
所以我们要找的这个随时变化的数字就是时间戳。
C语言中time函数可以返回一个时间戳,我们如何用呢?
可以看到:
而srand接收的参数为unsigned int 类型,我们就需要将这个数强制转换为unsigned int类型。
srand((unsigned int)time(NULL));
//我们不需要传参,传空值NULL就行了
写成这样我们终于可以生成随机数了,虽然两次运行的数变了,但是我们发现这个随机数变化太慢了,导致我们一次运行出现的数时一样的。
第一次运行:
第二次运行:
对于srand函数,如果我们每时每刻都在调用的话,让rand函数生成的值会很接近,甚至出现相同的现象。
因此我们只在主函数调用一次srand就可以了。
可以看到生成的数每次都不一样了。
我们这时生成的是0 ~ 32767的数,范围太大了,为了保证游戏的可玩性我们生成1 ~ 100的数
int ret = rand()%100+1;
//由于任何数模上100得到的是0~99的数
//所以模上100加1就是1~100的随机数啦
终于,我们解决了生成随机数的问题。
2.2 设计猜数字环节
根据上图,我们可以得到猜数字的逻辑实现。
代码实现:
while (1)
{
printf("请猜数字:>");
scanf("%d", &guess);
if (guess > ret)
{
printf("猜大了,继续猜\n");
}
else if (guess < ret)
{
printf("猜小了,继续猜\n");
}
else
{
printf("恭喜你,猜对了\n");
break;
}
}
3.代码实现
菜单:
void menu()
{
printf("****************************************\n");
printf("*********** 猜数字游戏 *************\n");
printf("********* 选择1:开始游戏 ***********\n");
printf("********* 选择0:退出游戏 ***********\n");
printf("****************************************\n");
}
猜数字游戏:
void game()
{
int ret = rand() % 100 + 1;
int guess = 0;
//printf("%d\n", ret);添加这一句即可实现作弊模式
while (1)
{
printf("请输入猜的数字:");
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;
}
//可以把玩家选择这一步封装成一个函数,简化主函数
调试实例:
4. 完整代码参考
#include <stdio.h>
#include <stdlib.h>//rand和srand所在的头文件
#include<time.h>//time函数所在的头文件
void menu()
{
printf("****************************************\n");
printf("*********** 猜数字游戏 *************\n");
printf("********* 选择1:开始游戏 ***********\n");
printf("********* 选择0:退出游戏 ***********\n");
printf("****************************************\n");
}
void game()
{
int ret = rand() % 100 + 1;
//printf("%d\n", ret);
int guess = 0;
while (1)
{
printf("请输入猜的数字:");
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;
}