C语言-猜数字游戏(超详细!)

本人是一名不太聪明的计科专业学生,将会在这里记录我的代码学习进程,如果文章中有哪些地方说的不对或者代码有哪些可以改进的地方就有劳大家打在评论区啦!那咱们废话不多说,直接开始吧!

1. 游戏描述:

项目开始运行时,玩家可选择开始游戏或退出游戏,选择开始游戏后系统将随机生成一个1~100的数字,玩家则是进行一个猜数字的操作,若猜的数字比答案大或小都分别会有相关提示,猜出正确答案后,玩家可选择再来一局或退出游戏,若再来一局系统将生成一个新的随机数作为答案,玩家则只需重复上述操作,若玩家选择退出则程序结束运行。

不难看出,要想成功做出这款小游戏,最核心的部分不过是实现三点:

1.每进行新的一轮游戏都需要生成一个新的数字

2.猜的过程中需一直循环,而不是猜一次就退出进程了

3.在上一局游戏结束后,程序不能自己结束进程,而是给玩家对下一盘游戏进行与否的选择

那么接下来就让我们一起看看应该如何解决生成随机数的问题以及游戏的最终实现吧!Let's go~

2. 游戏实现

2.1随机数的生成

2.1.1  rand函数

在C语言中,有一个函数叫rand,它可以生成一个伪随机数,下面是它的函数原型:

int rand(void);

“阿巴阿巴,我不明白,我不理解,解释解释......”

好好好,那就让我们直接点击链接cplusplus.com/reference/cstdlib/rand/直捣黄龙看看这函数究竟是怎么个事儿(摇头晃脑)

...

...

不是,你怎么还在这个页面?

这都被你猜到了?好吧,其实我已经帮你截过来了

在这个页面显示了rand函数的原型以及函数解释,大概意思就是我们在调用它的时候可以得到它随机生成的0~RAND_MAX的伪随机整型数字

“你等等,那这个RAND_MAX到底是多大呢?”

事实上,它的数值是依赖编译器上实现的,但是在⼤部分编译器上是32767。

因此我们也可以理解为这个rand函数会随机生成一个0~32767之间的数字。这下明白了吧~

接下来,就让我们一起运行下面这段代码看看啥效果吧!(记得要包含stdlib.h这个头文件噢)

#include<stdio.h>
#include<stdlib.h>//要使用rand函数需要包含这个头文件哟~
int main()
{

printf("%d",rand());

printf("%d",rand());

printf("%d",rand());


return 0;
}

我们会发现,通过这个函数我们的确得到了三个不同的数字

但当我们多运行几次后会发现,这三个数值并没有像想象中的那样每次都不一样,反之,每次出来的运行结果都没有任何变化,这是怎么回事呢?

还记得我们刚刚说到的吗,rand函数生成的是一个伪随机数,重点圈出一个“伪”字,说明其实这个数字“并不那么随机”,它的随机仅仅体现在第一次生成数字的时候。

“嘶...这可怎么办,对了,你刚刚上面的那个网页你就解释了一行RAND_MAX啊,后面的内容都说了嘛?”

后面的那段话翻译过来是:

“这个数字是由一个算法生成的,每次调用它时返回一个明显不相关的数字序列。这个算法使用种子来生成序列,应该使用函数srand将其初始化为一些独特的值。”

诶?这里似乎提到了另外一个函数---srand函数,答案应该就隐藏在这个函数中了

2.1.2  srand函数

我们直接点击cplusplus.com/reference/cstdlib/srand/穿越,看看这个srand函数到底怎么事儿!

“这一页的函数解释更长了七七八八的一大堆,看了都头疼啊!!!”

我们不用在意那么多,先看这个函数的原型:

void srand (unsigned int seed);

大概意思就是说:这个srand函数需要我们给它传入一个“种子数”,在接收到不同种子数之后这个函数就会对应将rand函数传出的伪随机数初始化为不同的值。

这么一来我们就明白了,原来刚刚rand函数生成的数值一直不变是因为我们并未用srand函数给它传不同的种子数啊~

在确定它的函数原型后:

我们直接运行代码进行验证:

#include<stdio.h>
#include<stdlib.h>
int main()
{
	
	srand(1);
	printf("%d\n", rand());

	printf("%d\n", rand());

	printf("%d\n", rand());


	return 0;
}

运行结果如下图所示:

不难看出在我们修改了种子数后,生成的数字确实发生了改变 ~b( ̄▽ ̄)d

可是在游戏开始运行时我们也不可能猜一局就退出来自行改个数字,这也不符合我们的游戏描述,因此我们便需要一个随时都在变得数字来充当我们的种子数从而满足我们的生成数的随机性与连贯性。

那什么东西是自始至终都在发生变化的呢?你一定已经想到了,就是一寸它能换一寸金的---时间

2.1.3  time函数

 在C语言中有个函数叫time,就可以获得这个时间,time函数原型如下:
 time_t time (time_t* timer);

time 函数能返回当前的日历时间。其实,这个返回值是 1970 年 1 月 1 日 0 时 0 分 0 秒到当前程序运行时间的差值,单位是秒。返回类型是 time_t 类型,本质上,time_t 类型是 32 位或者 64 位的整型类型。

 

如果 time 函数的参数 timer 是一个非 NULL 的指针,函数会将返回的差值存放到 timer 指向的内存中带回。若 timer 是 NULL,则仅返回时间差值。time 函数返回的这个时间差,又叫作:时间戳。

那如果我们只需要让它返回一个时间戳的话,就写成下面的形式就OK啦~

time(NULL);
 

使用 time 函数时,需要包含头文件:time.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
	

	srand((unsigned int)time(NULL));//别忘了srand的种子数中有个(unsigned int)的强制类型转换噢

	printf("%d\n", rand());

	printf("%d\n", rand());

	printf("%d\n", rand());


	return 0;
}

接下来,就让我们一起运行上面这段代码试试看此时的生成数是否能够满足我们的需求了:

嗯~这么看来我们的生成随机数的问题似乎就解决了,接下来只需要根据我们需要的数字范围根据下面的操作来对这个rand()进行小小的改动就OK啦~

v1 = rand() % 100;         // v1 in the range 0 to 99
v2 = rand() % 100 + 1;     // v2 in the range 1 to 100
v3 = rand() % 30 + 1985;   // v3 in the range 1985-2014
v4 = a + rand()%(b-a+1);   // v4 in the range a-b

0~99、1~100、1985~2014甚至是自定义的a~b的各种范围任君挑选~  \(*^▽^*)/

太好辣!我们已经解决了随机数在规定范围内的生成,接下来就是游戏的整体实现部分辣~

2.2整体实现

效果预想:游戏大概的效果差不多就是开始运行程序后,先出来一个菜单询问玩家开始游戏或者是退出游戏,选择开始游戏则玩家开始猜数字环节,玩家输入一个数后系统将其与答案相比较,过大过小都给予相应的提示,猜出正确数字后,系统将再次询问是否继续游戏或退出,若选择退出游戏则退出进程,程序停止运行。

本次的游戏整体实现部分主要涉及到选择语句、循环语句、判断语句的复合使用以及一点点的函数部分内容

2.1.1菜单制作

菜单的制作还是十分简单的,就是对“*”以及选项的基本排版,以下为代码实现:

void menu()
{
	printf("********************\n");
	printf("****** 1.Play ******\n");
	printf("****** 0.Exit ******\n");
	printf("********************\n");
	printf("请输入您的选项->");
}

大致的运行效果展示:

2.1.2猜数字功能

若玩家输入数字过大,则会提醒“太大了”,反之,则会提醒“太小了”;若是在规定的次数以内才对则提示挑战成功,反之,则提示挑战失败;一局游戏结束后,系统还将询问是否再来一局,以下为代码实现:

void game()
{
	int a=0,b;
	srand((unsigned int)time(NULL));
	int ranNum = rand()%100+1;//随机生成一个数字
	printf("请输入您想要挑战的猜数字次数:");
	scanf("%d", &a);
	printf("请在%d次机会内猜出数字,否则算游戏失败...\n",a);
	
	while(a){
		printf("请输入您猜的数字->");
		scanf("%d", &b);
		if (b > ranNum)
		{
			printf("太大了\n");
		}
		else if (b < ranNum)
		{
			printf("太小了\n");
		}
		else {
			printf("恭喜你!猜对了!\n\n");
			printf("再来一局吗?\n");
			break;
		}

		a--;

	}
	if (a == 0) {
		printf("很遗憾,挑战失败...\n");
		printf("要再挑战一次吗?\n");
	}
}

我在原有的基础上还加了一个玩家可自行决定猜的次数以获得更丰富的游戏体验,更加惊心动魄!o(*≧▽≦)ツ

大致的运行效果展示:

2.1.3主函数部分

主函数部分主要就是菜单选择部分功能的实现,玩家输入1开始游戏,输入0退出游戏,输入其他数字则提示输入错误

int main()
{
	int input;
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏!\n");
			game();
			break;
		case 0:
			printf("退出游戏...\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}

	} while (input);
	
	return 0;
}

2.3完整代码

实现此游戏的完整代码实现如下:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//猜数字游戏
void menu()
{
	printf("********************\n");
	printf("****** 1.Play ******\n");
	printf("****** 0.Exit ******\n");
	printf("********************\n");
	printf("请输入您的选项->");
}

void game()
{
	int a=0,b;
	srand((unsigned int)time(NULL));
	int ranNum = rand()%100+1;//随机生成一个数字
	printf("请输入您想要挑战的猜数字次数:");
	scanf("%d", &a);
	printf("请在%d次机会内猜出数字,否则算游戏失败...\n",a);
	/*for (int i = 15; i >= 0; i--)
	{
		printf("您还剩%d次机会\n", i);
		printf("请输入您猜的数字->");
		scanf("%d", &a);
		if (a > ranNum)
		{
			printf("太大了\n");
		}
		else if (a < ranNum)
		{
			printf("太小了\n");
		}
		else {
			printf("恭喜你!猜对了!\n\n");
			printf("再来一局吗?\n");
			break;
		}
	} *///这一段不用管,是我尝试用for循环实现的一点实验性代码,嘿嘿~
	while(a){
		printf("请输入您猜的数字->");
		scanf("%d", &b);
		if (b > ranNum)
		{
			printf("太大了\n");
		}
		else if (b < ranNum)
		{
			printf("太小了\n");
		}
		else {
			printf("恭喜你!猜对了!\n\n");
			printf("再来一局吗?\n");
			break;
		}

		a--;

	}
	if (a == 0) {
		printf("很遗憾,挑战失败...\n");
		printf("要再挑战一次吗?\n");
	}
}

void menu();
void game();

int main()
{
	int input;
	do {
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏!\n");
			game();
			break;
		case 0:
			printf("退出游戏...\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}

	} while (input);
	
	return 0;
}

看到这里是不是也感觉手痒痒的了呢~快去上手试试吧!


OK啦!以上便是从最开始的初识rand函数到后面猜数字游戏的完全落地的所有过程唠,感谢你能够耐心地看到这里,希望这篇文章能够对你有帮助,哪怕只有一点点我也很开心啦~

创作不易,既然都看到这里了不妨就点个关注、点个赞再走嘛~再次感谢感谢你~

今后我依旧会继续更新我的代码学习内容,让我们一起加油吧!咱们下次再见~

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值