✅作者简介:大家好我是原始豌豆,感谢支持
系列专栏:C语言项目实战
️作者主页:原始豌豆的博客
创作不易:本文共两万八千字,文章最后附上全部源码和音频包,欢迎大家点赞,关注,评论
猜数字游戏是大多数人学习C语言时都会了解到的一个有趣的C语言小游戏,本文对猜数字游戏进行了升级与优化,增加了很多新功能,比如进入游戏的黄色皮卡丘动态效果展示,动态的打印欢迎进入Guess_Number文字,加入了游戏背景音乐,增加了游戏说明书,主界面的菜单显示,难度的分级,和游戏失败的皮卡丘关机惩罚,玩小游戏的同时,也能对C语言和程序设计有更好的认识。
一.游戏描述
二.头部文件
三.代码实现:
(1) 菜单函数
(2) 皮卡丘函数
(3) 动态字符串函数
(4) 心形图案函数
(5) 背景音乐函数
(6) 游戏难度等级函数
(7) 游戏主体函数
(8) 打印提示框函数
(9) 关机函数
(10) bug处理函数
(11) 游戏玩法说明函数
(12) 开发人员菜单函数
主函数
四.全部源码
五.项目总结
游戏分为普通模式,困难模式和地狱模式。
普通模式:程序生成一个1~100之间的的随机数,并给予玩家10次机会,让玩家去猜,并给予玩家一定的提示。
1.玩家输入猜测的数字,程序告诉玩家猜大了或者猜小了,然后继续猜。如果猜对了,则游戏结束,回到主菜单界面。
2.如果10次机会用尽,玩家依旧没有猜出来,则进入惩罚模式,电脑召唤红色的皮卡丘,对玩家电脑发动十万伏特攻击,将玩家的电脑倒计时两分钟关机,玩家可通过输入对应的口令解除关机。如果玩家头铁强行关闭程序,关机指令并不会关闭,倒计时结束依旧会关机。
困难模式:困难模式在普通模式的基础上增大了随机数的生成范围(1~1000),并增加了二级关机指令,玩家输入对应的口令解除第一层关机后还会有第二层关机程序,解开题目方可彻底解除关机。
地狱模式:地狱模式在普通模式的基础上增大了随机数的生成范围(1~10000),并增加了伪关机指令,玩家输入对应的口令解除关机后,直接进入倒计时5s,倒计时结束强制关机,玩家开机后打印心型图案,降低玩家怒气。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#pragma comment(lib,“Winmm.lib”)
游戏使用的所有头文件如下,第一条头文件vs编译器专用,其他编译器删除此条。
#define _CRT_SECURE_NO_WARNINGS//vs编译器加上此条头文件,其他编译器不用。
#include
#include
#include
#include
#include
#pragma comment(lib,"Winmm.lib")
(1) 菜单函数 void Menu()
首先呢,我们既然做游戏,得有一个菜单,供玩家选择开始游戏或退出游戏等功能。我们先做一个Menu菜单函数并写上每个功能,使用时在主函数里调用就可以展示给玩家了。
菜单函数也可以设计的很精美,可以参考我的设计样式,system(“color 70”);是一个Windows Api,我们可以通过调用它实现菜单和颜色和字体的的设置。
void Menu()
{
system("color 70");//灰底黑字
printf("\t\t\t\t猜数字游戏\n");
printf("\t\t\t _______________________\n");
printf("\t\t\t| 1.开始游戏 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t| 2.困难模式 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t| 3.地狱模式 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t| 4.玩法说明 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t| 5.退出游戏 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t| 6.开发人员 |\n");
printf("\t\t\t|_______________________|\n");
printf("\t\t\t请选择:->");
}
(2) 皮卡丘函数 void PiKaQiu(char color_control)
我们的游戏叫皮卡丘猜数字,那怎么能没有皮卡丘呢,我们做一个皮卡丘函数PiKaQiu用来展示进入游戏时的皮卡丘动画展示,我们的游戏设计是黄色皮卡丘出现在游戏开场动画里,红色皮卡丘出现在游戏失败进入关机惩罚的动画里,但我们总不能做两个皮卡丘函数吧,那样代码太臃肿了,所以这里我们给皮卡丘函数带上参数,char color_control 用于接受传过来的参数,如果传过来的是’y’,代表黄色yellow,如果传过来的是’r’,代表红色red,皮卡丘图案是printf函数一行一行打印出来的,我们在每行打印结束的后面加上Sleep(100);这是一个Windows Api 可以实现延迟效果,设置延迟为100ms,每行最后都加一个Sleep(100);这样就可以实现动态效果了。
皮卡丘函数中的PlaySound(TEXT(“pikaqiu.wav”), NULL, SND_FILENAME | SND_ASYNC);Sleep(3000);这行代码是用来控制音效的,红色皮卡丘释放十万伏特会发出声音的哦,这在后面会详细介绍。
//皮卡丘函数,打印开始界面的皮卡丘图案
void PiKaQiu(char color_control) {
if (color_control == 'y')//yellow ,控制皮卡丘颜色
{
system("color 0E");//黑底黄字
printf("\n 黄色皮卡丘:我可不是摆设哦!!!!\n\n");
}
if (color_control == 'r')//red,控制皮卡丘颜色
{
system("color 04");//黑底红字
PlaySound(TEXT("pikaqiu.wav"), NULL, SND_FILENAME | SND_ASYNC);
Sleep(3000);
printf("\n 红色皮卡丘:我都说了我不是摆设哦!!!!\n\n");
}
printf(" へ /|\n"); Sleep(100);
printf(" /\ ∠_/\n"); Sleep(100);
printf(" / │ / /\n"); Sleep(100);
printf(" │ L _,< / /`ヽ\n"); Sleep(100);
printf(" │ ヽ / 〉\n"); Sleep(100);
printf(" Y ` / / /\n"); Sleep(100);
printf(" ( ● 、 ● |〈 \n"); Sleep(100);
printf(" () へ | \〈\n"); Sleep(100);
printf(" >- 、_ ィ │ //\n"); Sleep(100);
printf(" / へ / )<| \\\n"); Sleep(100);
printf(" ヽ_) (_/ │//\n"); Sleep(100);
printf(" 7 |/\n"); Sleep(100);
printf(" >―r ̄ ̄`-―_\n\n"); Sleep(100);
}
(3) 动态字符串函数 void Welcome()
我们的游戏设计是黄色皮卡丘出现在游戏开场动画里,然后出现动态文字,打印欢迎进入 Welcome To Guess_NumberGuess_Number(欢迎来到猜数字游戏),然后才进入游戏菜单,打印数字大家都会,那么如何显示动态文字,这里我们做一个欢迎函数Welcome用来动态展示字符。
函数体内部创建一个字符数组用于存放我们要打印的字符串,利用strlen(arr1) - 1求出数组的右下标,然后创建一个循环来遍历数组,打印数组里的每个字符,每打印一个字符设置75ms延迟,Sleep(75);来实现动态效果,打印完字符串后,我们要进入菜单界面了,所以在这里我们设置一个system(“pause”);和system(“cls”);用来实现控制台停留和清屏
//显示欢迎进入猜数字游戏的字符串函数
void Welcome()
{
char arr1[] = " Welcome To Guess_Number!!! ";//设置一些空格,控制和皮卡丘图案对齐。
int left = 0;
int right = strlen(arr1) - 1;//字符数组最右边下标
while (left <= right)//循环遍历字符数组
{
Sleep(75);//设置休眠函数,以实现动态打印效果
printf("%c", arr1[left]);
left++;
}
system("pause");//控制台停留
system("cls");//清屏
}
(4) 心形图案函数 void heart()
游戏里的地狱模式惩罚里会倒计时并强制给玩家关机,没有其他方式阻止,所以我们设计一个心形函数heart(),当玩家愤怒的开机归来,程序就显示红色爱心来降低玩家怒气值。程序里的地狱模式的关机惩罚里采用的是休眠但不终断进程的方式关机,所以重启电脑后还是会显示程序关机前正在运行的界面。心型函数的实现如下,采用了笛卡尔心型曲线为数学基础,通过坐标来判断如何打印心型图案。
//心形图案函数
void heart()
{
printf(" 刚开机回来吧,我一直都在 @_@\n");
system("color 04");//黑底红字
for (float y = 1.5f; y > -1.0f; y -= 0.1f) {
for (float x = -2.0f; x < 2.0f; x += 0.05f) {
float a = x * x + y * y - 1;
putchar(a * a * a - x * x * y * y * y <= 0.0f ? '*' : ' ');
}
Sleep(30);
putchar('\n');
}
}
心形图案函数运行效果如图:
(5) 背景音乐函数 void BackgroundMusic(int num)
我们的游戏是带有背景音乐的,所以这里我们创建一个背景音乐函数 BackgroundMusic,通过调用windows api 来实现音乐的播放和音效的实现,“lihuaxiangA.wav”,引号内部的内容为音频文件的名称(音频文件必须是wav格式的,音频文件放在代码对应的release文件底下程序才能有声音),在这里给 BackgroundMusic函数设置了参数num,通过参数用来控制音乐的打开或关闭。传参数0时音乐停止,音频文件我会放到本文的最后。
//背景音乐函数
void BackgroundMusic(int num)
{
PlaySound(TEXT("lihuaxiangA.wav"), NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);//播放音频文件,循环播放,异步播放
if (num == 0)
{
PlaySound(NULL, NULL, SND_PURGE); // 停止所有声音
}
}
如图:音频文件和.exe文件放在一个目录下,音频文件必须是wav格式的
(6) 游戏难度等级函数 void game_class(int class)
这里的game_class函数和下面的game函数是程序的重点部分,game_class函数的参数class用来接收玩家在游戏菜单选择的难度等级,1,2,3分别对应普通模式,困难模式和地狱模式,将不同难度产生的随机数值 random_num ,玩家游戏次数count和关机惩罚等级shutdown_class三个参数传给game函数进行处理。game_class函数和game函数本为一体,但考虑到游戏内容的增多,和函数应该保持高内聚低耦合的性质,所以拆分成了两个函数,方便修改和维护。
//game_class函数对玩家选择的模式进行处理,并将难度对应的参数传给game函数
void game_class(int class) //class=1,2,3分别对应普通困难地狱三种模式
{
if (class == 1)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 100 + 1;//将随机数模100产生0~99之间的数字。+1随机数变成0~100
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 1;//猜错后关机程序对应的等级
printf("\t\t\t普通模式->电脑已经生成了一个1到100之间的随机数,你猜猜数字是多少 ?\n");
game_class(random_num, count, shutdown_class);
}
if (class == 2)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 1000 + 1;//将随机数模1000产生0~999之间的数字。+1随机数变成0~1000
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 2;//猜错后关机程序对应的等级
printf("\t\t\t困难模式->电脑已经生成了一个1到1000之间的随机数,你猜猜数字是多少 ?\n");
game_class(random_num, count, shutdown_class);
}if (class == 3)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 10000 + 1;//将随机数模100产生0~9999之间的数字。+1随机数变成0~10000
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 3;//猜错后关机程序对应的等级
printf("\t\t\t地狱模式->电脑已经生成了一个1到10000之间的随机数,你猜猜数字是多少 ?\n");
game_class(random_num, count, shutdown_class);
}
}
(7) 游戏主体函数 void game(int random_num, int count, int shutdown)
game函数接收game_class函数传过来的参数并进行处理,对随机数值 random_num 和玩家输入的数字进行比较,以此来缩小玩家判断程序产生的随机数的范围,game函数调用PrintFunction函数并为其传参n,参数n的四个数值对应PrintFunction函数里的四种情况的打印形式,程序以此来判断应该打印哪种形式的提示框
//game函数对应的三个参数分别为game_class函数传过来的随机数,猜测次数,和关机指令等级
void game(int random_num, int count, int shutdown) //对玩家输入的数字进行处理,给出猜大了猜小了猜对了次数耗尽的反馈
{
int guess1 = 0;//存放玩家输入的数字
int n = 0; //n变量控制if语句进入打印函数之后,打印哪种形式的提示框的参数变量
while (1)
{
printf("\t\t\t请输入你猜的数字>:");
scanf("%d", &guess1);
int guess2 = digit(guess1);//把用户输入传入数据处理的函数,只有用户输入纯数字时才能跳出数据处理函数,并返回输入的纯数字
count--;//次数减1放在数据处理函数的后面,避免因用户输入字符导致count--;
if (guess2 > random_num)
{
n = 1;
PrintFunction(count, n);//n==1参数对应打印函数PrintFunction中的第一种打印形式
}
else if (guess2 < random_num)
{
n = 2;
PrintFunction(count, n);//n==2参数对应打印函数PrintFunction中的第二种打印形式
}
else
{
n = 3;
PrintFunction(count, n);// n == 3参数对应打印函数PrintFunction中的第三种打印形式
break;
}
if (count == 0) //count==0时代表玩家猜测次数已经耗尽,进入惩罚状态
{
n = 4;
PrintFunction(count, n);// n == 4参数对应打印函数PrintFunction中的第四种打印形式
PiKaQiu('r'); //调用皮卡丘函数进行十万伏特攻击(皮卡丘函数传参为'r'表示红色皮卡丘);
Shutdown(shutdown); //关机程序
break;
}
}
}
(8) 打印提示框函数 void PrintFunction(int count, int n)
PrintFunction函数的两个参数接收的是game函数传过来的游戏次数count和n,判断以哪种形式进行输出打印。采用如下格式打印,增加了游戏运行的美观性。
//给出猜大了猜小了猜对了的玩家提示框(参数由game函数传递)
void PrintFunction(int count, int n)//打印函数,打印提示信息猜大猜小等情况
{
if (n == 1)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 你猜大了,你还有%d次机会 |\n", count);
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 2)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 你猜小了,你还有%d次机会 |\n", count);
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 3)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 恭喜你,猜对了(*^o^*)\a |\n");
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 4)
{
system("cls");
printf("\t\t\t ______________O-o ?_______________\n");
printf("\t\t\t| 十次你都猜不对?十万伏特!!|\n");
printf("\t\t\t|__________________________________|\n");
Sleep(1000);
}
}
(9) 关机函数 void Shutdown(shutdown_class)
这里是程序的重点部分,关机函数,参数shutdown_class ,分为1,2,3三个等级,对应游戏的普通,困难和地狱三种模式的惩罚情况,参数由game函数传递。三个等级对应的关机处理方式各不相同,普通模式的关机触发后输入对应口令即可解除,困难模式的关机触发后,需要处理两层,通过输入口令进入内层,然后计算数列得出结果来解除关机指令,地狱模式增加了伪关机指令,玩家输入对应的口令解除关机后,直接进入倒计时5s,倒计时结束强制关机,地狱模式的关机惩罚里采用的是休眠但不终断进程的方式关机。
//关机函数,参数shutdown_class ,分为1,2,3三个等级
void Shutdown(shutdown_class)
{
char input[100] = { 0 };//字符数组,用来存储玩家输入的字符串
system("shutdown /s /t 120 /c 你的电脑已经被皮卡丘的十万伏特电坏!即将在120s后关机O-o珍惜你最后的时间吧");
printf("电脑将在两分钟内关机,如果输入:哈哈哈我有避雷针,就取消关机!请输入:>");
while (1)
{
scanf("%s", input);
if (0 == strcmp(input, "哈哈哈我有避雷针"))
{
if (shutdown_class == 1)//一级关机参数情况下,输入正确直接取消关机,二级关机参数情况下,if语句不执行
{
system("shutdown -a");
printf("已经取消关机!!!");
}
if (shutdown_class == 3)//三级关机参数情况下,输入正确也直接关机,二级关机参数情况下,if语句不执行
{
system("shutdown -a");
Sleep(1000);
char ch[] = "\t\t\t你以为这就结束了么?\n\t\t输对了也给你关机,哈哈哈!这就是地狱模式\n";//设置一些空格,控制和皮卡丘图案对齐。
int left = 0;
int right = strlen(ch) - 1;//字符数组最右边下标
while (left <= right) //循环遍历字符数组
{
Sleep(60); //设置休眠函数,以实现动态打印效果
printf("%c", ch[left]);
left++;
}
for (int i = 5; i >= 0; i--)
{
Sleep(1000);
printf("\t\t\t\t倒计时%d\r", i);
}
printf("\t\t ______________O-o ?_______________\n"); Sleep(50);
printf("\t\t| 拜拜了,您内 !! |\n"); Sleep(50);
printf("\t\t|__________________________________|\n\n"); Sleep(50);
Sleep(1500);
// system("shutdown /h");
}
break;
}
else
{
printf("输入错误,请重新输入:");
}
}
if (shutdown_class == 2)//如果1,3 级参数都未执行,来到此处,二级关机参数情况下,上一个while循环执行完后,进入这里
{
printf(" ________________________________________________________________________________________\n");
printf("|真当困难模式是摆设啊?避雷针都给你劈碎它,输入 1+3+5+7+......+97+99 的值,才能取消关机 |\n");
printf("|_______________________________________________________________________________________|\n");
int num = 0;
while (num != 2500)
{
scanf("%d", &num);
while (getchar() != '\n');
switch (num)
{
case 2500:
system("shutdown -a");
printf("已经取消关机!!!算你厉害!");
break;
default:
printf("结果错误,请重新输入!\n");
}
}
}
}
普通模式关机函数运行效果如图: 这里是带音效的,皮卡丘的叫声和电流声,音频文件放在了本文最后。
普通模式关机函数运行效果如图:
(10) bug处理函数 int digit(int input)
本程序的主要可能出现bug的地方在于应该输入数字的位置上,玩家如果输入字符就会产生程序死循环或缓冲区错乱等情况,针对此情况本程序所有使用到scanf函数进行输入的位置都做了清空输入缓冲区字符的处理,while (getchar() != ‘\n’);此语句用于清空缓冲区字符,经过测试发现bug基本已经消除,唯独在count计数玩家剩余猜测次数时,输入字符会导致count变量次数减少,故此单独做了此 digit函数处理这个问题,对用户输入的值进行处理的函数,只有用户输入纯数字时才能跳出函数,并返回输入的纯数字
//对用户输入的值进行处理的函数,只有用户输入纯数字时才能跳出函数,并返回输入的纯数字
int digit(int input)
{
int hey = getchar();
while (hey != 10)
{
while (getchar() != '\n');
printf("\t\t\t只能输入整数!!!,输入字符或字符加数字无效\n\n");
printf("\t\t\t请输入猜的数字>:");
scanf("%d", &input);
hey = getchar();
}
return input;
}
digit函数运行效果如图: 任何非纯整数数字的输入都会被警告并处理
(11) 游戏玩法说明函数 void introduction()
此函数对应主菜单界面的第4个选项玩法说明,讲解了该游戏的基本玩法。
//游戏玩法说明函数
void introduction()
{
printf(" ________________________________________________________________________________________________________________________________________________________\n"); Sleep(100);
printf("|进入游戏时,会显示黄色皮卡丘动画,然后显示欢迎进入猜数字游戏的英文文字,显示完后按任意键继续,进入到游戏主菜单 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|主菜单分为1.开始游戏 2.困难模式 3.地狱模式 4.游戏说明 5.退出游戏 按下对应的数字再按下Enter键即可进入对应模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|普通模式会生成一个1到100之间的随机数,玩家共有十次猜数机会,键盘输入数字再按下Enter键,即可猜数,机会耗尽进入惩罚模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|普通模式的惩罚模式会将玩家电脑倒计时120s关机,倒计时结束之前未输入正确密码,则会强制关机,关闭程序也不会停止后台关机倒计时,还会使玩家失去输入密码的机会|\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式会生成一个1到1000之间的随机数,玩家共有十次猜数机会,键盘输入数字再按下Enter键,即可猜数,机会耗尽进入惩罚模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式的惩罚模式会将玩家电脑倒计时120s关机,倒计时结束之前未输入正确密码,则会强制关机,关闭程序也不会停止后台关机倒计时,还会使玩家失去输入密码的机会|\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式的惩罚模式输入密码后会提示进一步输入二级密码,一级二级密码都输入正确后才会取消关机程序,二级密码是一道数列题的答案 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|地狱模式的的玩法和对应惩罚模式请玩家自行探索 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
}
(12) 开发人员菜单函数 void kaifa()
此函数对应主菜单界面的第6个选项开发人员,介绍了版本号,作者信息(我本人),和制作时间,背景音乐等信息,该函数可以控制程序内的音乐打开或关闭。
void kaifa()
{
int control = 0;
do
{
system("color B0");
printf(" ________________________________________________________\n"); Sleep(30);
printf("| 皮卡丘猜数字V1.1版本 作者 --->原始豌豆 |\n"); Sleep(30);
printf("| |\n"); Sleep(30);
printf("| 制作时间 2024.2.05 音乐 --->梨花香 |\n"); Sleep(30);
printf("|________________________________________________________|\n"); Sleep(30);
printf("**************1.开启音乐 0.关闭音乐********************\n");
printf("************** 2.回到主界面 *********************\n");
scanf("%d", &control);
while (getchar() != '\n');
switch (control)
{
case 0:
game_class(0);
BackgroundMusic(0);
break;
case 1:
BackgroundMusic(1);
break;
case 2:
system("cls");//回到主界面前先清屏
break;
default:
printf(" 选择错误,请重新输入!");
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏,防止玩家多次输入错误造成屏幕占满
break;
}
} while (control != 2);
}
上述函数都写好后,在主函数中调用各个函数,即可完成皮卡丘猜数字游戏的制作,主函数中设置随机数种子生成起点用于对rand函数进行起点设置,然后依次调用PiKaQiu(‘y’);Welcome();BackgroundMusic();完成动画展示和背景音乐开启, do while循环打印菜单并设置switch分支语句,处理玩家不同的选项,在每个switch分支里调用不同的函数以实现游戏的运行。
//主函数
int main()
{
int input = 0;
int ch = 0;
srand((unsigned)time(NULL)); //设置随机数种子生成起点
ConsoleSet();
PiKaQiu('y');//动态显示进入游戏皮卡丘动画
Welcome();//动态显示欢迎进入猜数字游戏的字符串
BackgroundMusic();
do
{
Menu();
scanf("%d", &input);
while (getchar() != '\n');
switch (input)
{
case 1:
game_class(1);
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 2:
game_class(2);
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 3:
game_class(3);
heart();
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 4:
introduction();
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
break;
case 6:
system("cls"); //界面美化---->清屏
kaifa();
//system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
//system("cls");
break;
case 5:
break;
default:
printf(" 选择错误,请重新输入!");
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏,防止玩家多次输入错误造成屏幕占满
break;
}
} while (input != 5);
return 0;
}
全部源代码如下:将音频包添加到文件中,代码复制到编译器中即可运行
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#pragma comment(lib,"Winmm.lib")
//开始菜单
void Menu()
{
system("color 70");//灰底黑字
printf("\t\t\t\t猜数字游戏\n");
printf("\t\t\t _______________________\n"); Sleep(100);
printf("\t\t\t| 1.开始游戏 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t| 2.困难模式 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t| 3.地狱模式 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t| 4.玩法说明 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t| 5.退出游戏 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t| 6.开发人员 |\n"); Sleep(100);
printf("\t\t\t|_______________________|\n"); Sleep(100);
printf("\t\t\t请选择:->");
}
//皮卡丘函数,打印开始界面的皮卡丘图案
void PiKaQiu(char color_control) {
if (color_control == 'y')//yellow ,控制皮卡丘颜色
{
system("color 0E");//黑底黄字
printf("\n 黄色皮卡丘:我可不是摆设哦!!!!\n\n");
}
if (color_control == 'r')//red,控制皮卡丘颜色
{
system("color 04");//黑底红字
PlaySound(TEXT("pikaqiu.wav"), NULL, SND_FILENAME | SND_ASYNC);
Sleep(3000);
printf("\n 红色皮卡丘:我都说了我不是摆设哦!!!!\n\n");
}
printf(" へ /|\n"); Sleep(100);
printf(" /\ ∠_/\n"); Sleep(100);
printf(" / │ / /\n"); Sleep(100);
printf(" │ L _,< / /`ヽ\n"); Sleep(100);
printf(" │ ヽ / 〉\n"); Sleep(100);
printf(" Y ` / / /\n"); Sleep(100);
printf(" ( ● 、 ● |〈 \n"); Sleep(100);
printf(" () へ | \〈\n"); Sleep(100);
printf(" >- 、_ ィ │ //\n"); Sleep(100);
printf(" / へ / )<| \\\n"); Sleep(100);
printf(" ヽ_) (_/ │//\n"); Sleep(100);
printf(" 7 |/\n"); Sleep(100);
printf(" >―r ̄ ̄`-―_\n\n"); Sleep(100);
}
//显示欢迎进入猜数字游戏的字符串函数
void Welcome()
{
char arr1[] = " Welcome To Guess_Number!!! ";//设置一些空格,控制和皮卡丘图案对齐。
int left = 0;
int right = strlen(arr1) - 1;//字符数组最右边下标
while (left <= right)//循环遍历字符数组
{
Sleep(75);//设置休眠函数,以实现动态打印效果
printf("%c", arr1[left]);
left++;
}
system("pause");//控制台停留
system("cls");//清屏
}
//猜对数字打印心形图案
void heart()
{
printf(" 刚开机回来吧,我一直都在 @_@\n");
system("color 04");//黑底红字
for (float y = 1.5f; y > -1.0f; y -= 0.1f) {
for (float x = -2.0f; x < 2.0f; x += 0.05f) {
float a = x * x + y * y - 1;
putchar(a * a * a - x * x * y * y * y <= 0.0f ? '*' : ' ');
}
Sleep(30);
putchar('\n');
}
}
//给出猜大了猜小了猜对了的玩家提示框(参数由game函数传递)
void PrintFunction(int count, int n)//打印函数,打印提示信息猜大猜小等情况
{
if (n == 1)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 你猜大了,你还有%d次机会 |\n", count);
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 2)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 你猜小了,你还有%d次机会 |\n", count);
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 3)
{
printf("\t\t\t __________________________________\n");
printf("\t\t\t| 恭喜你,猜对了(*^o^*)\a |\n");
printf("\t\t\t|__________________________________|\n\n");
}
else if (n == 4)
{
system("cls");
printf("\t\t\t ______________O-o ?_______________\n");
printf("\t\t\t| 十次你都猜不对?十万伏特!!|\n");
printf("\t\t\t|__________________________________|\n");
Sleep(1000);
}
}
//关机函数,参数shutdown_class ,分为1,2,3三个等级
void Shutdown(shutdown_class)
{
char input[100] = { 0 };//字符数组,用来存储玩家输入的字符串
system("shutdown /s /t 120 /c 你的电脑已经被皮卡丘的十万伏特电坏!即将在120s后关机O-o珍惜你最后的时间吧");
printf("电脑将在两分钟内关机,如果输入:哈哈哈我有避雷针,就取消关机!请输入:>");
while (1)
{
scanf("%s", input);
if (0 == strcmp(input, "哈哈哈我有避雷针"))
{
if (shutdown_class == 1)//一级关机参数情况下,输入正确直接取消关机,二级关机参数情况下,if语句不执行
{
system("shutdown -a");
printf("已经取消关机!!!");
}
if (shutdown_class == 3)//三级关机参数情况下,输入正确也直接关机,二级关机参数情况下,if语句不执行
{
system("shutdown -a");
Sleep(1000);
char ch[] = "\t\t\t你以为这就结束了么?\n\t\t输对了也给你关机,哈哈哈!这就是地狱模式\n";//设置一些空格,控制和皮卡丘图案对齐。
int left = 0;
int right = strlen(ch) - 1;//字符数组最右边下标
while (left <= right) //循环遍历字符数组
{
Sleep(60); //设置休眠函数,以实现动态打印效果
printf("%c", ch[left]);
left++;
}
for (int i = 5; i >= 0; i--)
{
Sleep(1000);
printf("\t\t\t\t倒计时%d\r", i);
}
printf("\t\t ______________O-o ?_______________\n"); Sleep(50);
printf("\t\t| 拜拜了,您内 !! |\n"); Sleep(50);
printf("\t\t|__________________________________|\n\n"); Sleep(50);
Sleep(1500);
// system("shutdown /h");
}
break;
}
else
{
printf("输入错误,请重新输入:");
}
}
if (shutdown_class == 2)//如果1,3 级参数都未执行,来到此处,二级关机参数情况下,上一个while循环执行完后,进入这里
{
printf(" ________________________________________________________________________________________\n");
printf("|真当困难模式是摆设啊?避雷针都给你劈碎它,输入 1+3+5+7+......+97+99 的值,才能取消关机 |\n");
printf("|_______________________________________________________________________________________|\n");
int num = 0;
while (num != 2500)
{
scanf("%d", &num);
while (getchar() != '\n');
switch (num)
{
case 2500:
system("shutdown -a");
printf("已经取消关机!!!算你厉害!");
break;
default:
printf("结果错误,请重新输入!\n");
}
}
}
}
//对用户输入的值进行处理的函数,只有用户输入纯数字时才能跳出函数,并返回输入的纯数字
int digit(int input)
{
int hey = getchar();
while (hey != 10)
{
while (getchar() != '\n');
printf("\t\t\t只能输入整数!!!,输入字符或字符加数字无效\n\n");
printf("\t\t\t请输入猜的数字>:");
scanf("%d", &input);
hey = getchar();
}
return input;
}
//game函数对应的三个参数分别为game_class函数传过来的随机数,猜测次数,和关机指令等级
void game(int random_num, int count, int shutdown) //对玩家输入的数字进行处理,给出猜大了猜小了猜对了次数耗尽的反馈
{
int guess1 = 0;//存放玩家输入的数字
int n = 0; //n变量控制if语句进入打印函数之后,打印哪种形式的提示框的参数变量
while (1)
{
printf("\t\t\t请输入你猜的数字>:");
scanf("%d", &guess1);
int guess2 = digit(guess1);//把用户输入传入数据处理的函数,只有用户输入纯数字时才能跳出数据处理函数,并返回输入的纯数字
count--;//次数减1放在数据处理函数的后面,避免因用户输入字符导致count--;
if (guess2 > random_num)
{
n = 1;
PrintFunction(count, n);//n==1参数对应打印函数PrintFunction中的第一种打印形式
}
else if (guess2 < random_num)
{
n = 2;
PrintFunction(count, n);//n==2参数对应打印函数PrintFunction中的第二种打印形式
}
else
{
n = 3;
PrintFunction(count, n);// n == 3参数对应打印函数PrintFunction中的第三种打印形式
break;
}
if (count == 0) //count==0时代表玩家猜测次数已经耗尽,进入惩罚状态
{
n = 4;
PrintFunction(count, n);// n == 4参数对应打印函数PrintFunction中的第四种打印形式
PiKaQiu('r'); //调用皮卡丘函数进行十万伏特攻击(皮卡丘函数传参为'r'表示红色皮卡丘);
Shutdown(shutdown); //关机程序
break;
}
}
}
//game函数对玩家选择的模式进行处理,并将难度对应的参数传给game_class函数
void game_class(int class) //class=1,2,3分别对应普通困难地狱三种模式
{
if (class == 1)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 100 + 1;//将随机数模100产生0~99之间的数字。+1随机数变成0~100
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 1;//猜错后关机程序对应的等级
printf("\t\t\t普通模式->电脑已经生成了一个1到100之间的随机数,你猜猜数字是多少 ?\n");
game(random_num, count, shutdown_class);
}
if (class == 2)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 1000 + 1;//将随机数模1000产生0~999之间的数字。+1随机数变成0~1000
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 2;//猜错后关机程序对应的等级
printf("\t\t\t困难模式->电脑已经生成了一个1到1000之间的随机数,你猜猜数字是多少 ?\n");
game(random_num, count, shutdown_class);
}if (class == 3)
{
//rand函数能返回随机数的最大值。
int random_num = rand() % 10000 + 1;//将随机数模100产生0~9999之间的数字。+1随机数变成0~10000
int count = 10;//玩家猜测数字的总次数
int shutdown_class = 3;//猜错后关机程序对应的等级
printf("\t\t\t地狱模式->电脑已经生成了一个1到10000之间的随机数,你猜猜数字是多少 ?\n");
game(random_num, count, shutdown_class);
}
}
//游戏玩法说明函数
void introduction()
{
printf(" ________________________________________________________________________________________________________________________________________________________\n"); Sleep(100);
printf("|进入游戏时,会显示黄色皮卡丘动画,然后显示欢迎进入猜数字游戏的英文文字,显示完后按任意键继续,进入到游戏主菜单 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|主菜单分为1.开始游戏 2.困难模式 3.地狱模式 4.游戏说明 5.退出游戏 按下对应的数字再按下Enter键即可进入对应模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|普通模式会生成一个1到100之间的随机数,玩家共有十次猜数机会,键盘输入数字再按下Enter键,即可猜数,机会耗尽进入惩罚模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|普通模式的惩罚模式会将玩家电脑倒计时120s关机,倒计时结束之前未输入正确密码,则会强制关机,关闭程序也不会停止后台关机倒计时,还会使玩家失去输入密码的机会|\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式会生成一个1到1000之间的随机数,玩家共有十次猜数机会,键盘输入数字再按下Enter键,即可猜数,机会耗尽进入惩罚模式 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式的惩罚模式会将玩家电脑倒计时120s关机,倒计时结束之前未输入正确密码,则会强制关机,关闭程序也不会停止后台关机倒计时,还会使玩家失去输入密码的机会|\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|困难模式的惩罚模式输入密码后会提示进一步输入二级密码,一级二级密码都输入正确后才会取消关机程序,二级密码是一道数列题的答案 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
printf("|地狱模式的的玩法和对应惩罚模式请玩家自行探索 |\n"); Sleep(100);
printf("|________________________________________________________________________________________________________________________________________________________|\n"); Sleep(100);
}
//背景音乐函数
void BackgroundMusic(num)
{
PlaySound(TEXT("lihuaxiangA.wav"), NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);//播放音频文件,循环播放,异步播放
if (num == 0)
{
PlaySound(NULL, NULL, SND_PURGE); // 停止所有声音
}
}
void kaifa()
{
int control = 0;
do
{
system("color B0");
printf(" ________________________________________________________\n"); Sleep(30);
printf("| 皮卡丘猜数字V1.1版本 作者 --->原始豌豆 |\n"); Sleep(30);
printf("| |\n"); Sleep(30);
printf("| 制作时间 2024.2.05 音乐 --->梨花香 |\n"); Sleep(30);
printf("|________________________________________________________|\n"); Sleep(30);
printf("**************1.开启音乐 0.关闭音乐********************\n");
printf("************** 2.回到主界面 *********************\n");
scanf("%d", &control);
while (getchar() != '\n');
switch (control)
{
case 0:
game_class(0);
BackgroundMusic(0);
break;
case 1:
BackgroundMusic(1);
break;
case 2:
system("cls");//回到主界面前先清屏
break;
default:
printf(" 选择错误,请重新输入!");
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏,防止玩家多次输入错误造成屏幕占满
break;
}
} while (control != 2);
}
//主函数
int main()
{
int input = 0;
int ch = 0;
srand((unsigned)time(NULL)); //设置随机数种子生成起点
ConsoleSet();
PiKaQiu('y');//动态显示进入游戏皮卡丘动画
Welcome();//动态显示欢迎进入猜数字游戏的字符串
BackgroundMusic();
do
{
Menu();
scanf("%d", &input);
while (getchar() != '\n');
switch (input)
{
case 1:
game_class(1);
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 2:
game_class(2);
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 3:
game_class(3);
heart();
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
BackgroundMusic(1);
break;
case 4:
introduction();
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏
break;
case 6:
system("cls"); //界面美化---->清屏
kaifa();
//system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
//system("cls");
break;
case 5:
break;
default:
printf(" 选择错误,请重新输入!");
system("pause");//界面美化---->控制台停留,实现按任意键继续的效果
system("cls"); //界面美化---->清屏,防止玩家多次输入错误造成屏幕占满
break;
}
} while (input != 5);
return 0;
}
通过实现"猜数字"游戏,我们可以学习到很多C语言编程的基础知识,包括:
如何生成和使用随机数。
如何使用循环和条件判断来控制程序的流程。
如何与用户进行交互,接收用户输入并给出反馈。
如何进行简单的错误处理,提高程序的健壮性。
此外,这个项目我加入了大量界面美化的代码,使程序看起来更加美观,使用效果更好,考虑了很多代码复用性的问题,更加精简了代码,在测试方面解决了诸多可能遇到的bug。这个程序可以帮助我们锻炼逻辑思维和解决问题的能力,提升编程技巧。通过不断地调试和优化代码,我们还可以更加深入地理解C语言的特性和编程的精髓