前言:
前面已经讲过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就是无符号整数。
想要详细了解时间戳以及存在的某种隐患就太过复杂,暂时不用深入了解,只需要会用就可以啦~
srand(time(NULL));
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,那就说明循环执行完了也没有猜对:
if (i == times)
{
printf("连续猜错%d次,游戏失败!\n", times);
printf("正确答案为:%d\n\n", n);
}
游戏函数的大体代码就完成了。
六、清屏代码和停顿代码(美化界面)
我们完成了一次游戏开始下一次没有清除之前的代码,会让界面看起来多些很没有必要的东西。
为了让界面看起来更美观,我们可以使用下面的代码
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;
}