首先猜数游戏肯定需要循环判断是否猜的正确肯定需要循环和分支,所以可以这样写
int guess;
int r;
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
给 r 一个数,这样循环当猜对 r 时从break跳出即可,但这个 r 的数怎么给?
但是这个数肯定不能由我们游玩的人自己生成,所以 r 得让它生成一个随机数
#include
r = rand();
rand()可以生成一个随机数,不需要传递参数,这个随机数的范围在0-RAND_MAX之间,这个RAND_MAX在大部分编译器中的值都是32767
所以把上面的代码让 r = rand()就可以有随机数
但它需要一个头文件,stdlib.h
#include
#include
int guess;
int r = rand();
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
但是这样生成的rand()的数是很大的,所以我们需要用一些运算符来给他限定取值范围
如果要生成 1-100 的随机数,方法如下:
rand()%100+1;//%100的余数是0~99,0~99的数字+1,范围是1~100
如果要生成 a-b 的随机数,方法如下:
a + rand()%(b-a+1);
所以游戏代码如下:
#include
#include
int guess;
int r = rand() % 100 + 1; //取值范围为1-100
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
但这样真的没问题吗?
如果按着这个代码,这个游戏进行多次的时候就会发现一个问题。
下面随机数多生成了几次后就会看见这样的结果
#include
#include
int main()
{
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
两次rand()生成的随机数的值都是一样的
因为rand()生成的值都是以一个“种子”为基准进行运算生成的随机数,这里种子未变,所以生成的随机数不会变
void srand(unsigned int seed);
当这个种子里的seed值变化时,生成的随机数就会变化
#include
#include
int main()
{
int guess;
srand(N); //当N的值变化时,生成的随机数一直在变化
int r = rand() % 100 + 1;
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
return 0;
}
但怎么样让这个N一直变化呢,总不能用rand吧,这样就陷入死循环了
因为我们生活中时间是一直在不断变化的
所以如果能够把时间给N,那么我们猜的数就会一直随着时间的变化而变化
所以可以用 time() 函数
time() 函数需要一个头文件 time.h
time() 函数的参数是一个指针,需要传递一个地址进去,但这里我们只需要时间戳
什么是时间戳?
时间戳就是从某一刻到现在具体时间转换为秒数为单位的时间差值
时间戳 = 现在的时间(秒)- 固定的某一刻的时间(秒)
如果我们需要使用时间戳,我们可以在用在time参数里面输入NULL(表示空指针)
time(NULL);
但是因为srand的返回值是需要的数据类型是unsigned int,所以我们需要强制类型转换来改变time的类型
#include
#include
#include
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;
}
这样两次的值就不一样了
所以代码就变成了这样
#include
#include
#include
int main()
{
int guess;
srand((unsigned int)time(NULL));
int r = rand() % 100 + 1;
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
return 0;
}
这样就可以玩无限次且 r 不同的数了
这里为了美观起见我们可以在游戏开始前制作一个菜单,如果输入1则开始游玩,如果输入0则退出游戏
void menu()
{
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
定义一个menu函数制作出来一个菜单,所以可以这样
#include
#include
#include
void menu()
{
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
int main()
{
int guess;
int input; //定义input来接受用户输入的值
srand((unsigned int)time(NULL));
int r = rand() % 100 + 1;
do {
menu(); //使用menu函数
printf("请输入0或1决定是否游玩\n");
scanf("%d", &input);
switch (input) {
case 1:
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
因为菜单是肯定要输出一次的,所以我们可以使用do-while函数,先使用一次菜单,再根据 input 决定游戏是否开始或结束,这种选择结构这里使用了switch,比较美观
在switch 语句中放游戏进行过程显得有点混乱,我们可以再次使用一个定义一个 game函数来存放游戏进行的过程
#include
#include
#include
void menu()
{
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
void game()
{
int guess;
int r = rand() % 100 + 1;
printf("请输入一个数字:\n");
while (1) {
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
}
}
int main()
{
int input;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入0或1决定是否游玩\n");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
这样看起来更加美观了
如果能够无限次猜那这个游戏没有任何难度可言,猜到最后总会成功,为了加大难度我们来限定它的次数
我们可以在game()函数里面加入计数器cnt,如果我们每猜一次,无论猜大了还是猜小了我们都让cnt--,如果cnt最后等于0,那么直接认为失败,游戏结束,cnt则表示游戏最大猜测的次数
#include
#include
#include
void menu()
{
printf("*******************\n");
printf("***** 1.play ******\n");
printf("***** 0.exit ******\n");
printf("*******************\n");
}
void game()
{
int guess;
int r = rand() % 100 + 1;
int cnt = 5; //让猜测次数最大值为5次
while (cnt) { //当cnt为0时终止循环
printf("你还有%d次机会", cnt); //输出次数剩余
printf("请输入一个数字:\n");
scanf("%d", &guess);
if (guess > r) {
printf("猜大了\n");
}
else if (guess < r) {
printf("猜小了\n");
}
else {
printf("恭喜你,猜对了\n");
break;
}
cnt--; //次数减1
if (cnt == 0) {
printf("你失败了,正确值是%d\n", r);
}
}
}
int main()
{
int input;
srand((unsigned int)time(NULL));
do {
menu();
printf("请输入0或1决定是否游玩\n");
scanf("%d", &input);
switch (input) {
case 1:
game();
break;
case 0:
printf("游戏结束\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
} while (input);
return 0;
}
这样难度就大大增加了
你们有成功的吗?我试了好多次都没有成功