整体思路:
实际上可以理解为框架及main函数的结构,细节实际上为main函数内部实现功能的代码进行模块化,以便在主函数中更直观的看到思路结构以及方便调试代码。
编写框架
1、使用while循环语句和if实现选择。
我们考虑选择用输入“Y/N”的方式来实现,“Y/N”为字符类型。
问题1:
在编写过程中会发现,第一次选择可以实现,之后的选择则不论输入Y或N还是其他任意,都呈现"输入错误请重新输入”的效果。查资料发现,用scanf函数输入时输入的实际上为“Y”和“\n”两个字符,第一次判断时,代码在缓冲区提取“Y”,之后判断则提取到的是之前存在缓冲区的“\n”。
解决1:
所以我们在输入函数后加入getchar()函数将回车的字符给拿走,以免影响下一次的结果。
代码:
int main()
{
while (1)
{
char name = '0';//定义(Y/N)
printf("是否进入游戏(Y/N):");
scanf("%c", &name);
getchar();//把scanf输入的回车给拿走 //拿走以免影响下一次输入结果
if (name == 'Y')
{
game();//游戏
}
else if(name == 'N')
{
printf("退出游戏\n");
break;
}
else
{
printf("输入错误请重新输入\n");
}
}
return 0;
}
2、使用do...while
思路:
由于是先执行选择是否进行游戏的代码来实现不退出可以一直玩的效果,考虑使用do...while循环来实现。选择部分我们选择用switch语句。原因:switch语句用常量来进行操作
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
//框架 实现不退出可以一直游戏的效果
do
{
printf("*****1.开始游戏*****\n");//菜单栏
printf("*****0.退出游戏*****\n");
scanf("%d", &input);
//选择
switch (input)
{
case 1:
//printf("开始游戏...\n");
game();
break;
case 0:
printf("退出游戏...\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
子函数game()
思路:
查询到C语言中随机数生成函数为rand(),又了解到使用rand函数需要用srand(),生成种子(seed),而srand中参数需要由一个变化的值来充当。联想到可以使用时间戳,可以调用时间戳的函数为time()。依据这三个函数的定义、结构等可以写出代码为:
srand((unsigned int)time(NULL));
int ret = rand() % 100 + 1;
printf("%d", ret);//显示随机数
rand()函数只能够生成[0,RAND_MAX]范围内的整数,RAND_MAX是stdlib.h头文件中的一个常数(32767),在不同的系统之下这个常数是不一样的。
问题2:
在测试代码时(game函数中只有生成随机数时)如果循环速度过快,两次产生的随机值有可能一样。
解决2:
生成随机数本质上是依靠时间的变化来实现的,时间戳以秒为单位变化,所以要想解决此问题,将srand((unsigned int)time(NULL));放入主函数中。
全部代码:
(框架用while、if语句实现的)
//猜数字游戏
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
void game()
{
//1、生成随机数
int ret = rand() % 100 + 1;
printf("%d", ret);//显示随机数
//2、猜词
int num = 0;
while (1)
{
printf("请输入数字:");
scanf("%d", &num);
getchar();//把scanf输入的回车给拿走
if (num > ret)
{
printf("猜大了\n");
}
else if (num < ret)
{
printf("猜小了\n");
}
else
{
printf("恭喜你,猜对了!\n");
break;
}
}
}
int main()
{
while (1)
{
char name = '0';//定义(Y/N)
srand((unsigned int)time(NULL));
printf("是否进入游戏(Y/N):");
scanf("%c", &name);
getchar();//把scanf输入的回车给拿走 //拿走以免影响下一次输入结果
if (name == 'Y')
{
game();//游戏
}
else if(name == 'N')
{
printf("退出游戏\n");
break;
}
else
{
printf("输入错误请重新输入\n");
}
}
return 0;
}
代码模拟第五人格六十发必出金光
这一part单纯属于打完代码后突发奇想想自己尝试一下,结合游戏生活。
思路:
整体框架还是,只要不选择退出,就一直在可以开始抽卡的界面。game()子函数部分,随便指定一个1-60内的数为金光(eg:56),当生成的随机数为56时视为抽到金光。当抽到第60次之前没有抽到金光,则触发保底效果,第60次一定为金光。
查阅:
输出给定范围之内的随机数:需要使用rand() % (b - a + 1)+ a,显然,rand()% (b - a + 1)的范围是[0,b - a],再加上a之后的范围就是[a,b]。
代码:
#include <stdlib.h>
#include <time.h>
void game()
{
int i = 0;//抽卡次数
for (i = 1; i < 61; i++)
{
//模拟一个抽卡按钮
int button = 0;
scanf("%d", &button);//输入任意整形数字模拟一次次抽卡
//1.生成随机数ret(1-60)
int ret = rand() % 61;
//printf("%d", ret);//显示生成的随机数
//2.判断是否是金光
if (ret == 56) //定义当随机数为56时为金光
{
printf("恭喜你获得金光!!!!!!!!!!!\n");
break;
}
else if(i == 60)//60发必出
{
printf("恭喜你获得金光!!!\n");
break;
}
else
{
printf("很遗憾,下次必出!\n");
}
}
}
int main()
{
int conf = 0;//确认
srand((unsigned int)time(NULL));//生成随机数的种子
do
{
printf("*****1.抽卡*****\n");
printf("*****0.退出*****\n");
scanf("%d", &conf);
//选择
switch (conf)
{
case 1:
printf("开始抽卡...\n");
game();
break;
case 0:
printf("退出游戏...\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (conf);
}
参考资料:
https://blog.csdn.net/qq_39445165/article/details/94891900
https://www.bilibili.com/video/BV1cq4y1U7sg/?spm_id_from=333.999.0.0