今天呢介绍的是我的一个新系列,自制小游戏,第一期就选择最简单的猜数字吧,后续还会引入EsayX图形编程制作相对更高级的游戏
游戏逻辑介绍
猜数字这个游戏的设计逻辑非常简单
第一:电脑生成一个随机数作为谜底;
第二:用户输入猜数;
第三:判断结果(猜大猜小),若胜利直接结束游戏
第四:未胜利重复二三,直至胜利或者用户次数耗尽失败
简单介绍了一下猜数字的逻辑,接下来就要设计合理有趣的小游戏了
初始界面
先设计一个登录界面,因为这个登录界面至少要打印一次并且能让用户多次游玩,所以我们要用do...while循环
因为我们不确定用户想要游玩几次,所以我们用死循环,也就是while(1),只要用户输入0后break跳出循环就可以了
接着是让用户选择是否进入游戏,用很简单的if即可
设计好了游戏的初始界面,就该设计游戏的逻辑了,这里我们可以看到我把游戏的设计放在了game函数里,因为这个游戏十分的简单,不需要弄成多个文件的形式
游戏设计
生成随机数
生成随机数需要我们调用一个随机数生成函数 rand,这个函数的功能是用来产生一个0到RANDMAX(32767)的随机数
但是我们直接使用这个rand函数存在一个问题,就是这个随机数的生成是伪随机,这与rand函数的原理有关系,简单来说就是rand函数的随机数生成是有一个种子,如同<<我的世界>>里面的地图种子一样,种子会决定你出生的地形,同一个种子会产生相同的地形,不同的种子产生的地形就不同,而rand函数默认种子值为1,如果我们不自己设置一个种子的话,就会产生下面的情况
我们可以看到两次生成的随机数都是一样的,因为它们的种子一样.所以我们需要自己设置种子,种子是可变的,这样才能保证每次随机数都不同,那么什么适合做种子呢?时间戳.
时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数.也就是说时间戳是不断变化并且没有相同的,我们就可以用这个来做生成随机数的种子
void srand(unsigned int seed)
这是srand函数声明,我们可以看到它的参数是unsigned int类型,但是用time函数获取的时间是time_t类型的,所以我们需要强制转化类型,其次time函数的参数是一个指针,实际上并不需要获取参数,所以我们只用一个空指针就可以了,最后要注意引入srand函数和time函数的头文件 <stdlib.h>和<time.h>
上面这一段介绍的是原理, 我们在使用时只需要srand((unsigned int) time(NULL));即可
我们可以看到成功生成了随机数,但是要注意种子设置一次就可以了,即不要把种子放在循环里面,不然就会出现以下情况
同时我们会发现生成的随机数范围太大了,我们想要生成一个规定范围内的随机数,怎么办呢?很简单,我们只用rand()%n+c就可以得到我们想要的范围,例如我要生成1到100的随机数,就是rand()%100+1
明白了原理之后生成随机数这块就很简单了
用户猜数并判断大小或是胜利
用户需要不断猜数字直至胜利或次数耗尽所以我们很清楚的知道这要设计成循环的方式,这个循环有两种结束方式,一是次数耗尽不再进入猜数环节,二是胜利后跳出循环.根据这两个特征,前者我们设置为循环的进入条件,后者我们放入循环内
我们先把次数设置为6
为了增加游戏的趣味性,我们可以设置惩罚
惩罚措施,关机小程序
这个程序非常的简单,首先我们要用到system函数,这个函数是用来执行系统指令的,我们用这个函数来执行system命令,头文件是
<stdlib.h>
system("shutdown -s -t 60") -s是设置关机,-t是设置时间,60就是我们设置的秒数,如果我们想要秒关机,可以把时间设置为0或shutdown -p(ps:不是很建议设置成立马关机)
我们也得给用户一点补救的措施,shutdown -a解除关机,但是加点小条件,就是用户要输入指定的一段话,那如何判断用户是否输入正确呢,我们需要strcmp函数
int strcmp(const char *str1, const char *str2)
这是strcmp的函数声明,形参也可以输入两个字符串,返回类型是int类型
- 如果返回值小于 0,则表示 str1 小于 str2。
- 如果返回值大于 0,则表示 str1 大于 str2。
- 如果返回值等于 0,则表示 str1 等于 str2。
也就是说相等返回0,不相等返回非0(正数或负数),我们只用判断函数返回值是不是0就可以知道相不相等了 ,头文件是<string.h> 具体比较的原理呢,就是一位一位的去比,如果相同就接着比下一位,如果不同就返回大小,而不是比较字符串的长度
例如"abcdef"和"abe"就是后面大于前面,前两位都相同,比第三位,e的ASCII码值大于c,所以后者大,注意/0的ASCII码值是0
明白了这两个函数后我们就可以完善我们的游戏了
这就是我们的一个惩罚措施了,然后我们的这个小游戏也算写完了,接着是最后一步
生成release版本
我们写的这个是debug版本,用户必须得要有编译器才能运行,所以我们要做一个release版本,可以让朋友点击即玩
这里以vs2022为例,选择release,然后运行一次(这也是为什么我不建议设置立即关机的原因),然后就可以在对应目录下生成一个exe文件
将这个exe文件发送给朋友就可以增进双方的感情了
最后附上源代码
源代码
#include <time.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
void init_menu(void)
{
printf("*********************************\n");
printf("***********1.进入游戏************\n");
printf("***********0.退出游戏************\n");
}
void game()
{
int ret;
ret = rand() % 100 + 1;
printf("请输入一个1到100的整数\n");
int count;
for(count=6;count>0;count--)
{
printf("%d次机会\n",count);
int guess;
scanf("%d", &guess);
if (guess > ret) printf("猜大了\n");
else if (guess < ret) printf("猜小了\n");
else if (guess == ret) { printf("恭喜猜对\n"); break; }
}
if (count == 0)
{
printf("失败啦,你的电脑将在一分钟后关机\n");
system("shutdown -s -t 60");
printf("输入\"我太逊了\"即可取消关机\n");
char arr[20];
while (1)
{
scanf("%s", arr);
if (strcmp(arr, "我太逊了") == 0)
{
system("shutdown -a");
printf("关机已取消\n");
break;
}
}
}
}
int main()
{
srand((unsigned int)time(NULL));
do
{
init_menu();
int choice;
scanf("%d", &choice);
if (choice == 1)
game();
else if (choice == 0)
break;
else
printf("输入错误,请重新输入\n");
} while (1);
return 0;
}