前言:
前面已经讲过c语言的基本结构,我们今天将基于分支与循环设计并完成一个猜数字的小游戏。
一、游戏要求:
游戏要求:
1. 电脑⾃动⽣成一个0~你选择的大小(n)的随机数
2. 玩家猜数字,猜数字的过程中,根据猜测数据的⼤⼩给出⼤了或⼩了的反馈。
3. 玩家一共有log2(n)次机会,在log2(n)次内,猜对就游戏通关,猜错就游戏失败。
4. 游戏失败可以选择执行惩罚措施(60s后电脑关机),若输入我是猪,则取消关机。
二、随机数的生成
猜数字首先需要有一个数字,这个数字由系统进行随机生成。
2.1 rand()函数
1.头文件<stdlib.h>
2.C 库函数rand(void) 返回一个范围在 0 到 RAND_MAX 之间的“随机数”。RAND_MAX 是一个常量,它的默认值在不同的实现中会有所不同,但是值至少是 32767。
3.int rand (void);,void表示()内不需要填值,返回值是int类型,也就是生成那个“随机数”
代码如下
#include <stdio.h> #include <stdlib.h> int main() { int m = 0; scanf("%d", &m); int n = rand()%m;//生成随机数0~m return 0; }
但是rand()函数生成的“随机数”是一种伪随机数,是根据一个数值按照某个公式推算出来的,每次生成的结果是一样的,该怎么办呢?
2.3 srand()函数
1.头文件<stdlib.h>
2.C 库函数srand() 播种由函数 rand 使用的随机数发生器。
3. void srand(unsigned int seed),不返回值。
srand()函数能控制rand()函数生成的值, 我们知道了rand()并不是真正的随机数,但是srand()如果参数部分仍是一个确定的值,rand()生成的数仍是伪随机数,这又要怎么处理呢?
我们自然而然想到,我们能不能通过控制srand(),来间接控制rand()呢,开始套娃了呢。
2.3 time()函数
在srand()函数里面我们需要一个随时改变的值,那有什么是时刻都在变的呢?
那就是现在的时间,在c语言里面被称为时间戳!
1.头文件<time.h>
2.C 库函数 time(time_t *seconds) 返回自纪元 Epoch(1970-01-01 00:00:00 UTC)起经过的时间,以秒为单位。如果 seconds 不为空,则返回值也存储在变量 seconds 中。
3.time_t time(time_t *seconds),time_t就是无符号整数。
想要详细了解时间戳以及存在的某种隐患就太过复杂,暂时不用深入了解,只需要会用就可以啦~
1. srand(time(NULL)); 2. int n = rand()%m;//生成随机数0~m
三、设计思路
- 在开始时自动出现一个简易的菜单,提醒我们做选择。
- 玩家选择时,1为开始游戏,0为退出游戏。
- 选择了其他的让玩家重新选择。
- 至少执行一次让玩家选择是否开始,所以用do while循环。
- 设计一个game()函数为执行游戏。
- 当一次游戏结束后再让玩家选择是否继续
代码实现如下:
int main() { int chiose = 0; start(); do { printf("请选择:>"); scanf("%d", &chiose); printf("\n"); switch (chiose) { case 1:game(); printf("是否要继续游玩?(1.是 0.否)\n"); break; case 0: printf("退出游戏\n"); break; default:printf("输入错误\n"); } } while (chiose); return 0; }
四、菜单
菜单只需要简单的打印出来就行,写一个菜单函数start(),无需返回值。
代码实现如下:
void start() { printf("**************************************************\n"); printf("************* 1.play 0.exit *************\n"); printf("**************************************************\n"); }
五、游戏函数的实现
我们要实现这个游戏函数需要先创建一个随机数:
void game() { int m; srand(time(NULL)); printf(" 猜数字游戏\n\n"); printf("选择范围(0~?):"); scanf("%d", &m); printf("\n"); int times=log2(m); int n = rand()%m;//生成随机数0~m }
我们给的猜测次数设为以2为底m的对数,log函数的头文件是math.h,既然需要猜,那一次没猜中就要继续猜,知道猜测次数用完,猜对了就跳出循环,没猜对给出提示。
void game() { int guess, i, m; srand(time(NULL)); printf(" 猜数字游戏\n\n"); printf("选择范围(0~?):"); scanf("%d", &m); printf("\n"); int times=log2(m); int n = rand()%m;//生成随机数0~m int a = times; for (i = 0;i < times;i++) { printf("猜一个数字:\n"); scanf("%d",&guess); if (guess > n) { printf("猜大了\n"); a--; printf("剩余%d次机会\n\n",a); } else if (guess < n) { printf("猜小了\n"); a--; printf("剩余%d次机会\n\n",a); }else { printf("猜对了\n\n"); break; } } }
出循环之后如果i==times,那就说明循环执行完了也没有猜对:
1. if (i == times) 2. { 3. printf("连续猜错%d次,游戏失败!\n", times); 4. printf("正确答案为:%d\n\n", n); 5. }
游戏函数的大体代码就完成了。
六、清屏代码和停顿代码(美化界面)
我们完成了一次游戏开始下一次没有清除之前的代码,会让界面看起来多些很没有必要的东西。
为了让界面看起来更美观,我们可以使用下面的代码
system("cls");
这个函数用于执行外部命令,这句代码用于对控制台面板进行清屏,在合适的地方加上能让游戏运行时界面更加美观,它的头文件是stdlib
有的时候我们需要程序暂停一段时间,让我们的视觉有一定的反应时间,达到美化显示页面的效果。
sleep(500);
单位是毫秒。
七、完整代码
我的代码没有加入惩罚,你可以自行加入,例如关机代码。
也可以自行加入一些打印出中文提示语句,以及计分功能,倒数次数等功能,可以自由发挥。
#include<stdio.h> #include <stdlib.h> #include <time.h> #include<windows.h> #include<math.h> int point = 0; int j = 0; void start() { printf("**************************************************\n"); printf("************* 1.play 0.exit *************\n"); printf("**************************************************\n"); } void game() { system("cls"); int guess, i, m; srand(time(NULL)); printf(" 猜数字游戏\n\n"); printf("选择范围(0~?):"); scanf("%d", &m); printf("\n"); int times=log2(m); int n = rand()%m;//生成随机数0~m int a = times; j++; for (i = 0;i < times;i++) { printf("猜一个数字:\n"); scanf("%d",&guess); if (guess > n) { printf("猜大了\n"); a--; printf("剩余%d次机会\n\n",a); Sleep(500); } else if (guess < n) { printf("猜小了\n"); a--; printf("剩余%d次机会\n\n",a); Sleep(500); }else { printf("猜对了\n\n"); point++; break; } } if (i == times) { printf("连续猜错%d次,游戏失败!\n", times); printf("正确答案为:%d\n\n", n); Sleep(1000);//停顿 } } int main() { int chiose = 0; start(); do { printf("请选择:>"); scanf("%d", &chiose); printf("\n"); switch (chiose) { case 1:game(); printf("是否要继续游玩?(1.是 0.否)\n"); break; case 0:system("cls"); printf("退出游戏\n"); printf("你总共参加了%d局游戏,获得的分数为%d\n", j, point); break; default:;printf("输入错误\n"); } } while (chiose); return 0; }