目录
前言
猜数判定
if else 语句
重复到猜对为止(do语句,while语句)
随机设定目标数字
srand函数大显神功
限制次数并保存输入记录
尾声
前言 施律.C语言小游戏系列预计共有10个,较适合于已经学习完C语言入门内容,并想要掌握实际编程能力的程序猿。
猜数游戏在大家初学的课本上应该都有,难度系数不大,属于一遍过的那种程序。但再小的苍蝇也有肉啊!其实猜数游戏也包含了许多实用性的技巧。长话短说,接下来听施律.为渴望提升的你讲解C语言小游戏(一)----猜数游戏。
猜数判定 先来个测试版的“猜数游戏”。通过if else语句、scanf函数键入数值和“目标数字”进行比较,并显示出比较的后果。
#include int main()
{
int no;
int ans = 5;
printf("Please guess0--9:\n");
printf("是多少呢?\n");
scanf("%d", &no);
if (no > ans)
printf("Too big!\n");
else if (no < ans)
printf("Too small\n");
else
printf("Yes!You are right!\n");
\\\n是一种转义字符,表示换行 return 0;
}
本游戏设立的数是5。如果输入的数小于5,则输出Too small!;如果输入的数大于5,则输出Too big!。
if else 语句 本程序中的if语句采用以下形式。
if(表达式)语句 else if(表达式)语句 else 语句 |
接下来我们讨论讨论多分支的方法,即用上述语句更另外2种if else 形态语句进行对比,得出优劣。话不多说,上代码!
if(no > ans)
printf("Too big!\n");
else if(no < ans)
printf("Too small!\n");
else
printf("Yes!You are right!\n");
//1if(no > ans)
printf("Too big!\n");
else if (no < ans)
printf("Too small!\n");
else if (no == ans)
printf("Yes!You are right!\n");
//2if(no > ans)
printf("Too big!\n");
if (no < ans)
printf("Too small!\n");
if (no = ans)
printf("Yes!You are right!\n");
//3
我们来分析一下程序2、3较于1看看能得出什么结论。程序2较程序1追加了(no==ans)判断,这其实是非常多余的;程序3的三个if并列,无论no和ans之间的大小关系如何,程序都会对这三个条件进行判断。
接下来我们再通过图表的方式分析程序1、2、3所进行的判断,看看能得出什么结论。下面的【1】判断no>ans,【2】判断no
大小关系 | no>ans时 | no | no==ans时 |
1 | 【1】 | 【1】【2】 | 【1】【2】 |
2 | 【1】 | 【1】【2】 | 【1】【2】【3】 |
3 | 【1】【2】【3】 | 【1】【2】【3】 | 【1】【2】【3】 |
重复到猜对为止(do语句,while语句) 上个程序只允许玩家输入一次数值操作起来是十分无趣的。所以我们将程序改良一下,让玩家可以一直重复输入直到猜对为止。那我们该如何实现输入多次呢?我们学到的循环该派上用场了。利用do语句循环实现多次输入,代码如下:
#include int main()
{
int no;
int ans = 7;
printf("请猜一个0-9的数。\n\n");
do {
printf("是多少呢?\n");
scanf("%d", &no);
if (no > ans)
printf("Too big!\n");
else if (no < ans)
printf("Too small!\n");
else
printf("Yes!You are right!\n");
} while (no != ans);
return 0;
}
do语句是先循环后判断的,跟它的好兄弟while语句和for语句不同(后面会讲到)。在运用到do语句的过程中要时刻记得它的末尾是有分号“ ; ”的。如上所示,do 语句的控制表达式是no!=ans,运算符!=对左边和右边的操作数的值是否不相等这一条件进行判断。如果这个条件成立,程序就会生成int型的1表示继续,不成立则生成int型的0表示循环结束。
接下来我们看看用while语句实现猜数游戏:
#include int main()
{
int no;
int ans = 7;
printf("请猜一个0-9的数。\n\n");
while (1) {
printf("是多少呢?\n");
scanf("%d", &no);
if (no > ans)
printf("Too big!\n");
else if (no < ans)
printf("Too small!\n");
else
break;
}
printf("Yes!You are right!\n");
return 0;
}
while语句是先判断后循环,跟前面的do语句的循环方式是不一样的。如上,while的控制表达式是1,所以循环会永远进行下去。这样的循环岂不是“无限循环”?那这样的循环该如何破解呢?break语句大显神功,直接强制跳出了循环语句。
随机设定目标数字 在前面的游戏中,自己设定的数自己猜显得太枯燥无趣了,要是能随机生成数字来猜则会增加很多的趣味性。仔细想想,我们好像能用rand函数来生成随机数。rand的功能是计算0-RAND_MAX(很多初学的小伙伴不知道RAND_MAX,这其实是头文件包含的一个宏,规定它的值不能小于编译环境所规定的最小数,最小为32767)的伪随机整数序列。何为“伪”?且听我一一分析。先上代码:
#include
#includeint main()
{
int retry;
//再运行一次? printf("在这个编译环境中能够生成0-%d的随机数。\n", RAND_MAX);
do {
printf("\n生成了随机数%d。\n", rand());
printf("再运行一次?(0)否(1)是:");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
聪明的小伙伴可以自行ctrl+c到编译器上看看,多执行几次程序会发现生成的随机序列是一模一样的!rand函数看似生成随机实则不随机,是有一定规律可循的。为什么呢?这是因为rand函数的默认种子(rand函数是对一个叫作“种子”的基准值加以运算来生成随机数的)是1。如果我们想要生成不同的随机序列,就必须更换种子的值。
srand函数大显神功 srand函数就能解决上面所描述的窘境。它的功能是给后续调用的rand函数设置一个种子,用于生成新的伪随机数序列。如果用同一个种子的值调用本函数,就会生成相同的伪随机数序列。如果在调用本函数之前调用了rand函数,就相当于程序在一开始调用了本函数,把种子设定成了1,最后会生成一个种子值为1的序列。此外,其他库函数在运行时会无视本函数的调用。
该怎么表示呢?打个比方srand(50)和srand(40),它们生成的随机序列是不同的,且看下表:
种子为50时,生成235->666->777->231->3489..... |
种子为40时,生成222->2678->2235->1463->87..... |
#include
#include
#include int main()
{
int retry;
srand(time(NULL));
printf("在这个编译环境中能够生成0-%d的随机数。\n", RAND_MAX);
do {
printf("\n生成了随机数%d。\n", rand());
printf("再运行一次?(0)否(1)是:");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
RAND_MAX在上文中提到它所生成的数可能是非常大的,几万几十万都有可能。那么我们该怎么控制srand生成的随机值呢?我们可以运用求余运算来实现。普及一下求余的概念。请看下面:
rand()%6是生成0到5的随机数,因为求余运算得出的结果是不会大于被余数的 |
#include
#include
#include int main()
{
int retry;
srand(time(NULL));
printf("在这个编译环境中能够生成0-%d的随机数。\n", RAND_MAX);
do {
printf("\n生成了随机数%d。\n", rand());
printf("再运行一次?(0)否(1)是:");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
这样游戏玩起来就不会枯燥乏味了!但好像缺少了点紧张刺激,我们应该再对该程序进行升级----限制次数并保存输入记录。
限制次数并保存输入记录 如果游戏能够限制玩家的输入次数和保存玩家输入的值,玩家的游戏体验一定会有大幅度的升级!想到保存输入的值,我们肯定能联想到用数组保存。通过数组遍历,将玩家输入的值一一存入,并在游戏结束后呈现给玩家,让玩家知道自己猜的数字距离目标数字有多近。先上代码:
#include
#include
#include #define MAX_STAGE 10int main()
{
int i;
int stage;
//玩家已经操作的次数
int no;
int ans;
int num[MAX_STAGE];
//玩家能操作的最大次数 srand(time(NULL));
ans = rand() % 1000;
printf("请猜一个0-999的整数。\n\n");
stage = 0;
do {
printf("还剩%d次机会。是多少呢: ", MAX_STAGE - stage);
scanf("%d", &no);
num[stage++] = no;
if (no > ans)
printf("Too big!\n");
else if (no < ans)
printf("Too small!\n");
} while (no != ans && stage < MAX_STAGE);
if (no != ans)
printf("很遗憾,正确答案是%d。\n", ans);
else
{
printf("Yes!You are right!\n");
printf("您用了%d次猜中了。\n", stage);
} puts("\n--- 输入记录 ---");
for (i = 0;
i < stage;
i++)
printf(" %2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
return 0;
}
我们来分析分析上面的代码。
(1)先讲一个错误的例子。初级程序猿经常会犯这样的错误:
int n=10;
int arr[n]={0};
乍一看貌似和上面的差不多,但实际上这是错误的写法。而先定义一个宏,再在数组【】中引用宏则是正确的写法;
(2)代码num[stage++]=no; 是后置++,其利用for循环来对stage数进行增加。通过反复的循环处理,即可把玩家输入的值按顺序依次存入数组。
(3)在这段代码中我们运用了上面未曾讲到的for语句来显示输出记录。我们将这段代码拉出来单独讲解:
for (i = 0;
i < stage;
i++)
printf(" %2d:%4d %+4d\n", i + 1, num[i], num[i] - ans);
首先把i的值设为0,当i的值小于stage时,就不断往i的值上+1,以此来让循环体运行stage次(stage的值等于玩家输入数值的次数)。
%2d %4d符号与字母之前的数字代表它们的域宽,而%+4d中的+4是将数字向右靠齐。
下面的·代表一个空格,以125为例 |
%4d125· |
%+4d·125 |
尾声 以上就是施律.对本系列第一个游戏----猜字游戏的理解与分析,感谢能观看到这里的你!如果觉得本篇博客对正在学习编程的你有帮助的话,请给施律.多一点的支持与关注!接下来的10多天时间里施律.将和大家畅玩其他用编程实现的游戏,希望下次的我能为大家奉上更好的游戏,也希望下次的博客有你!
【易懂|C语言小游戏(一)----猜数游戏】
推荐阅读
- 易懂|送给好朋友的圣诞树+带名字的爱心 圣诞特别版
- 易懂|动态内存分配浅论
- 笔记|C语言扫雷简化版(b站鹏哥)
- GUI-PyQt5|python3GUI--打造一款音乐播放器By:PyQt5(附下载地址)
- GUI-PyQt5|python3GUI--疫情信息快速查看工具By:PyQt5(附源码)
- 第十二届蓝桥杯大赛软件赛省赛B组题解
- 数据结构之究竟什么是树
- 数据结构|遗落在时光里的静态链表(线性表的静态存储)---C语言版
- 数据结构|栈(操作受限的线性表)---C语言版