猜数字游戏

电脑产生一个随机数(1-100)
猜数字
反馈猜大了还是猜小了
直到才对了,结束

我希望这个游戏,我猜数字的时候玩一把,玩完一把之后觉得玩的不过瘾还可以继续玩,这个时候就可以提供一个菜单,玩完之后呢,来决定继续玩还是结束。所以这个地方最好设计一个菜单。

那这个菜单呢最开始就要打印,而且循环过程中也要打印。所以最开始就给一个do ... while循环,这个do...while循环的特点,不管什么上来就要先执行语句,然后接下来是循环。

那do这里进来的时候我们首先要打印一个菜单,菜单就简单封装一个函数,叫menu。

那这个时候,有了这个菜单的打印,那么这个地方让你选择

然后这个时候就可以选了,可以选0,选1,也有可能不小按其他值,那这个时候就要从键盘输入你的选择,用input来接收

那这个地方当我们有了这个值之后,我就知道你到底输入的是几啊,你输的是1,我们接着玩游戏,输的是0,我们这个地方退出游戏,如果你输入的是其他值呢,我就告诉你选错了。那这个地方就switch,我根据你输入的这个input的值,来进行判断,如果走了case 1,那这里就是猜数字的逻辑,先写的简单点,就写个猜数字。如果是case 0,我们这就提示一下退出游戏,而如果选的是其他的值,走default子句,那这个地方就得输出一句话,选择错误,重新选择。 

 那当这选择了之后呢,这个do ... while循环要不要继续,如果这里选了0,退出了游戏,那这个循环就不要再继续循环下去了,那怎么让他不循环了呢,这里虽然有break,但这个break只是跳出这个switch语句,他不会跳出外层这个循环的,那怎么办呢。  如果你选了0,这个input是0,所以走了case 0,退出游戏,那我干脆把这个input放到while循环条件里面好了。

input往这放的时候,因为input是0,while循环这判断的时候input=0,0为假啊,那他就不循环了,那这个退出游戏的逻辑对了,其他逻辑呢,比如说,如果选了1,猜数字,这猜完之后break跳出来了,跳到了while这里,然后判断这个input,input是1,所以他继续上来走,这个逻辑也对,如果有人选错了,那选的肯定不是0也不是1,选了其他值,那这个时候input放while这,也让这个while循环为真,再上来重新选择,整体逻辑没有问题。先用猜数字三个字代替了这个猜数字逻辑,先不管他。 那这个时候测试一下:

#include<stdio.h>
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:
				printf("猜数字\n");
				break;
			case 0:
				rintf("退出游戏\n");
				break;
			default:
				printf("选择错误,重新选择!\n");
				break;
		}
	} while (input);
	return 0;
}

结果:

在写代码时,要养成一个良好的习惯,就是写一部分测一部分。那这样你前面写的时候有bug就改一下,不会到最后一堆bug难改,不会积累到后面去。

那现在最重要的不是说case 1这就是打印猜数字,是要真正完成猜数字逻辑,就再封装一个函数game,这里面才是猜数字的整个逻辑。

那怎么做呢,把game函数放到前面,返回类型是void,这里面才是猜数字逻辑的过程,

猜数字的步骤:

1、电脑产生一个随机数(1-100)

那这个rand函数怎么用,注意,使用这个函数的时候要添加头文件 #include<stdlib.h>

也是就说,这个rand函数会返回一个值,就是这个随机值,再把这个返回的值存起来,用ret接收

 而他返回的这个值打印的话也是可以打印出来的。

注意,他生成的随机数的范围是0 到 RAND_MAX。。那这个 RAND_MAX 是多少呢。

0~RAND_MAX(32767)

那现在测试一下 ,测试两次结果:

发现两次结果一样。  这个rand函数的介绍后面还有这句话。

 大概意思就是,每一次这个rand函数被调用,就会通过返回一个明显不相关的数的算法产生一个数。这个算法使用一个方法去产生一个应该被srand函数初始化一些特定值的序列。

就是在使用rand函数之前要先使用srand函数初始化一些特定值。

在rand之前调用srand,这个srand函数需要传个数字,那我先传个100.

发现又出问题了,为什么一直是365呢,因为这个srand的100这个数值没变,那我把他改成200呢

变了,也就是说,只要这个srand函数的这个数在变化,rand函数生成的随机数就在变化。

那我就往这个srand函数里面传个随机数进去,只要这个随机数在发生变化,那这个rand函数就能生成随机数了,那问题来了,我们想要一个随机数结果需要一个随机数,那怎么整呢,所以这个想法是不现实的。

那我们srand函数这里需要传一个值,这个值时时刻刻都在发生变化,那什么在发生变化呢?时间!!时间在一分一秒的发生变化,只要这个时间在变,那生成的随机数就在变,那这个时候怎么获得时间呢?

这个时候就有了时间戳的概念

 那所谓的时间戳是什么呢,就像我们的邮戳一样,当我今天要给你写一封信的时候,那我就在这个信封上戳一个邮戳,那这上面就会记录我今天什么时间点,我发出的这封信,上面会有一个时间。那在这个地方时间戳是什么意思呢?就是在这个时间2024-05-10 20:12:04这个时间点,相对于计算机的起始时间之间的一个差值,单位是s,而只要时间在一分一秒地往后走,这个时间戳就在发生变化,时间在变,时间戳就在变。

而这个时间轴就是个整数,传给这个srand函数,就合适,那我们在这个地方如何生成一个时间戳呢,在C语言中有一个叫time的函数,头文件是time.h。 time这个函数,他返回的就是时间戳

如果不想用这个参数的话,可以给他传一个空指针,这个参数用也可以,不用也可以,不用的时候就给他传一个空指针进去,他会返回一个time_t的值,这个值就是时间戳。

 time_t是C语言给的一个类型,会发现其实是一个__time64_t,是一个整数

他其实是一个long long 的typedef,所以本质上这个 time_t 是个整数。

所以把这个time函数的返回值传给srand函数也没有问题,这个time函数的参数我不想用,我给他传个空指针(NULL),然后这个time(NULL)函数的返回值类型是time_t,而我这srand函数期望得到的是unsigned int,而time(NULL)返回的本质上也是整型,只是类型叫time_t而已,所以这可以强制类型转换一下,就把他转换成unsigned int这个类型。

这个时候就把随机数生成器就设置好了,注意要添加头文件。

使用time函数返回的时间戳作为这个随机数的生成(srand函数)起点的设置 ,然后再用rand函数来调用生成随机数。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("***************************\n");
	printf("*******  1、play  *********\n");
	printf("*******  0、exit  *********\n");
	printf("***************************\n");
}
//0~RAND_MAX(32767)
void game()
{
	srand((unsigned int)time(NULL));
	//1、生成随机数
	int ret=rand();//生成随机数的函数
	printf("%d\n", ret);
}
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;
}

结果:

 都不一样,但这个时候会发现如果输入的比较快,会有几次随机数是相同的

生成的随机数有可能是相同的,这有点问题,实际上呢,确实要在rand函数上调用这个srand,但不是每次生成随机数的时候我都设置这个起点,而是应该在整个工程里面只要设置一次就可以了,所以应该把srand((unsigned int)time(NULL));这串代码放到主函数里面,程序运行起来的时候,把随机数的生成起点设置一次就可以了,以后生成随机数的时候直接生成就可以了,不用再设置这个起点。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("***************************\n");
	printf("*******  1、play  *********\n");
	printf("*******  0、exit  *********\n");
	printf("***************************\n");
}
//0~RAND_MAX(32767)
void game()
{
	//1、生成随机数
	int ret=rand();//生成随机数的函数
	printf("%d\n", ret);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}

 这样生成的随机数就非常随机了,哪怕你按的快一点,也不会有两个一样的。这样才是一个正确的使用方法。

那这个空指针(NULL)代表什么

比如这里一个指针变量,int *p=  ,这里要给他赋个值,原来定义一个变量的时候习惯性的给他赋一个值,比如int a=0;这是初始化,指针呢在给他初始化的时候,也可以给他初始化一个NULL,

int *p=NULL;  NULL这个叫空指针的意思,这个空指针其实就是0的意思,就相当于0

 对0的强制类型转换成了void*,但他本质上就是0.那就跟这个变量的创建赋值为0 int a=0;  ,是一个道理。

注意srand((unsigned int)time(NULL));time这里传了个NULL,就意味着我暂时不需要这个参数。

这个时候想使用time的参数就不能使用了。更具体还没学。

但这个时候还是不完整的,最开始希望生成的随机数的范围是1到100,那怎么让他生成的随机数范围在1到100呢?

让这里模上100

rand函数生成的这个随机数在0到32767之间任何一个数,任何一个数模上100,得到的数字都是0到99,因为得到的数是余数,而0到99这个数字给他加个一,这个时候就会变成1到100之间的数

这样一处理,生成的随机数肯定是1到100了

到这一步的正确代码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("***************************\n");
	printf("*******  1、play  *********\n");
	printf("*******  0、exit  *********\n");
	printf("***************************\n");
}
//0~RAND_MAX(32767)
void game()
{
	//1、生成随机数
	int ret=rand()%100+1;//生成随机数的函数
	printf("%d\n", ret);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}

结果:

然后接下来猜的数字不能看,屏蔽这个语句

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("***************************\n");
	printf("*******  1、play  *********\n");
	printf("*******  0、exit  *********\n");
	printf("***************************\n");
}
//0~RAND_MAX(32767)
void game()
{
	//1、生成随机数
	int ret=rand()%100+1;//生成随机数的函数
	//printf("%d\n", ret);
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}

 接下来就是开始猜数字

2、猜数字

反馈猜大了还是猜小了
直到才对了,结束

全部代码:

#define _CRT_SECURE_NO_WARNINGS 1



#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void menu()
{
	printf("***************************\n");
	printf("*******  1、play  *********\n");
	printf("*******  0、exit  *********\n");
	printf("***************************\n");
}
//0~RAND_MAX(32767)
void game()
{
	//1、生成随机数
	int ret=rand()%100+1;//生成随机数的函数
	//printf("%d\n", ret);
	//2、猜数字
	int guess = 0;
	while (1)
	{
		printf("请猜数字:>");
		sacnf("%d", &guess);
		if (guess < ret)
		{
			printf("猜小了\n");
		}
		else if (guess > ret)
		{
			printf("猜大了\n");
		}
		else
		{
			printf("恭喜你,才对了!\n");
			break;
		}
	}
}
int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	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;
}

结果:

  • 32
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值