目录
用C语言中的二维数组写一个扫雷游戏程序
一、整体构思
1.整体框架-代码的骨架
首先我们需要编写一个简易游戏界面,即菜单menu,输入1,则开始游戏,输入0,则退出游戏(程序结束)。
以下是进入游戏界面的简易程序:
菜单程序
void menu()
{
printf("*********************************\n");
printf("**************1.play*************\n");
printf("**************0.exit*************\n");
printf("*********************************\n");
}
主函数程序
int main()
{
srand((unsigned int)time(NULL));
int input=0;
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch(input)
{
case 1:
printf("开始游戏\n");
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择\n");
break;
}
}while(input);
return 0;
}
至于主函数中为何要有下面的代码,是因为接下来要写布置雷的函数需要随机布置
srand((unsigned int)time(NULL));
接下来就是思考如何编写game()这个函数了
2.函数的声明
我们需要声明以下头文件与函数
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define ROW 9//行
#define COL 9//列
#define ROWS ROW+2//扫9*9边界的点
#define COLS COL+2//防止其周围越界
#define DIFFICULTY 10//低级难度10个雷
void menu();
void game();
void initboard(char board[ROWS][COLS],int rows,int cols,char set);//初始化是11*11,防止越界
void displayboard(char board[ROWS][COLS],int row,int col);//打印是9*9
void setmine(char board[ROWS][COLS],int row,int col);//布置雷
void findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col);//排查雷
int getminecount(char mine[ROWS][COLS],int x,int y);//统计坐标周围有几个雷
3.主游戏函数—game()的编写
在编写这个游戏函数之前,我们需要了解何为扫雷游戏:扫雷是一款经典的单人电脑游戏,目标是在不触发地雷的情况下,清除所有未埋雷的方格。以下是扫雷游戏的基本玩法和游戏规则
- 游戏开始时,你会看到一个由方格组成的矩形区域。方格的大小和数量取决于游戏的难度级别(初级、中级、高级)。
• 初级:9×9 的方格,10 个地雷。
• 中级:16×16 的方格,40 个地雷。
• 高级:16×30 的方格,99 个地雷。 - 游戏目标 :清除所有未埋雷的方格,同时避免触发地雷。游戏胜利的条件是所有非雷方格都被翻开,而地雷方格被标记为旗帜(右键点击方格可以标记)。
- 操作方式• 左键点击:翻开一个方格。如果方格内有地雷,游戏结束;如果方格内没有地雷,会显示一个数字,表示周围 8 个相邻方格中地雷的数量。
根据以上游戏规则,我们可以通过主要的两个二维数组来实现其基本玩法。
1.数组mine用来存放我们打游戏时不可见的布置雷的信息
2.数组show则是我们玩游戏时看着的那个矩形区域,还没有开始排查时是一片白色方格
char mine[ROWS][COLS]={0};//存放布置好的雷的信息
char show[ROWS][COLS]={0};//存放排查出的雷的信息
总结game() 程序如下
void game()
{
char mine[ROWS][COLS]={0};//存放布置好的雷的信息
char show[ROWS][COLS]={0};//存放排查出的雷的信息
initboard(mine,ROWS,COLS,'0');//初始化布置好的雷的信息全为0
initboard(show,ROWS,COLS,'*');//初始化排查出的雷的信息全为*
setmine(mine,ROW,COL);//布置雷,1表示雷,0表示不是雷
printf("-------------扫雷-----------\n");
displayboard(mine,ROW,COL);//打印布置好雷的棋盘,正式进行游戏时,需要隐藏
printf("\n");
printf("____________________________\n");
displayboard(show,ROW,COL);
findmine(mine,show,ROW,COL);//排查雷
}
二、关键函数的编写
1.初始化棋盘
接着我们应该思考如何写一个函数初始化我们的两个游戏矩阵区域数组,即用固定的符号填满整个矩形区域
1.我们可将存放雷的数组全部初始化为0,0表示不是雷
2.把展示给我们的矩形区域数组全部初始化为 * ,* 表示该位置还未被排查
void initboard(char board[ROWS][COLS],int rows,int cols,char set)
{
int i=0;
int j=0;
for(i=0;i<rows;i++)
{
for(j=0;j<cols;j++)
{
board[i][j]=set;
}
}
}
2.布置雷
紧接着便是布置雷的函数setmine,众所周知雷的布置是随机的,这便需要我上述提到的一个代码
注意其需要的头文件<stdlib.h>,<time.h>
srand((unsigned int)time(NULL));
我们把字符1当做雷,把雷布置在初始化后的存放雷的数组中
布置雷的函数如下
void setmine(char mine[ROWS][COLS],int row,int col)
{
int count=DIFFICULTY;
while(count)
{
int x=rand()%9+1;
int y=rand()%9+1;
if(mine[x][y]=='0')
{
mine[x][y]='1';
count--;
}
}
}
3.打印矩形区域
void displayboard(char board[ROWS][COLS],int row,int col)
{
int i=0;
int j=0;
for(i=0;i<=col;i++)
{
printf("%d ",i);
}
printf("\n");
for(i=1;i<=col;i++)
{
printf("%d ",i);
for(j=1;j<=row;j++)
{
printf("%c ",board[i][j]);
}
printf("\n");
}
}
4.排查雷(关键)
void findmine(char mine[ROWS][COLS],char show[ROWS][COLS],int row,int col)
{
int x,y;
int WIN=0;
while(ROW*COL-DIFFICULTY!=WIN)
{
printf("请输入要排查的坐标:>");
scanf("%d %d",&x,&y);
if(x>=1&&x<=9&&y>=1&&y<=9)
{
if(mine[x][y]=='1')
{
printf("很遗憾,你被炸死了\n");
displayboard(mine,ROW,COL);
break;
}
if(mine[x][y]=='0')
{
int count=getminecount(mine,x,y);
show[x][y]=count+'0';
displayboard(show,ROW,COL);
WIN++;
if(WIN==ROW*COL-DIFFICULTY)
{
printf("恭喜你,排雷成功\n");
displayboard(mine,ROW,COL);
break;
}
}
}
else
{
printf("输入坐标非法,请重新输入\n");
}
}
}
5.统计所排查的坐标周围有几个雷
即上述排查雷函数中调用的另一个函数
把所选排查的坐标上面三个坐标,所在行左右加其本身3个坐标,下面三个坐标这个3×3的区域都挨个过一遍
int getminecount(char mine[ROWS][COLS],int x,int y)//统计坐标周围有几个雷
{
int count=0;
for(int i=x-1;i<=x+1;i++)
{
for(int j=y-1;j<=y+1;j++)
{
if(mine[i][j]=='1')
{
count++;
}
}
}
return count;
}
三、拓展与思考
我们所编写的只是一个简易版的扫雷,其中缺少了很多游戏中的正式功能。如可以放个旗帜在未排查但已知是雷的区域上增加可玩性;还有就是如果一个区域附近大片区域没有雷可以直接显示出空雷的区域,直到所扫的那个区块附近有雷,这可以有效的缩短时长增加可玩性;更高级一点的就是用鼠标点击那个想排查的区域,而不是输入坐标等等。这些大家感兴趣的都可以去了解一下。