基于C语言简单的扫雷小游戏

扫雷作为受众很广泛的一款小游戏,操作简单易上手,那么应该如何引用多文件实现一个小小的扫雷小游戏项目呢?

思路

根据多文件的性质,我们应该把这个项目分为三个文件,头文件、主函数的库文件和调用函数的库文件。
其中主要进行编程思考的是调用函数,本项目要实现的功能应该有:

  1. 玩家第一次选坐标不被炸死
  2. 初始化棋盘(随机布雷)
  3. 显示九宫格内雷的总数
  4. 展示棋盘
  5. 菜单选择界面

1.首先我们需要一个棋盘

我们需要用二维数组来打印两个棋盘,假如我们要打印10X10的棋盘,那我们的二维数组元素也要为10X10个吗?,不能,因为我们在设计算法时需要统计坐标周围8个方位雷的个数,假如要统计边界坐标周围雷的个数,那么就会有数组越界的问题,那我们就要在10X10的边界多上一圈元素,也就要定义12X12的数组元素,当然展示棋盘的时候这些元素我们不要打印出来
如图:
在这里插入图片描述
我们打印设计者棋盘要用数组mine[ROW][COL],打印要展示给玩家的数组board[ROW][COL],两个数组在开始必须要初始化,在设计棋盘中字符0代表不是雷,字符*代表显示棋盘的未点开的位置,先初始化两个数组
代码如下:
头文件包含:

#define ROW 12 //设计者棋盘横坐标
#define COL 12 //设计者棋盘纵坐标
#define TOTAL 10*10 //玩家棋盘的总数
#define MINE_NUM 20 //雷的个数

Game函数包含:

 char mine[ROW][COL];   
 char board[ROW][COL]; 
 memset(mine, '0', sizeof(mine));//初始化数组
 memset(board, '*', sizeof(board));

2.布雷,我们使用随机函数生成。

int GetRandIndex(int start, int end)//保证随机数在1-10
{
    
    
return rand() % (end - start + 1) + start;
}

void SetMine(char mine[][COL], int row, int col)
{
    
    
srand((unsigned long)time(NULL));
int count = 0;//count计算已经布雷的总数
while (count < MINE_NUM) {
    
    
int x = GetRandIndex(1, 10);
int y = GetRandIndex(1, 10);
if (mine[x][y] == '0') {
    
    
mine[x][y] = '1';
count++;
}
}}

3.打印雷阵

void ShowBoard(char board[][COL], int row, int col)
{
    
    
printf(" ");
int i = 1;
for (; i <= 10; i++) {
    
    
printf(" %d ", i);
}
printf("\n----");
for (i = 1; i <= 10; i++) {
    
    
printf("---");
}
printf("\n");
for (i = 1; i <= 10; i++) {
    
    
printf("%3d|", i);int j = 1;
for (; j <= 10; j++) {
    
    
printf("%2c|", board[i][j]);
}
printf("\n");
int k = 1;
for (k = 1; k <= 11; k++) {
    
    
printf("---");
}
printf("\n");
}
}

4.根据游戏规则,要在已经展开的地方的九宫格中心显示的地雷总数。

char GetMines(char mine[][COL], int row, int col)//char->'0'-'8'
{
    
    
return mine[row - 1][col - 1] + mine[row - 1][col] + \mine[row - 1][col + 1] + mine[row][col - 1] + mine[row][col + 1] + \
mine[row + 1][col - 1] + mine[row + 1][col] + \
mine[row + 1][col + 1] - 7 * '0';
}

5.游戏总函数

void Game()
{
    
    
 char mine[ROW][COL];   //set/judge mine
 char board[ROW][COL]; //show
 memset(mine, '0', sizeof(mine));
 memset(board, '*', sizeof(board));
 SetMine(mine, ROW, COL);
 int count = TOTAL;
 int x = 0;
 int y = 0;
 int times = 0;
 while (1) {
    
    
  ShowBoard(board, ROW, COL);
  printf("请选择坐标: ");
  scanf("%d,%d", &x, &y);
  times++;
  if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2) {
    
    
   if (times == 1) {
    
    
    mine[x][y] = '0';
   }
   if (mine[x][y] == '0') {
    
    
    if (mine[x - 1][y - 1] == '0')
     board[x - 1][y - 1] = GetMines(mine, x - 1, y - 1);
    if(mine[x - 1][y] == '0')
     board[x - 1][y] = GetMines(mine, x - 1, y);
    if(mine[x - 1][y + 1] == '0')
     board[x - 1][y + 1] = GetMines(mine, x - 1, y + 1);
    if(mine[x][y - 1] == '0')
     board[x][y - 1] = GetMines(mine, x, y - 1);
    if(mine[x][y + 1] == '0')
     board[x][y + 1] = GetMines(mine, x, y + 1);
    if(mine[x + 1][y - 1] == '0')
     board[x + 1][y - 1] = GetMines(mine, x + 1, y - 1);
    if( mine[x + 1][y] == '0') 
     board[x + 1][y] = GetMines(mine, x + 1, y);
    if(mine[x + 1][y + 1] == '0' )
     board[x + 1][y + 1] = GetMines(mine, x + 1, y + 1);
    char num = GetMines(mine, x, y);
    board[x][y] = num;
    count--;
    if (count <= 20) {
    
    
     printf("你赢了,厉害!\n");
     break;
    }
   }
   else {
    
    
    printf("不好意思,你被炸死了!\n");
    ShowBoard(mine, ROW, COL);
    break;
   }
  }
  else {
    
    
   printf("你输入的坐标有误,请重新输入!\n");
  }
 }
}

其中
为了像我们以往玩的那样,点开一个空的地方就展开旁边空的地方。需要做一个判断才能实现

if (mine[x - 1][y - 1] == '0')
     board[x - 1][y - 1] = GetMines(mine, x - 1, y - 1);
    if(mine[x - 1][y] == '0')
     board[x - 1][y] = GetMines(mine, x - 1, y);
    if(mine[x - 1][y + 1] == '0')
     board[x - 1][y + 1] = GetMines(mine, x - 1, y + 1);
    if(mine[x][y - 1] == '0')
     board[x][y - 1] = GetMines(mine, x, y - 1);
    if(mine[x][y + 1] == '0')
     board[x][y + 1] = GetMines(mine, x, y + 1);
    if(mine[x + 1][y - 1] == '0')
     board[x + 1][y - 1] = GetMines(mine, x + 1, y - 1);
    if( mine[x + 1][y] == '0') 
     board[x + 1][y] = GetMines(mine, x + 1, y);
    if(mine[x + 1][y + 1] == '0' )
     board[x + 1][y + 1] = GetMines(mine, x + 1, y + 1);

另外为了保证客户对游戏愉悦性,不能第一次就被炸死,所以:

 times++;//计算第几次输入坐标
  if (x >= 1 && x <= ROW - 2 && y >= 1 && y <= COL - 2) {
    
    
   if (times == 1) {
    
    
    mine[x][y] = '0';
   }

6.菜单选择

为了代码的简洁,分区清楚,菜单部分可以再建立一个.c文件

void Menu()
{
    
    
 printf("###################################\n");
 printf("## 1. Play               2. Exit ##\n");
 printf("###################################\n");
 printf("Please Select: ");
}
int main()
{
    
    
 int quit = 0;
 int select = 0;
 while (!quit){
    
    
  Menu();
  scanf("%d", &select);
  switch (select)
  {
    
    
  case 1:
   Game();
   break;
  case 2:
   printf("拜拜!\n");
   quit = 1;
   break;
  default:
   printf("选择错误,请重新选择!\n");
   break;
  }
 }
 system("pause");
 return 0;
}

最后奉上整体的代码:
https://github.com/GagaAutom/C-programming-language/tree/master/mine%20clearance

参考大佬来源:
C语言实现扫雷——详解
https://blog.csdn.net/yc1515707718/article/details/78744978

猜你喜欢

转载自blog.csdn.net/qq_40893595/article/details/102999586