失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C语言小游戏(一)----猜数游戏

C语言小游戏(一)----猜数游戏

时间:2018-09-27 04:09:55

相关推荐

C语言小游戏(一)----猜数游戏

目录

前言

猜数判定

if else 语句

重复到猜对为止(do语句,while语句)

随机设定目标数字

srand函数大显神功

限制次数并保存输入记录

尾声

前言

施律.C语言小游戏系列预计共有10个,较适合于已经学习完C语言入门内容,并想要掌握实际编程能力的程序猿。

猜数游戏在大家初学的课本上应该都有,难度系数不大,属于一遍过的那种程序。但再小的苍蝇也有肉啊!其实猜数游戏也包含了许多实用性的技巧。长话短说,接下来听施律.为渴望提升的你讲解C语言小游戏(一)----猜数游戏。

猜数判定

先来个测试版的“猜数游戏”。通过if else语句、scanf函数键入数值和“目标数字”进行比较,并显示出比较的后果。

#include <stdio.h>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");elseprintf("Yes!You are right!\n");\\ \n是一种转义字符,表示换行return 0;}

本游戏设立的数是5。如果输入的数小于5,则输出Too small!;如果输入的数大于5,则输出Too big!。

if else 语句

本程序中的if语句采用以下形式。

其中的else if可以是很多个,这取决于程序猿想要设计的条件个数。

接下来我们讨论讨论多分支的方法,即用上述语句更另外2种if else 形态语句进行对比,得出优劣。话不多说,上代码!

if(no > ans)printf("Too big!\n");else if(no < ans)printf("Too small!\n");elseprintf("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<ans,【3】判断no==ans。

由上可以得出,程序1的效率是最高的

重复到猜对为止(do语句,while语句)

上个程序只允许玩家输入一次数值操作起来是十分无趣的。所以我们将程序改良一下,让玩家可以一直重复输入直到猜对为止。那我们该如何实现输入多次呢?我们学到的循环该派上用场了。利用do语句循环实现多次输入,代码如下:

#include <stdio.h>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");elseprintf("Yes!You are right!\n");} while (no != ans);return 0;}

do语句是先循环后判断的,跟它的好兄弟while语句和for语句不同(后面会讲到)。在运用到do语句的过程中要时刻记得它的末尾是有分号“ ; ”的。如上所示,do 语句的控制表达式是no!=ans,运算符!=对左边和右边的操作数的值是否不相等这一条件进行判断。如果这个条件成立,程序就会生成int型的1表示继续,不成立则生成int型的0表示循环结束。

接下来我们看看用while语句实现猜数游戏:

#include <stdio.h>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");elsebreak;}printf("Yes!You are right!\n");return 0;}

while语句是先判断后循环,跟前面的do语句的循环方式是不一样的。如上,while的控制表达式是1,所以循环会永远进行下去。这样的循环岂不是“无限循环”?那这样的循环该如何破解呢?break语句大显神功,直接强制跳出了循环语句。

随机设定目标数字

在前面的游戏中,自己设定的数自己猜显得太枯燥无趣了,要是能随机生成数字来猜则会增加很多的趣味性。仔细想想,我们好像能用rand函数来生成随机数。rand的功能是计算0-RAND_MAX(很多初学的小伙伴不知道RAND_MAX,这其实是头文件<stdlib.h>包含的一个宏,规定它的值不能小于编译环境所规定的最小数,最小为32767)的伪随机整数序列。何为“伪”?且听我一一分析。先上代码:

#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)是:");scanf("%d", &retry);} while (retry == 1);return 0;}

聪明的小伙伴可以自行ctrl+c到编译器上看看,多执行几次程序会发现生成的随机序列是一模一样的!rand函数看似生成随机实则不随机,是有一定规律可循的。为什么呢?这是因为rand函数的默认种子(rand函数是对一个叫作“种子”的基准值加以运算来生成随机数的)是1。如果我们想要生成不同的随机序列,就必须更换种子的值。

srand函数大显神功

srand函数就能解决上面所描述的窘境。它的功能是给后续调用的rand函数设置一个种子,用于生成新的伪随机数序列。如果用同一个种子的值调用本函数,就会生成相同的伪随机数序列。如果在调用本函数之前调用了rand函数,就相当于程序在一开始调用了本函数,把种子设定成了1,最后会生成一个种子值为1的序列。此外,其他库函数在运行时会无视本函数的调用。

该怎么表示呢?打个比方srand(50)和srand(40),它们生成的随机序列是不同的,且看下表:

接下来我们要想把种子从常量变成随机值,可引用头文件<time.h>的time(),通过把运行程序时的时间当作种子来实现。上代码:

#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)是:");scanf("%d", &retry);} while (retry == 1);return 0;}

RAND_MAX在上文中提到它所生成的数可能是非常大的,几万几十万都有可能。那么我们该怎么控制srand生成的随机值呢?我们可以运用求余运算来实现。普及一下求余的概念。请看下面:

、我们再对上述代码进行修改:

#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)是:");scanf("%d", &retry);} while (retry == 1);return 0;}

这样游戏玩起来就不会枯燥乏味了!但好像缺少了点紧张刺激,我们应该再对该程序进行升级----限制次数并保存输入记录

限制次数并保存输入记录

如果游戏能够限制玩家的输入次数和保存玩家输入的值,玩家的游戏体验一定会有大幅度的升级!想到保存输入的值,我们肯定能联想到用数组保存。通过数组遍历,将玩家输入的值一一存入,并在游戏结束后呈现给玩家,让玩家知道自己猜的数字距离目标数字有多近。先上代码:

#include <stdio.h>#include <stdlib.h>#include <time.h>#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是将数字向右靠齐。

尾声

以上就是施律.对本系列第一个游戏----猜字游戏的理解与分析,感谢能观看到这里的你!如果觉得本篇博客对正在学习编程的你有帮助的话,请给施律.多一点的支持与关注!接下来的10多天时间里施律.将和大家畅玩其他用编程实现的游戏,希望下次的我能为大家奉上更好的游戏,也希望下次的博客有你!

如果觉得《C语言小游戏(一)----猜数游戏》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。