效果预览
下面附代码
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib,"Winmm.lib")
#define Ne 12//定义各种难度下的格子数量及雷的数量
#define Me 15
#define Nm 17
#define Mm 25
#define Nh 22
#define Mh 100
typedef struct nt//定义时间结构体
{
int Year;
int Month;
int Day;
int Hour;
int Minute;
}NowTime;
typedef struct rk//定义成绩结构体
{
char Level;
float Score;
NowTime Time;
}Rank;
void InitializationShow(char (*show)[22],int side);//初始化展示面板
void InitializationMines(char (*mines)[22],int side);//初始化雷区
void PrintingBoard(char (*board)[22],int side);//打印面板
void LindMines(char (*mines)[22],int side,int mount);//随机布雷
void Security(char (*mines)[22],int side,int X,int Y);//确保第一次查看区块安全
void Open(char (*show)[22],char (*mines)[22],int side,int X,int Y);//循环展开周围8个区块
void GameMove(char (*show)[22],char (*mines)[22],int side,int mount);//玩家行动模块
void Game(char (*show)[22],char (*mines)[22],int side,int mount);//游戏主程序
void OpenMenu();//开始菜单
void LastMenu();//结尾菜单
void ChangeLevel();//难度转换
void PrintfHistory();//显示历史记录
void ScanfHistory(float t,int mount);//读取成绩录入历史记录文件
int Statistics(char (*mines)[22],int X,int Y);//统计周围8个区块雷的数量
int Calculate(char (*show)[22],int side);//计算剩余为探索区块数量
char ChooseLevel();//选择难度
NowTime GetTime();//获取当前时间
void main()
{
OpenMenu();
}
NowTime GetTime()
{
time_t timep;
struct tm *p;
NowTime TM;
time (&timep);
p=gmtime(&timep);
TM.Year=1900+p->tm_year;
TM.Month=1+p->tm_mon;
TM.Day=p->tm_mday;
TM.Hour=8+p->tm_hour;
TM.Minute=p->tm_min;
return TM;
}
void OpenMenu()
{
PlaySound(TEXT("BackGroundMusic.wav"),NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);//播放背景音乐
int FLAG;
printf(" 欢迎游玩可选难度扫雷小游戏!\n");
printf("\n");
printf(" 游戏介绍:\n");
printf(" 该扫雷小游戏提供简单、中等、困难三种难度。\n");
printf(" 简单难度场地大小10*10,内含15个雷;\n");
printf(" 中等难度场地大小15*15,内含25个雷;\n");
printf(" 困难难度场地大小20*20,内含100个雷。\n");
printf("\n");
printf(" 下面请选择开始游戏、退出游戏或查看排行榜:\n");
printf(" --------------------------\n");
printf(" |1.准备好了,开始游戏!!|\n");
printf(" |2.太困难了,放弃游戏!!|\n");
printf(" |3. 我想看历史记录 |\n");
printf(" --------------------------\n");
do
{
scanf("%d",&FLAG);
getchar();
switch (FLAG)
{
case 1:
ChangeLevel();
break;
case 2:
exit(0);
case 3:
PrintfHistory();
default:
printf(" 不要逃避,选择吧!!\n");
break;
}
}while(FLAG);
}
void LastMenu()
{
PlaySound(TEXT("BackGroundMusic.wav"),NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
int FLAG;
printf(" --------------------------\n");
printf(" |1. 返回主菜单 |\n");
printf(" |2. 查看历史记录 |\n");
printf(" |3. 退出游戏吧 |\n");
printf(" --------------------------\n");
do
{
scanf("%d",&FLAG);
getchar();
switch (FLAG)
{
case 1:
OpenMenu();
case 2:
PrintfHistory();
case 3:
exit(0);
default:
printf(" 不要乱输,快点选吧!!\n");
break;
}
}while(FLAG);
}
void ChangeLevel()
{
PlaySound(TEXT("GamingMusic.wav"),NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
char ShowBoard[22][22],MinesBoard[22][22];
char LEVEL;
LEVEL=ChooseLevel();
if(LEVEL=='E'||LEVEL=='e')
{
Game(ShowBoard,MinesBoard,Ne,Me);
}
else if(LEVEL=='M'||LEVEL=='m')
{
Game(ShowBoard,MinesBoard,Nm,Mm);
}
else if(LEVEL=='H'||LEVEL=='h')
{
Game(ShowBoard,MinesBoard,Nh,Mh);
}
}
char ChooseLevel()
{
char LEVEL;
printf(" 请选择你想游玩的难度(简单:E(e)/中等:M(m)/困难:H(h)):");
for(;;)
{
scanf("%c",&LEVEL);
getchar();
if(LEVEL=='H'||LEVEL=='M'||LEVEL=='E'||LEVEL=='h'||LEVEL=='m'||LEVEL=='e')
break;
else
{
printf(" 请按照正确的格式输入难度:");
}
}
return LEVEL;
}
void Game(char (*show)[22],char (*mines)[22],int side,int mount)
{
InitializationShow(show,side);
InitializationMines(mines,side);
printf(" 场地面积为%d*%d,场上一共有%d个雷,小心了!!\n",side-2,side-2,mount);
PrintingBoard(show,side);
LindMines(mines,side,mount);
GameMove(show,mines,side,mount);
}
void InitializationShow(char (*show)[22],int side)
{
int i,j;
for(i=1;i<side-1;i++)
{
for(j=1;j<side-1;j++)
show[i][j]='*';
}
for(i=0,j=0;i<side;i++)//用“X”填充周围,便于测试和调试
show[i][j]='X';
for(i=0,j=0;j<side;j++)
show[i][j]='X';
for(i=side-1,j=0;j<side;j++)
show[i][j]='X';
for(i=0,j=side-1;i<side;i++)
show[i][j]='X';
}
void InitializationMines(char (*mines)[22],int side)
{
int i,j;
for(i=1;i<side-1;i++)
{
for(j=1;j<side-1;j++)
mines[i][j]='0';
}
for(i=0,j=0;i<side;i++)//用“X”填充周围,便于测试和调试
mines[i][j]='X';
for(i=0,j=0;j<side;j++)
mines[i][j]='X';
for(i=side-1,j=0;j<side;j++)
mines[i][j]='X';
for(i=0,j=side-1;i<side;i++)
mines[i][j]='X';
}
void PrintingBoard(char (*board)[22],int side)
{
int i=0,j=0,k=0;
printf(" %2d |",0);
for(i=1;i<side-1;i++)
{
printf("%2d |",i);//打印行数
}
printf("\n");
printf(" ");
for(i=0;i<side;i++)
printf("----");
printf("\n");
for(i=1;i<side-1;i++)
{
printf(" %2d |",i);//打印列数
for(j=1;j<side-1;j++)
{
printf(" %c |",board[i][j]);
}
printf("%2d |",i);
printf("\n");
printf(" ");
for(k=0;k<side;k++)
printf("----");
printf("\n");
}
}
void LindMines(char (*mines)[22],int side,int mount)
{
int x=0,y=0,COUNT;
COUNT=mount;
srand((int)time(NULL));//随机种子保证每次布雷不同
while(COUNT)
{
int x=rand()%(side-2)+1;
int y=rand()%(side-2)+1;
if(mines[x][y]=='0')
{
mines[x][y]='1';
COUNT--;
}
}
}
void Security(char (*mines)[22],int side,int X,int Y)
{
if(mines[X][Y]=='1')
{
int x=0,y=0,COUNT=1;
srand((int)time(NULL));
while(COUNT)
{
int x=rand()%(side-2)+1;
int y=rand()%(side-2)+1;
if(mines[x][y]=='0')
{
mines[x][y]='1';
COUNT--;
}
}
mines[X][Y]=='0';
}
}
void Open(char (*show)[22],char (*mines)[22],int side,int X,int Y)
{
int Mine=0;
Mine=Statistics(mines,X,Y);
if(Mine==0)
{
show[X][Y]=' ';
if (X-1>0&&Y>0&&show[X-1][Y]=='*')
Open(show,mines,side,X-1,Y);//反复展开直到不能展开为止
if (X-1>0&&Y+1<side-1&&show[X-1][Y+1]=='*')
Open(show,mines,side,X-1,Y+1);
if (X>0&&Y+1<side-1&&show[X][Y+1]=='*')
Open(show,mines,side,X,Y+1);
if (X+1<10&&Y+1<side-1&&show[X+1][Y+1]=='*')
Open(show,mines,side,X+1,Y+1);
if (X+1<side-1&&Y>0&&show[X+1][Y]=='*')
Open(show,mines,side,X+1,Y);
if (X+1<side-1&&Y-1>0&&show[X+1][Y-1]=='*')
Open(show,mines,side,X+1,Y-1);
if (X>0&&Y-1>0&&show[X][Y-1]=='*')
Open(show,mines,side,X,Y-1);
if (X-1>0&&Y-1>0&&show[X-1][Y-1]=='*')
Open(show,mines,side,X-1,Y-1);
}
else
{
show[X][Y]=Statistics(mines,X,Y)+'0';
}
}
int Statistics(char (*mines)[22],int X,int Y)
{
int COUNT=0;
if(mines[X-1][Y]=='1')
COUNT++;
if(mines[X-1][Y-1]=='1')
COUNT++;
if(mines[X-1][Y+1]=='1')
COUNT++;
if(mines[X][Y+1]=='1')
COUNT++;
if(mines[X][Y-1]=='1')
COUNT++;
if(mines[X+1][Y]=='1')
COUNT++;
if(mines[X+1][Y-1]=='1')
COUNT++;
if(mines[X+1][Y+1]=='1')
COUNT++;
return COUNT;
}
int Calculate(char (*show)[22],int side)
{
int i,j,COUNT=0;
for(i=1;i<side-1;i++)
{
for(j=1;j<side-1;j++)
{
if(show[i][j]=='*')
COUNT++;
}
}
return COUNT;
}
void GameMove(char (*show)[22],char (*mines)[22],int side,int mount)
{
int X,Y;
float time;
clock_t start,end;//计时
for(;;)//第一次查看同时确保第一次绝对安全
{
printf(" 请输入你想查看的坐标(X,Y):");
scanf("%d,%d",&X,&Y);
start=clock();
getchar();
if(X>=1&&X<=(side-2)&&Y>=1&&Y<=(side-2))
break;
else
printf(" 请按照格式输入正确的坐标!!");
}
printf("\a");
Security(mines,side,X,Y);
Open(show,mines,side,X,Y);
PrintingBoard(show,side);
printf(" 当前已点亮%d个区块,剩余%d个区块,加油!!\n",(side-2)*(side-2)-Calculate(show,side),Calculate(show,side)-mount);
for(;;)
{
printf(" 请输入请输入你想查看的坐标(X,Y):");
scanf("%d,%d",&X,&Y);
getchar();
if(show[X][Y]!='*')
{
printf(" 这个区块已经被点亮了哟!!\n");
continue;
}
if(X>=1&&X<=side-2&&Y>=1&&Y<=side-2)
{
if(mines[X][Y]=='1')
{
end=clock();
PrintingBoard(mines,side);
printf(" BOOM!!!\n你踩到雷了!!用时%f秒!!\n",((double)end-start)/CLK_TCK);
PlaySound(TEXT("BoomMusic.wav"),NULL,SND_FILENAME | SND_ASYNC | SND_LOOP);
system("pause");
printf("\n");
LastMenu();
}
else if(mines[X][Y]=='0')
{
printf("\a");
Open(show,mines,side,X,Y);
PrintingBoard(show,side);
if(Calculate(show,side)==mount)
{
end=clock();
PrintingBoard(mines,side);
time=((double)end-start)/CLK_TCK;
printf(" 扫雷成功!!用时%f秒!!\n",time);
ScanfHistory(time,mount);
printf("\n");
LastMenu();
}
else
printf(" 当前已点亮%d个区块,剩余%d个区块,加油!!\n",(side-2)*(side-2)-Calculate(show,side),Calculate(show,side)-mount);
}
}
else
{
printf(" 请按照格式输入正确的坐标!!");
}
}
}
void ScanfHistory(float t,int mount)
{
Rank R1;
R1.Time=GetTime();
R1.Score=t;
FILE *fp;
if(mount==Me)
R1.Level='E';
else if(mount==Mm)
R1.Level='M';
else if(mount==Mh)
R1.Level=='H';
fp=fopen("History.txt","a");
fprintf(fp,"%c %f %d\\%d\\%d %d:%d\n", R1.Level, R1.Score, R1.Time.Year,R1.Time.Month,R1.Time.Day,R1.Time.Hour,R1.Time.Minute);
fclose(fp);
}
void PrintfHistory()
{
Rank R2[1000],temp;
int N,i,j,p1=0,p2=0,p3=0;
FILE *fp;
char x,A[1000];
fp=fopen("History.txt","r");
while (!feof(fp))
{
x=fgetc(fp);
if (x=='\n')
N++;
}
rewind(fp);
Rank *Out=NULL;
Out=(Rank*)malloc(sizeof(Rank)*(N+1));
for (i=0;i<N;i++)
{
fgets(A,1000,fp);
sscanf(A,"%c %f %d\\%d\\%d %d:%d\n", &Out[i].Level, &Out[i].Score, &Out[i].Time.Year,&Out[i].Time.Month,&Out[i].Time.Day,&Out[i].Time.Hour,&Out[i].Time.Minute);
}
fclose(fp);
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
{
if(Out[i].Score>Out[j].Score)
{
temp=Out[i];
Out[i]=Out[j];
Out[j]=temp;
}
}
}
printf(" 简单难度历史记录为:\n\n");
printf(" 排名 成绩 时间\n\n");
for(i=0;i<10;i++)
{
if(Out[i].Level=='E')
{
p1++;
printf(" ");
printf("%d %f %d\\%d\\%d %d:%d\n", p1, Out[i].Score, Out[i].Time.Year,Out[i].Time.Month,Out[i].Time.Day,Out[i].Time.Hour,Out[i].Time.Minute);
}
}
printf("\n");
printf(" 中等难度历史记录为:\n\n");
printf(" 排名 成绩 时间\n\n");
for(i=0;i<10;i++)
{
if(Out[i].Level=='M')
{
p2++;
printf(" ");
printf("%d %f %d\\%d\\%d %d:%d\n", p2, Out[i].Score, Out[i].Time.Year,Out[i].Time.Month,Out[i].Time.Day,Out[i].Time.Hour,Out[i].Time.Minute);
}
}
printf("\n");
printf(" 困难难度历史记录为:\n\n");
printf(" 排名 成绩 时间\n\n");
for(i=0;i<10;i++)
{
if(Out[i].Level=='H')
{
p3++;
printf(" ");
printf("%d %f %d\\%d\\%d %d:%d\n", p3, Out[i].Score, Out[i].Time.Year,Out[i].Time.Month,Out[i].Time.Day,Out[i].Time.Hour,Out[i].Time.Minute);
}
}
LastMenu();
}