1.随机数生成
1.1 rand函数
C语言中提供了一个函数叫rand,这个函数可以生成随机数,函数原型如下:
int rand(void);
rand 函数会返回一个伪随机数,这个随机的范围是在0~RAND_MAX之间,这个RAND_MAX的大小依赖编译器实现的,但是大部分的编译器上是32767.
rand 函数的使用需要包含一个头文件是: stdlib.h
现在使用rand函数,这里调用5次,产生5个随机数:
#include<stdlib.h>
int main()
{
printf("%d", rand());
printf("%d", rand());
printf("%d", rand());
printf("%d", rand());
printf("%d", rand());
return 0;
}
得到:
并且我们发现如果再次运行程序时,得到的五个数字还是没有变化。
当我们深入了解了一下,发现rand 函数生成的随机数是伪随机数,伪随机数不是真的随机数,是通过某种算法生成的随机数。真正的随机数的是无法预测下一个值是多少的。而 rand 函数是对一个叫“种子”,的基准值进行运算生成的随机数。
之所以前面每次运行程序产生的随机数序列是一样的,那是因为rand 函数生成的随机数的默认种子是不变的,如果要生成不同的随机数,就要让种子是变化的。
1.2 srand函数
C语言中又提供了一个函数叫srand,用来初始化随机数的生成器的,srand的函数如下:
void srand(unsigned int seed);
程序中调用rand函数前要先调用srand函数,通过srand函数的参数seed来设置rand函数生成随机数的时候的种子,只要种子在变化,每次变化生成的随机数序列也就变化起来了。
也就是说如果srand函数的种子也是随机的,rand就能生成随机数;在生成随机数的时候有需要生成一个随机数,这就死循环了。
1.3 time函数
在程序中我们一般使用程序运行的时间作为种子,因为时间时刻发生变化。
在C语言中有一个函数叫time,可以使用这个获得时间,time函数如下:
time_t time(time_t *timer);
time 函数会返回当前的日历时间,其实返回的是1970年1月1日0时0分0秒到现在程序运行时间之间的差值,单位是秒。返回类型是time_t,time_t类型本质上就是32位或者64位的整型类型。
time函数的参数timer如果是非NULL的指针的话,函数也会将这个返回的差值放在timer指向的内存中带回去。
如果timer是NULL,就只会返回这个时间的差值。time函数返回的这个时间差也被叫做:时间戳。
time函数使用时需要包含头文件:time.h
如果只是让time函数返回时间戳,我们可以这样写:
time(NULL);
那么我们生成随机数的代码可以写成:
#include<stdlib.h>
#include<time.h>
int main()
{
srand((unsigned int)time(NULL));
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
printf("%d\n", rand());
return 0;
}
因为srand函数的参数是unsigned int类型需要将时间戳强制转换成该数据类型,并且srand函数不需要频繁调用,一次运行调用一次即可。
1.4 设置随机数的范围
如果我们需要生成0~99之间的随机数,方法如下:
rand()%100;//余数的范围是0~99
要生成1~100之间的随机数,方法如下:
rand()%100+1;
如果要生成100~200之间的随机数,方法如下:
100 + rand()%(100+1);//范围是0~100 + 100得到100~200的随机数
如果要生成a~b的随机数,方法如下:
a + rand()%(b - a + 1);
2.猜数字游戏实现
我们想要实现一个猜字游戏需要三个部分
- 菜单:打印菜单,让玩家知道有什么选项。
- 游戏:一个游戏的主体,游戏程序的编写都在里面。
- 主体:对于游戏的开始或退出与否进行判断。
2.1 菜单
void menu()
{
printf("********************************\n");
printf("********************************\n");
printf("********** 1.开始游戏 ********\n");
printf("********** 0.退出游戏 ********\n");
printf("********************************\n");
printf("********************************\n");
printf("请输入数字->");
}
因为我们这个菜单就只是起到打印的作用,我们不需要他返回什么值,所以函数的返回类型就可以为void,也就是空,不需要返回值。
2.2 游戏
首先猜数字游戏我们肯定需要一个随机数,令其范围为1~100,可以使用上面学到的srand函数以及rand函数进行编写:
srand((unsigned int)time(NULL));
int a = rand() % 100 + 1;//被猜数字范围为1到100
然后进行猜数字的游戏流程,我们需要玩家输入一个数字,使用scanf函数,然后需要判断是否等于被猜数字,如果不同,我们需要打印出范围,然后玩家继续输入。所以我们需要一个循环,当猜中数字时,退出循环。代码如下:
void game()
{
int b = 0;
int max = 100;
int min = 0;
srand((unsigned int)time(NULL));
int a = rand() % 100 + 1;//被猜数字范围为1到100
while (b != a)
{
printf("请猜数字->");
scanf("%d", &b);
if (b > a && b <= max)
{
max = b;
printf("数字的范围是%d到%d\n", min, max);
}
else if (b < a && b >= min)
{
min = b;
printf("数字的范围是%d到%d\n", min, max);
}
else if (b < min || b > max)
{
printf("输入数字错误,请重新输入!数字的范围是%d到%d\n", min, max);
}
}
printf("猜到了数字是%d\n", b);
}
2.3 主体
主体是我们进行判断玩家是否进行游戏,可以使用switch函数,因为玩家输入只有三种情况,输入1时进入游戏,输入0时结束游戏,输入其他时重新输入,然后可以使用goto函数回到菜单处继续判断。代码如下:
int main()
{
int a = 0;
again:
menu();//写一个函数来作为菜单
scanf("%d", &a);
switch (a)
{
case 1:
game();
goto again;
break;
case 0:
break;
default:
printf("输入错误,请重新输入!\n");
goto again;
}
return 0;
}
最后游戏的全部代码如下:
void menu()
{
printf("********************************\n");
printf("********************************\n");
printf("********** 1.开始游戏 ********\n");
printf("********** 0.退出游戏 ********\n");
printf("********************************\n");
printf("********************************\n");
printf("请输入数字->");
}
void game()
{
int b = 0;
int max = 100;
int min = 0;
srand((unsigned int)time(NULL));
int a = rand() % 100 + 1;//被猜数字范围为1到100
while (b != a)
{
printf("请猜数字->");
scanf("%d", &b);
if (b > a && b <= max)
{
max = b;
printf("数字的范围是%d到%d\n", min, max);
}
else if (b < a && b >= min)
{
min = b;
printf("数字的范围是%d到%d\n", min, max);
}
else if (b < min || b > max)
{
printf("输入数字错误,请重新输入!数字的范围是%d到%d\n", min, max);
}
}
printf("猜到了数字是%d\n", b);
}
int main()
{
int a = 0;
again:
menu();//写一个函数来作为菜单
scanf("%d", &a);
switch (a)
{
case 1:
game();
goto again;
break;
case 0:
break;
default:
printf("输入错误,请重新输入!\n");
goto again;
}
return 0;
}
还可以加上猜数字的次数限制,如果5次猜不出来,就算失败,这里我们只需要修改游戏部分就行了。代码如下:
void game()
{
int b = 0;
int max = 100;
int min = 0;
int count = 5;//次数计算器
srand((unsigned int)time(NULL));
int a = rand() % 100 + 1;//被猜数字范围为1到100
while (count)//当count等于0时,循环结束
{
count--;
printf("请猜数字->");
scanf("%d", &b);
if (b > a && b <= max)
{
max = b;
printf("数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
else if (b < a && b >= min)
{
min = b;
printf("数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
else if (b < min || b > max)
{
printf("输入数字错误,请重新输入!数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
if (b == a)
{
printf("猜到了数字是%d\n", b);
break;
}
}
if (count == 0 && b!= a)
//count等于0说明是次数使用完跳出循环的,但是如果是最后一次猜中也会打印,所以需要加上逻辑与运算符,防止最后一次猜中数字也打印失败
{
printf("次数使用完,请重新开始游戏!\n");
}
}
最后加上惩罚,如果5次猜不出来,电脑设置60秒后关机,但是打印我是猪,则取消关机。我们需要用到window头文件中的system函数来使用shutdown -s -t 来执行关机的命令,并且需要string头文件中的strcmp(input,"我是猪"),其中input是一个字符数组,这样才能识别文字,然后判断是不是“我是猪”,如果是input里的内容与我是猪相同,则strcmp函数返回0,然后我们可以使用shutdown -a来停止关机。这里我们仅需要修改游戏部分即可,代码如下:
#include<string.h>
#include<windows.h>
void game()
{
int b = 0;
int max = 100;
int min = 0;
int count = 5;
char input[20] = { 0 };
srand((unsigned int)time(NULL));
int a = rand() % 100 + 1;//被猜数字范围为1到100
while (count)
{
count--;
//printf("%d", a);该代码用来测试,可以直接,看到被猜数字
printf("请猜数字->");
scanf("%d", &b);
if (b > a && b <= max)
{
max = b;
printf("数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
else if (b < a && b >= min)
{
min = b;
printf("数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
else if (b < min || b > max)
{
printf("输入数字错误,请重新输入!数字的范围是%d到%d,还剩下%d次机会\n", min, max, count);
}
if (b == a)
{
printf("猜到了数字是%d\n", b);
break;
}
}
if (count == 0 && b != a)
{
system("shutdown -s -t 60");
again:
printf("打印我是猪,否则60秒后关机!\n");
scanf("%s", &input);
if (0 == strcmp(input, "我是猪"))
{
system("shutdown -a");
}
else
{
goto again;
}
printf("次数使用完,惩罚完毕,请重新开始游戏!\n");
}
}