猜数字游戏(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);
}

五:游戏进阶

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/520012.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

7款前端实战型项目特效分享(附在线预览)

分享7款实用性的前端动画特效 其中有canvas特效、css动画、svg动画等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 CSS春节灯笼特效 基于CSS实现的灯笼特效 灯笼会朝左右两个方向来回的摆动着 以下效果图只能体现…

rk3568 恢复出厂设置横屏

author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Qt,等方面的知识https://blog.csdn.net/qq_40715266?typeblog 在使用rk3568开发过程&#xff0c;虽然显示的方向已经改成了横屏&#xff0c;但是恢…

猫冻干价格差距大的原因是什么?价格合理、性价比高的生骨肉冻干分享

科学养猫知识的普及&#xff0c;铲屎官们逐渐意识到了生骨肉冻干喂养的益处。然而&#xff0c;价格因素仍是部分铲屎官的阻碍。实际上&#xff0c;像我这样的资深铲屎官&#xff0c;早已认识到生骨肉冻干的价值。虽然价格略高于烘焙粮和膨化粮&#xff0c;但其对猫咪的益处是实…

世界的本质是旋转(5)-在复平面上驱动软件无线电SDR发射BPSK波形

在上一篇文章中&#xff0c;我们介绍了复平面、拍照采样的一些思维实验。从本节开始&#xff0c;转入现实应用&#xff0c;通过控制复平面向量的位置&#xff0c;实现一个完整的BPSK全双工通信通道。 发射方&#xff1a;通过控制复平面向量在各个时刻的位置来携带信息的技术&a…

管道读写规则及 PIPE_BUF 涉及的写原子性问题

结论&#xff1a; 一、当管道内没有数据可读时 O_NONBLOCK disable&#xff1a;read 调用阻塞&#xff0c;直到有可读数据 O_NONBLOCK enable&#xff1a; read 调用返回 -1&#xff0c;errno 值为 EAGAIN 二、当管道已满或者剩余空间不够时 O_NONBLOCK disable&#xff1a;wr…

Vue时间轴

之前有这样子的需求没有用第三方插件于是自己写一个简单的时间轴 时间轴滚动条并左右切换滚动条位置相对应移动 <div class"time-scrollbar"><div v-if"timeLineData.length>0" class"scrollbar-content"><div class"ar…

vue3的基本使用(1)

Vue3的基本使用&#xff08;1&#xff09; 初识vue31. vue3简介2. 性能提升3. 源码升级 Vue3的创建1. vue-cli创建2. vite创建 Composition API的区别&#xff08;组合式&#xff09;setup函数响应式数据1. ref响应式2. reactive响应式 toRefs与toRef简单介绍 初识vue3 1. vue…

Vue系列-环境快速搭建

vue环境快速搭建 演示视频 快速搭建Vue开发环境pnpm和yarn 1. 基本信息 作者: GMCY系列: Vue仓库: GitHub | Gitee话题(GitHub): tools \ vue创建时间: 2024/03/02 2. 介绍 功能 批处理文件vue 环境的快速搭建nodejs, npm, pnpm, yarn 自动 下载安装npm, pnpm, yarn 自动 …

CVE-2024-27198 JetBrains TeamCity 身份验证绕过漏洞分析

漏洞简介 JetBrains TeamCity 是一款由 JetBrains 公司开发的持续集成和持续交付服务器。它提供了强大的功能和工具&#xff0c;旨在帮助开发团队构建、测试和部署他们的软件项目 JetBrains TeamCity发布新版本修复了两个高危漏洞JetBrains TeamCity 身份验证绕过漏洞(CVE-20…

企智汇:引领企业项目管理的数字智能化管理系统工具!

随着数字化时代的来临&#xff0c;企业对项目管理的要求也日益增高。面对日益复杂的业务流程和海量数据&#xff0c;如何有效地管理项目、整合资源、优化流程、提高管理效率&#xff0c;成为了摆在企业面前的重要课题。在这样的背景下&#xff0c;专业做了10年项目管理系统的&a…

vsphere虚拟机迁移是灰色如何解决

vsphere虚拟机迁移是灰色如何解决 问题描述&#xff1a; 在vsphere中&#xff0c;迁移虚拟机时迁移按钮是灰色&#xff0c;无法迁移&#xff0c;关机之后也无法迁移 虚拟机按钮为灰色 找到虚拟机存储对应的位置&#xff0c;查询是否有.vmx虚拟机文件 查询中发现有.vmx文件存…

JS使用方式

JS是解释性语言&#xff0c;所以不需要搭建类似C#/Java之类的开发运行环境&#xff0c;因为他们是编译型语言。JS一般运行在浏览器中或者node环境中&#xff0c;这里都是JS引擎的功劳。 node环境使用 推荐使用nvm管理node版本&#xff0c;nrm管理代理地址。 安装node&#xf…