猜数字游戏(C语言)

一:游戏要求

1.电脑自动生成1~100随机数字

2.玩家猜数字,在猜数字过程中,根据猜数字的大小,根据猜数据的大小,给出大了还是小了的反馈,直到猜对游戏

二:随机数的生成

要完成猜数字游戏,最重要的就是要生成随机数,那怎么才能生成随机数呢?

2.1 rand函数

基于上述问题,就要介绍一个C语言函数了-----rand,这个函数是可以生成随机数的,函数原型如下:

int rand(void);//void 指的是这个函数不含参数

rand函数会返回一个伪随机数(为什么成为伪,请看后续讲解),这个随机数的范围是0~RAND_MAX,这个RAND_MAX的大小是依赖编译器实现的,但是大部分编译器是32767.

rand函数的使用要包含一个头文件:stdlib.h

这里我先演示一下rand函数使用:随机生成五个数字

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的机制,明白它为什么会产生随机值,随机值为什么又是相对的?

rand函数由上述代码可以看出生成的随机数是伪随机数,而伪随机不是真正的随机数,是通过一种算法生成的随即数,真正的随机数是无法预测下一个值是多少的。而rand函数是对一个叫“种子”的基准值进行运算生成的随机数。

之所以前面每次程序产生的随机数序列是一样的,那是因为rand函数生产的随机数的默认种子是1。如果要生成不同的随机数,就要让“种子”发生变化。

2.2 srand

正巧是是,C语言中有一个函数叫srand,用来初始化随机数的生成器(初始化种子基准值),srand的原型如下:

void srand(unsigned int seed);

程序在调用rand函数之前先调用srand函数,通过srand函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子发生变化,每次生成的随机数的序列就会发生变化。

也就是说,给srand的种子如果是随机的,rand就能生成随机数;在生成随机数的时候又需要一个随机数,这似乎像套娃一样,没有尽头了

2.3 time

srand的种子是随机的,其中一层意思就是,它的种子是一直在变化的,才能保证rand的随机数列在变化。这是,我们可以想一下,什么是一直变化,且在短时间内是不会重复的?

此时,各位不妨看一下你们手机或电脑的时间,是不是每一秒都在变化?

所以,在程序中我们一般使用程序运行的时间作为种子的,因为时间时刻在变化。

time_t time (time_t* time);

time函数会返回当前的日历时间,其实返回的是1970年1月1日0时0分0秒到现在程序运行时间的插值,单位是秒。返回的类型是time_t类型的,time _t类型的本质上其实就是32位或64位的整数类型。

time函数的参数是timer,如果是非NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去

如果timet是NULL,就只返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。

time函数需要包含头文件:time.h

如果只是让time函数返回时间戳,我们可以这样写:

time(NULL);
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;
}

:使用srand生成种子之后,使用rand一次性产生大量的随机数,构成一个随机数列,所以srand不用频繁使用,一次运行的程序中调用一次就可以了

2.4随机数的范围

如果我们要生成0~99之间随机数,方法如下:

rand()%100//余数是0~99

如果要生成1~100之间的随机数,方法如下:

rand()%100 + 1 //%100的余数是0~99,,0~99+1就是1~100

如果要生成100~200之间的数字

100 + rand() % (200-100+1) //%101生成0~100之间的数字,+100就是100~200

由此可得出:生成a~b的随机数,方法如下:

a + rand()%(b-a+1)

三:游戏设计

3.1菜单

首先,我们应该打印一个游戏菜单,让玩家选择是否进入游戏,是退出游戏还是继续游戏?

其次就是,这个菜单时玩家已进入程序就会立即出现的,在这之前玩家还无需输入什么,菜单出现后,可以根据菜单的提示,做出相应的选择,所以这里就要用do while循环

    printf("*******************\n");
	printf("***** 0. exit *****\n");//0退出
	printf("***** 1. play *****\n");//1游戏
	printf("*******************\n");

为了让主函数更加简洁,易懂,让菜单可以重复利用,我们可以将菜单封装到一个函数中

3.2核心代码实现

核心代码的操作与菜单类似,封装到一个函数中

而在核心代码之前,应该有让玩家选择输入1还是0,输入1,才会进行游戏

有一个问题,srand生成的种子是放在game函数中,还是main函数中呢?

1.从调用次数来说,放在game函数中,如果玩家一次性玩多次,会被调用多次,而放在main函数中,玩家调用一次程序,在退出游戏之前,srand就只调用一次。从次数来说,放在main函数中好。

2.考虑极端情况,放在game中,如果玩家第一次玩游戏是一次性就猜中了,然后有选择继续玩,这是game就被调用第二次,srand就会根据当前时间,再次生成随机数,但是一次性猜中的情况下,两局游戏距离时间可能是十分短,所以srand产生的种子可能相同,那么随机数就是伪随机了。而放在main函数中,即使两次时间距离短暂,但是既然没有退出程序,那下次再猜数字就是从生成好的随机数列中继续向下选取数字,在一列随机数中,两个随机数不会相同。

综上,放在main函数中

四:代码

void menu()
{
	printf("*******************\n");
	printf("***** 0. exit *****\n");//0退出
	printf("***** 1. play *****\n");//1游戏
	printf("*******************\n");
}
void game()
{
	int num = rand() % 100 + 1;
	int guess = 0;
	while (1)
	{
		printf("请输入您猜的数字:");
		scanf("%d", &guess);
		if (guess < num)
		{
			printf("您猜小了\n");
		}
		else if (guess > num)
		{
			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("退出游戏");
			break;
		default:
			printf("输入错误,请重新输入");
		}

	} while (input);
}

五:游戏进阶

以上是猜数字游戏的基础版,再次之上还可以加各种限制要求,例如猜一定的次数就不可以再猜了......

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玖剹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值