有趣的代码——猜数字游戏的实现

前面介绍过很多的C语言常识,但是我们都知道“兴趣是最好的老师”,所以,今天我们用之前讲过的一些知识,加上部分新补充的知识点,写一个“猜数字”的小游戏,来丰富我们的编程学习生活,感受来自C语言的趣味性。

目录

1.猜数字游戏的大致流程

2.游戏实现的思路

3.随机数生成

3.1rand

3.2srand

3.3time

3.4随机数范围设置

4.猜数字游戏的代码实现

5.猜数字游戏的优化


1.猜数字游戏的大致流程

首先由计算机产生一个随机数,并给出这个随机数所在的区间,然后由玩家来猜测这个数,如果玩家猜中这个数,则显示成功并结束本轮游戏,如果猜测次数超过8次,则显示猜测失败并结束本轮游戏。

2.游戏实现的思路

我们在写编程题或者小游戏代码时,最重要的就是理清思路——主体是什么?为了实现目的要创建哪些函数?函数的功能都是什么?只有当我们心中有了一个大体的框架,知道该做些什么时,我们才能更高效地编写代码,完成程序设计。

猜数字游戏的算法如下:

1.提供游戏菜单,由玩家选择是否进行游戏:按“1”开始游戏,按“0”退出游戏,按其他则显示“选择错误,请重新选择”。

2.开始游戏后,先初始化猜测次数count = 0;

3.重复执行下述操作,直到count达到8次:

        3.1玩家输入一个数guess(进行猜测);

        3.2count++;

        3.2如果guess等于secret(计算机产生的随机数),跳出循环;否则显示“错了,请重新猜!你还有8-count次猜测次数,请把握好机会!”

4.如果count达到8次,则显示“超过次数,游戏结束!”;否则,显示“恭喜,猜对了!共猜测count次!”

5。本轮游戏结束,打印菜单并再次询问玩家的选择。

如上面所示,这就是猜数字游戏大体框架的算法呈现。

我们在思考大体框架时不用过多在意具体函数的实现方法,可以先起个能表达其功能的函数名并把它放在需要的位置。(说白了就是先搞一个空壳函数占位置,等到大体框架调试完毕不再有问题后,再去实现这些空壳函数)大体框架代码如下:

#iclude<stdio.h>

int main()
{
    int secret;//随机数怎么建立呢?我们好像暂时也不清楚,那么就先假设一个空壳的,不用在意它。
    int input;
    do
    {    //menu函数在调试大体框架时,也可以是空壳函数
         menu();//打印游戏菜单。我们建立函数可以让主函数不至于太过冗长,而且增加了代码的可读性,使程序模块化。
         printf("请选择:>");
         scanf("%d", &input);
         switch(input)
         {
             case 1:
                 guess(secret);//guess是用来猜测并判断是否正确的函数,这里也是空壳函数
                 break;
             case 0:
                 printf("游戏结束\n");
                 break;
             default:
                 printf("选择错误,请重新选择\n");
                 break;
           }
     }while(input);
     return 0;
}

上面的guess函数就是个空壳函数,我们可以在把主体框架完成后再去实现。而guess函数的功能就是:

①guess(玩家猜测数)= secret,则显示“恭喜,猜对了!同猜测count次!”;

②guess(玩家猜测数)!= secret,则显示“错了,请重新猜!你还有8-count次猜测机会,请把握好机会!”

guess函数的代码实现如下:

void guess(int secret)
{
     int guess= 0, count = 0;
     do
     {
         printf("请输入一个整数>:");
         scanf("%d", &guess);
         count++;
         if(guess == secret) break;
         else pritnf("错了,请重新猜!你还有%d猜测次数,请把握好机会\n",8-count);
     }while(count<8);

     if(count < 8)
         printf("恭喜,猜对了!共猜测%d次!\n",count);
     else
         printf("超过次数,游戏结束!\n");
     
}

menu函数的代码实现如下:

void menu()
{
     printf("***********************\n");
     printf("****** 1. play ******\n");
     printf("****** 0. exit ******\n");
     printf("***********************\n");
}
3.随机数生成

上面我们已经把大体框架和空壳函数都实现,按照正常情况我们的代码已经完成了,只需要调试使其能正常运行即可,但是在这个游戏中我们还需要补充一个新的知识点——随机数的生成。

3.1rand

C语言提供了随机数生成函数rand,该函数返回0~RAND_MAX的一个随机整数,RAND_MAX是在头文件stdlib.h中定义的符号常量,其值与机器字长和编程环境有关,一般为2^15-1或2^31-1。

rand函数原型为:

int rand (void);

#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;
}

大家可以测试两次上面的数据,然后大家会发现随机数的建立到这一步还没有结束。😏

下面是我的代码两次运行结果,大家品一品

我们可以看到虽然一次运行中产生的5个数字是相对随机的,但是下一次运行程序生成的结果和上一次一模一样,这就说明有点问题。 如果再深入了解一下,我们就不难发现,其实rand函数生成的随机数是伪随机的,伪随机数不是真正的随机数,是通过某种算法生成的随机数,而真正的随机数的是无法预测下一个值是多少的。

rand函数是对一个叫“种子”的基准值进行运算生成的随机数。 之所以前面每次运行程序产生的随机数序列是一样的,那是因为rand函数生成随机数的默认种子是1。 如果要生成不同的随机数,就要让种子是变化的。

3.2srand

C语言提供了库函数srand初始化随机种子,例如可以调用库函数time得到当前的系统时间,将当前系统时间作为随机种子。

srand函数的原型为:

void srand (unsigned int seed);

程序中在调用rand函数之前先调用srand函数,通过srand函数的参数seed来设置rand函数生成随 机数的时候的种子,只要种子在变化,每次生成的随机数序列也就变化起来了。那也就是说给srand的种子是如果是随机的,rand就能生成随机数;在生成随机数的时候又需要一个随机数,这就矛盾了,该怎么解决呢? 

3.3time

C语言提供一个函数time,用来获得系统时间。

time函数的原型为:

time_t time (time_t* timer);

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

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

综合上面三个函数及介绍,则随机数生成代码实现为:

srand((unsigned int)time(NULL));//初始化随机种子
rand( );//产生随机数
3.4随机数范围设置

既然是随机数,那么就会从0~RAND_MAX中随机生成一个数字,那我们能猜对吗?😀答案是显然的,别说是八次机会,就是八十次都不一定能猜对。所以,为了照顾玩家的游戏体验,我们也必须设置随机数的范围,让它更为科学和合理。

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

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

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

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

 如果我们要生成a~b之间的随机数,方法如下:

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

4.猜数字游戏的代码实现

前面的准备工作已经做完了,那么就整合所有模块,一起来见证我们努力的成果吧!

#include<stdio.h>
#include <stdlib.h>
#include <time.h>//记得检查所需的函数头文件都引用没有哦 

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

void guess(int secret)
{
     int guess = 0, count = 0;
     do
     {
         printf("请输入一个整数>:");
         scanf("%d", &guess);
         count++;
         if(guess == secret) break;
         else printf("错了,请重新猜!你还有%d猜测次数,请把握好机会\n\n",8-count);
     }while(count<8);

     if(count < 8)
         printf("恭喜,猜对了!共猜测%d次!\n",count);
     else
         printf("超过次数,游戏结束!\n");
     
}

int main()
{
	srand((unsigned int)time(NULL));
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {    
    	int secret = rand() %100;//生成0~99之间的随机数 
		//menu函数在调试大体框架时,也可以是空壳函数
         menu();//打印游戏菜单。我们建立函数可以让主函数不至于太过冗长,而且增加了代码的可读性,使程序模块化。
         printf("请选择:>");
         scanf("%d", &input);
         switch(input)
         {
             case 1:
                 guess(secret);//guess是用来猜测并判断是否正确的函数,这里也是空壳函数
                 break;
             case 0:
                 printf("游戏结束\n");
                 break;
             default:
                 printf("选择错误,请重新选择\n");
                 break;
           }
     }while(input);
     return 0;
}

上面的代码进行了细微的调整——把rand的随机种子初始化放在do之前,然后把随机数的生成放在do…while语句中,这样我们每一轮游戏所猜的数字都是不同的,且不必重复初始化随机种子。

5.猜数字游戏的优化

我们玩几局就会发现,虽然限制了随机数的范围,但想在8次机会中猜对还是有些难度,所以为了我们亲爱的玩家,我们就再降低难度——当他们猜完数字后,给他们提示:“猜大了”或者“猜小了”

优化后的代码如下:

#include<stdio.h>
#include <stdlib.h>
#include <time.h>//记得检查所需的函数头文件都引用没有哦 

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

void guess(int secret)
{
     int guess = 0, count = 0;
     do
     {
         printf("请输入一个整数>:");
         scanf("%d", &guess);
         count++;
         if(guess == secret) 
		 	break;
         else if(guess > secret)
         {
         	if(count != 8) 
		 		printf("猜大了,请重新猜!你还有%d猜测次数,请把握好机会\n\n",8-count);
		 	else 
		 		printf("可惜最后还是猜大了\n");
		 }	
		 else
		 {
         	if(count != 8) 
		 		printf("猜小了,请重新猜!你还有%d猜测次数,请把握好机会\n\n",8-count);
		 	else 
		 		printf("可惜最后还是猜小了\n");
		 }
     }while(count<8);

     if(count < 8)
         printf("恭喜,猜对了!共猜测%d次!\n",count);
     else
         printf("不好意思,次数已用完,游戏结束!\n");
     
}

int main()
{
	srand((unsigned int)time(NULL));
    int input = 0;
    srand((unsigned int)time(NULL));
    do
    {    
    	int secret = rand() %100;//生成0~99之间的随机数 
		//menu函数在调试大体框架时,也可以是空壳函数
         menu();//打印游戏菜单。我们建立函数可以让主函数不至于太过冗长,而且增加了代码的可读性,使程序模块化。
         printf("请选择:>");
         scanf("%d", &input);
         switch(input)
         {
             case 1:
                 guess(secret);//guess是用来猜测并判断是否正确的函数,这里也是空壳函数
                 break;
             case 0:
                 printf("游戏结束\n");
                 break;
             default:
                 printf("选择错误,请重新选择\n");
                 break;
           }
     }while(input);
     return 0;
}

猜数字小游戏到这里算是结束喽,不知道大家学习的过程辛苦不辛苦,反正我是痛并快乐着的🙂🙂🙂

关于猜数字的更多玩法和可能性,就全权交由聪明的大家了。当然大家有啥好想法又不想一个人搞的,也可以在评论区发出来,大家一起交流交流,研究研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值