分支与循环的应用—猜数字游戏简单实现

1. 前言

  在学习完分支与循环语句后,我们就可以进行一些简单的应用了,本篇文章将简要介绍猜数字游戏。

2. 设计程序

我们这样思考:
  假如让电脑可以生成一个随机数,我们输入一个数字进行猜数字,当我们猜大了,提示:“猜大了,继续猜”。当我们猜小了,提示:“猜小了,继续猜”,当我们猜对了。提示:“恭喜你,猜对了,结束游戏”。我们发现这样就进行了一次游戏了,那我们肯定不止玩一把,于是继续玩,不用退出程序。
我们整理一下思路:
请添加图片描述
我们发现,这个程序还要有提示菜单去指引玩家,并且我们想要让玩家自行选择开始游戏和退出游戏,我们可以用’1’来表示开始游戏,用’0’表示结束游戏,玩家选择1开始,玩家选择0退出。当玩家选择的不是1或者0时,提示"选择错误请,重新选择"。
菜单设计逻辑:
请添加图片描述

2.1 生成随机数(难点)

我们想要引入一个随机数,怎么办?不要慌张,在这里我们介绍一个函数rand()函数,我们可以在网站上查询到它的使用方法rand介绍,通过查询我们可以知道rand()返回介于0和RAND_MAX之间的整数值。而RAND_MAX的值在任何标准库中为32767
请添加图片描述
在VS2019环境同样如此,选中RAND_MAX转到定义,可以看到RAND_MAX的值。所以rand()可以生成随机数随机数范围是0~32767

选中RAND_MAX,右击,再点击转到定义:
请添加图片描述

请添加图片描述
那我们是不是可以用它生成随机数了呢?

#include <stdio.h>
#include <stdlib.h>
void game()
{
	int ret = rand();
	printf("%d\n", ret);
}
int main()
{
	for(int i=0;i<10;i++)
	game();
	return 0;
}

通过上面代码我们可以看到,确实是生成了十个随机数

请添加图片描述
在一次运行时确实是随机数,但这些随机数在每次运行程序时都是一样的,那我们该怎么正确使用rand()函数,使每次运行时生成的数都不一样呢,我们这时就需要使用srand配合rand使用。
请添加图片描述
srand是初始化随机数的生成器,不需要返回值。

请添加图片描述
请添加图片描述
请添加图片描述
我们发现当我们传给srand的值变化时,随机数的值也在变,所以我们只需要让这个数是一个随时变化的数就行了。
这里我们引入时间戳概念,每时每刻的时间都可以转化为一个数字,我们就叫它时间戳

时间戳转换在线工具

请添加图片描述
请添加图片描述
所以我们要找的这个随时变化的数字就是时间戳
C语言中time函数可以返回一个时间戳,我们如何用呢?
可以看到:
请添加图片描述

而srand接收的参数为unsigned int 类型,我们就需要将这个数强制转换为unsigned int类型。

srand((unsigned int)time(NULL));
//我们不需要传参,传空值NULL就行了

写成这样我们终于可以生成随机数了,虽然两次运行的数变了,但是我们发现这个随机数变化太慢了,导致我们一次运行出现的数时一样的。

第一次运行:
请添加图片描述
第二次运行:
请添加图片描述
对于srand函数,如果我们每时每刻都在调用的话,让rand函数生成的值会很接近,甚至出现相同的现象。
因此我们只在主函数调用一次srand就可以了
请添加图片描述
可以看到生成的数每次都不一样了。
我们这时生成的是0 ~ 32767的数,范围太大了,为了保证游戏的可玩性我们生成1 ~ 100的数

int ret = rand()%100+1;
//由于任何数模上100得到的是0~99的数
//所以模上100加1就是1~100的随机数啦

请添加图片描述
终于,我们解决了生成随机数的问题。

2.2 设计猜数字环节

请添加图片描述
根据上图,我们可以得到猜数字的逻辑实现。
代码实现:

while (1)
	{
		printf("请猜数字:>");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了,继续猜\n");
		}
		else if (guess < ret)
		{
			printf("猜小了,继续猜\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}

3.代码实现

菜单:

void menu()
{
	printf("****************************************\n");
	printf("***********    猜数字游戏  *************\n");
	printf("*********   选择1:开始游戏  ***********\n");
	printf("*********   选择0:退出游戏  ***********\n");
	printf("****************************************\n");
}

猜数字游戏:

void game()
{
	int ret = rand() % 100 + 1;
	int guess = 0;
	//printf("%d\n", ret);添加这一句即可实现作弊模式
	while (1)
	{
		printf("请输入猜的数字:");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了,继续猜\n");
		}
		else if (guess < ret)
		{
			printf("猜小了,继续猜\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}
}

主函数:

int main()
{
	srand((unsigned int)time(NULL));
	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;
}
//可以把玩家选择这一步封装成一个函数,简化主函数

调试实例:
请添加图片描述

4. 完整代码参考

#include <stdio.h>
#include <stdlib.h>//rand和srand所在的头文件
#include<time.h>//time函数所在的头文件
void menu()
{
	printf("****************************************\n");
	printf("***********    猜数字游戏  *************\n");
	printf("*********   选择1:开始游戏  ***********\n");
	printf("*********   选择0:退出游戏  ***********\n");
	printf("****************************************\n");
}

void game()
{
	int ret = rand() % 100 + 1;
	//printf("%d\n", ret);
	int guess = 0;
	while (1)
	{
		printf("请输入猜的数字:");
		scanf("%d", &guess);
		if (guess > ret)
		{
			printf("猜大了,继续猜\n");
		}
		else if (guess < ret)
		{
			printf("猜小了,继续猜\n");
		}
		else
		{
			printf("恭喜你,猜对了\n");
			break;
		}
	}

}

int main()
{
	srand((unsigned int)time(NULL));
	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;
}
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值