云边有个稻草人-CSDN博客

我的个人主页

目录

云边有个稻草人-CSDN博客

前言

猜数字游戏的游戏要求

1. 随机数的生成

1.1 rand

1.2 srand

1.3 time

1.4 设置随机数的范围

2. 猜数字游戏实现

2.1 游戏实现基本思路

2.2 代码实现

Relaxing Time!

——————————————《My type》——————————————


正文开始——

前言

前面我们学习了C语言常见概念数据类型和变量以及分支与循环,现在我们就可以整合这些知识写一个 interesting 的小游戏啦,此刻展现我们学习成果的时候到了!今天我们尝试猜数字游戏代码的编写。

猜数字游戏的游戏要求

  1. 电脑自动随机生成一个1~100的随机数
  2. 玩家猜数字,猜数字的过程,根据猜测数据的大小给出猜大了还是猜小了的反馈,直到猜对,游戏结束。

唉,有个疑问,想要完成猜数字游戏,第一步那肯定是先产生一个随机数,那么该如何产生一个随机数呢?

1. 随机数的生成

1.1 rand

C语言提供了一个函数叫rand,这函数可以生成随机数的,函数原型如下:

int rand (void);

rand函数会返回一个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的大小是依赖编译器上实现的,但是大部分编译器上是32767;同时使用 rand函数 需要包含头文件,stdlib.h

那我们就来试用一下rand函数,多调用几次看看产生的随机数

#include<stdio.h>
#include<stdlib.h>

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函数 生成随机数的默认种子是1。如果要生成不同的随机数,就要让种子是变化的。

那如何让种子是变化的呢?那我们来学习srand就知道啦

1.2 srand

 C语言又提供了一个函数叫srand,用来初始化随机数的生成器的,srand的原型如下:

void srand (unsigned int seed);

程序中在调用 rand函数 之前先调用 srand函数,通过srand函数的参数seed来设置rand函数生成随机数时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。BUT!想一想,此时我们还得给 srand 的参数传一个随机数,这,这,就,想想何必呢,本来一开始就是想要一个随机数,结果现在折腾半天还需要一个随机数才能产生另一个随机数,看来这种方法不可行呀,换一条路吧。(这让我想起了,“你已偏离路线,已为你重新规划路线,请在合适的地方掉头”) 

在程序中我们一般是使用程序运行的时间作为种子的,因为时间是时刻在发生变化。下面来学习time函数

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函数 返回的这个时间差值也被叫做:时间戳

使用该函数要包含头文件:time.h

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

time (NULL);//调用time函数返回时间戳,这里没有接收返回值

那么我们再尝试改写生成随机数的代码见下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main()
{
	//使用time函数的返回值来设置种子
	//因为srand的参数是unsigned int类型,我们将time函数的返回值强制类型转换一下
	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函数是不需要频繁调用的,一次运行的程序中调用一次就够了。

根据游戏要求,我们要生成1~100之间的随机数,可是上面我们生成的数字是在0~32767之间的数字,那么我们该如何生成1~100之间的数字呢?

1.4 设置随机数的范围

如果我们要生成0~99之间的数字,方法见下:

rand () % 100;//余数的范围是0~99

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

rand () % 100+1;//在原余数的基础上+1,那么余数范围就变成了1~100

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

rand () % 101+100;

挺简单。这样就可以生成1~100之间的随机数了,见下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main()
{
	//使用time函数的返回值来设置种子
	//因为srand的参数是unsigned int类型,我们将time函数的返回值强制类型转换一下
	srand((unsigned int)time(NULL));
	printf("%d\n", rand() % 100 + 1);
	printf("%d\n", rand() % 100 + 1);
	printf("%d\n", rand() % 100 + 1);
	printf("%d\n", rand() % 100 + 1);
	printf("%d\n", rand() % 100 + 1);

	return 0;
}

2. 猜数字游戏实现

2.1 游戏实现基本思路

基本的外部框架借助 do-while循环 来实现,实现循环的条件还挺妙的我赶脚,下一次进入循环可以借助上一次的选择,仔细品一品。首先上来就先打印菜单,我们可以把菜单(以及后面的游戏逻辑)封装成一个函数,没有冗杂的函数这样main函数里面更显逻辑清晰,然后根据我们的选择展开后续;如果我们选择进入游戏,需要先产生一个随机数,注意不要把产生随机数的环节加入到while循环里面,不然每次猜都会生成一个随机数可能永远都猜不到,因为rand函数的种子是以time函数的返回值为参数的,时间戳在随时变化,那么如果放到循环里面每次判断一轮产生的rand的返回值都不一样随机数也就在变化,除非你好运爆棚一次就中,记得买个彩票哦;再接着我们就可以猜数字了,判断我们猜大了还是猜小了直到猜对为止,或者我们可以限制猜的次数,正如下面代码实现的那样,然后就没有然后了......快试一试吧

2.2 代码实现

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<time.h>
#include<stdlib.h>

void menu()
{
	printf("********************\n");
	printf("****** 1.play ******\n");
	printf("****** 0.exit ******\n");
	printf("********************\n");
}

void game()
{
	int count = 5;
	//产生一个1~100之间的随机数
	int r = rand() % 100 + 1;
	int guess = 0;
	while (count)
	{
		printf("请猜数字>: ");
		scanf("%d", &guess);
		if (guess > r)
		{
			printf("猜大了\n");
		}
		else if (guess < r)
		{
			printf("猜小了\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
		count--;
		printf("还剩余%d次机会\n", count);
	}
    
    //跳出while循环有2种可能,一种是猜对了,一种是count==0结束循环
	printf("很遗憾,没有机会了,正确的数字是 %d ,再接再厉\n", r);

}

int main()
{
	//设立一个变量存放菜单选择
	int input = 0;

	//用time函数的返回值来设置种子,注意要进行强制类型转换
	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\n");
			break;
		}

	} while (input);

	return 0;
}

新手入门必学的猜数字游戏,还挺简单的吧,后面我还会继续出各种有趣小游戏的实现,一起加油!


Relaxing Time!

《My type》

My Type_The Chainsmokers、Emily Warren_高音质在线试听_My Type歌词|歌曲下载_酷狗音乐

云边有个稻草人

期待与你的下一次相遇!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐