当前位置:网站首页>C语言实战之猜数游戏
C语言实战之猜数游戏
2022-07-23 00:51:00 【子夜的星】
C语言之猜数游戏
前言
所涉及的知识内容
1.if 分支语句、do、while、for循环语句
2.随机数的生成与种子的变更
3.数组的设定与获取
猜数游戏设置步骤

游戏设计
条件分支(不可玩版)
为了实现最后的猜数游戏,我们先从一个简陋的猜数游戏谈起。设计一个程序,用来显示玩家输入的数值与计算机中设置好的数值的比较结果。
#include<stdio.h>
int main()
{
int a;//读取的数字
int ans;//简陋版本设定的目标数字
ans = 30;//设置需要猜的数为30
printf("请输入一个你猜测的整数:");
scanf("%d", &a);
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
else
{
printf("你猜对了!\n");
}
return 0;
}
上述程序用到了if 分支语句,不熟悉的朋友可以复习下相关语句。
重复循环(粗糙版)
上述代码虽能展示出玩家所猜的结果与设定数的大小关系,但是却只能玩一次,每猜一次程序就会结束,想猜第二次就需要重新打开程序,这样未免太过无趣。因此我们需要使用do 语句来让程序可以一直重复,直到玩家猜对为止。
#include<stdio.h>
int main()
{
int a;
int ans;
ans = 30;
do
{
printf("请输入一个你猜测的整数:");
scanf("%d", &a);
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
} while (a != ans);
printf("你猜对了!");
return 0;
}
上述程序用到了do循环语句,不熟悉的朋友可以复习下相关语句。
当然,我们的可以实现重复循环这一要求的语句并不止do语句,我们下面用while语句实现上述要求。
#include<stdio.h>
int main()
{
int a;
int ans;
ans = 30;
while (1)
{
printf("请输入一个你猜测的整数:");
scanf("%d", &a);
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
else
{
break;
}
}
printf("你猜对了!");
return 0;
}
上述程序用到了while语句,不熟悉的朋友可以复习下相关语句。
while语句的控制表达式为1,1为真故循环会一直进行,但是当我们猜对了数字,那么就会执行break语句,break语句的作用是跳出循环,如此我们便用while语句完成了循环的要求。
这里我们来区分以下do语句和while语句的具体区别:
do语句是先循环后判断,无论如何,循环体都会被运行一次。
while语句和for语句都是先判断后循环,循环体可能会一次也不执行。
数字随机(可玩版)
上述代码虽然能够玩,但是当玩家答对一次后,以后就能一次猜出答案,为了能让游戏的每次答案都不同,提高游戏的可玩性,我们应该让每次的答案都随机起来。下面我们写几组生成随机数的代码。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int retry;
printf("能够生成0~%d的随机数。\n", RAND_MAX);
do
{
printf("\n生成了随机数%d\n", rand());
printf("是否再运行一次?否···0 是···1\n");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
上述程序用到了rand语句,不熟悉的朋友可以复习下相关语句。
介绍以下rand函数:
使用rand函数需要引用头文件:#include<stdlib.h>
rand的功能:rand函数返回一个范围从0到RAND_MAX的伪随机整数。
rand的返回值:返回生成的伪随机数整数
上述程序虽然能够生成一组随机数,但是当我们多次运行就会发现。每次运行时生成的随机数序列都是一样的,这种rand生成的值并不是真正的随机,因此我们需要对其进行改进。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
int retry;/*再来一次*/
srand(time(NULL));/*根据当前时间设置随机数种子*/
printf("能够生成0~%d的随机数。\n", RAND_MAX);
do
{
printf("\n生成了随机数%d\n", rand());
printf("是否再运行一次?否···0 是···1\n");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
上述程序用到了srand语句,不熟悉的朋友可以复习下相关语句。
使用srand设置了种子的值为程序运行的时间,这样就能保证每次运行时候的种子不同自然每次生成的随机数序列就不会相同了!
介绍以下srand函数:
使用srand函数需要引用头文件:#include<time.h>
srand的功能:srand函数设置生成一系列伪随机整数的起点,简而言之,给rand函数设置一个种子,用于生成后续的随机数序列。如果不适用srand函数,那么rand函数会一开始就把种子值设置为1。
上述代码虽然能够完成随机数生成这一要求,但是,rand函数生成的值为:0~RAND_MAX (32767) ,我们需要的随机数值并不能完全在自己设定的范围之内,因此我们需要进一步改进,设置以下生成数的范围,这样才能让游戏更加具有可玩性。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
int a;/*输入的值*/
int ans;/*随机数*/
srand(time(NULL));/*设置时间种子*/
ans = rand() % 100;/*生成的随机数除以100的余数赋给ans*/
puts("请输入一个0~99的数字。");
do
{
printf("请输入一个你猜测的整数:");
scanf("%d", &a);
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
} while (a != ans);
printf("你猜对了!");
return 0;
}
我们将rand函数生成的随机数除以100再取余数,就能获得一组范围在0~99的随机数
rand()% (a+1) 将范围设置在大于等于0且小于等于a的范围内
b+rand()% (a+1)将范围设置在大于等于b且小于等于b+a的范围内
限制次数(次完美版)
其实上述代码已经能有不错的游戏体验了,但是我们可以让他变得更加有意思,我们可以设置输入次数的限制,使游戏变得更加有趣。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
int a;/*输入的值*/
int ans;/*随机数*/
const int max = MAX_STAGE;/*最多输入次数*/
int remain = max;
srand(time(NULL));/*设置时间种子*/
ans = rand() % 100;/*生成的随机数除以100的余数赋给ans*/
puts("请输入一个0~99的数字。");
do
{
printf("你还剩余%d次机会,请输入你猜测的整数:",remain);
scanf("%d", &a);
remain--;
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
} while (a != ans && remain > 0 );
if (a != ans)
{
printf("\n很遗憾,正确答案为:%d", ans);
}
else
{
printf("回答正确!\n");
printf("你用了%d次猜中了。\n",max-remain);
}
return 0;
}
这里声明最多次输入次数变量max的时候使用了const使变量的值无法修改,这样就不用担心后续reamin–写成了max–而不自知的情况了(编译器会报错)
在修改数据声明时,const关键字指定该对象或变量不可修改。当跟随成员函数的形参列表时,const关键字指定函数不修改被调用的对象。
保存输入(完美版)
上述代码已经很完美了,但是如果我们再添加保存输入记录的功能,就会使这个游戏更加完美。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
int i;
int stage = 0;/*已输入次数*/
int a;/*读取的值*/
int ans;/*目标的值*/
int num[MAX_STAGE];/*读取的值的历史记录*/
srand(time(NULL));
ans = rand() % 100;
printf("请输入一个0~99的数字\n");
do
{
printf("你还剩余%d次机会,请输入你猜测的整数:", MAX_STAGE - stage);
scanf("%d", &a);
num[stage++] = a;
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
} while (a != ans && stage < MAX_STAGE);
if (a != ans)
{
printf("\n很遗憾,正确答案为:%d", ans);
}
else
{
printf("回答正确!\n");
printf("你用了%d次猜中了。\n", stage);
}
puts("------输入记录-------");
for (i = 0; i < stage; i++)
printf("%2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
return 0;
}

为了让玩家的历次记录保存,需要将其储存在数组里面。
总结
游戏代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_STAGE 10 /*最多输入的次数!*/
int main()
{
int i;
int stage = 0;/*已输入次数*/
int a;/*读取的值*/
int ans;/*目标的值*/
int num[MAX_STAGE];/*读取的值的历史记录*/
srand(time(NULL));
ans = rand() % 100;
printf("请输入一个0~99的数字\n");
do
{
printf("你还剩余%d次机会,请输入你猜测的整数:", MAX_STAGE - stage);
scanf("%d", &a);
num[stage++] = a;
if (a > ans)
{
printf("你猜大了!\n");
}
else if (a < ans)
{
printf("你猜小了!\n");
}
} while (a != ans && stage < MAX_STAGE);
if (a != ans)
{
printf("\n很遗憾,正确答案为:%d", ans);
}
else
{
printf("回答正确!\n");
printf("你用了%d次猜中了。\n", stage);
}
puts("------输入记录-------");
for (i = 0; i < stage; i++)
printf("%2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
return 0;
}
运行结果

知识总结
生成随机数的准备工作
生成随机数之前需要基于当前时间设定 ”种子“的值。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
srand(time (NULL));
在最初调用rand函数的时候先调用srand函数设置种子,如果没有调用srand函数,那么rand函数的种子会默认为1,这样产生的数就不够随机。
生成随机数的小技巧
调用rand函数后会随机生成0~RAND_MAX的随机数,RAND_MAX取决于编译器,大于等于32767.
如果需要将随机数限定在某个范围,可以像下面这样操作:
rand()% (a+1) 将范围设置在大于等于0且小于等于a的范围内。
b+rand()% (a+1)将范围设置在大于等于b且小于等于b+a的范围内。
三种循环的区别
do语句是先循环后判断,无论如何,循环体都会被运行一次。
while语句和for语句都是先判断后循环,循环体可能会一次也不执行。
边栏推荐
- 50道经典计算机网络面试题,你答得上几个?(二)
- Swin transformer object detection project installation tutorial
- 基于共轭梯度法的对抗攻击
- [array]nc77 adjust the array order so that odd numbers precede even numbers (one) - medium
- Regular expression conversion to corresponding text gadget
- 【并发编程】第二章:从核心源码深入ReentrantLock锁
- 2000. 反转单词前缀
- 涅槃重生!字节大牛力荐大型分布式手册,凤凰架构让你浴火成神
- 基于SSM的博客系统【带后台管理】
- 一个月学透阿里整理的分布式架构笔记
猜你喜欢

IDM下载器免费高质量的Win下载工具无使用限制

UGUI源码解析——IClippable

Mathematical modeling -- graph and network models and methods (II)

妙啊!美团 OCTO 分布式服务治理系统,这描述也太清晰了

DOM series prohibit selected text and prohibit right-click menu

disruptor框架无锁实现生产者消费者代码实例

数学建模——图与网络模型及方法(二)

AirServer第三方投屏软件v7.3.0中文版 (Airplay终端实用工具)

UGUI源码解析——MaskableGraphic

Unity3d learning note 9 - loading textures
随机推荐
实行自动化网络性能监控的优势
券商真的有保本型理财产品吗?
disruptor框架无锁实现生产者消费者代码实例
元宇宙并不是一个像互联网一样将流量看成是终极追求的存在
LiveQing直播RTMP点播视频流媒体平台如何携带登录接口返回的sid和token接口调用鉴权streamToken视频流鉴权
Practical exercise | a simple method for MySQL processlist table and Navicat monitor to identify slow queries
The role of include in makefile
数学建模——插值拟合
股票开户网上开户安全吗,银河证券怎么样
关系表达式 大于> 小于< 全等=== Nan isNan() 逻辑运算符 双感叹号!! && || % ++ -- 短路计算 赋值表达式 快捷运算符 顺序 闰年
UGUI源码解析——IMaskable
Must I make money by buying REITs funds? Is it safe to open an account
It is not safe to open an account in tongdaxin
PMP备考心得 | 好的习惯、好的过程、好的结果
Found a useful data analysis tool
Number theory -- division and blocking, common classic examples.
UGUI源码解析——Mask
NodeJS 基于 Dapr 构建云原生微服务应用,从 0 到 1 快速上手指南
疫情隔离区订餐系统的开发
Anti attack based on conjugate gradient method