扫雷----超详解+完整原码(扩展版)(下)

简介: 扫雷----超详解+完整原码(扩展版)(下)

😊书写排查雷的函数


//排雷的函数
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
   //1.输入排查的坐标
     //2.检查该坐标处是不是雷
   //(1) 是雷   - 很遗憾,你被炸死了 - 游戏结束
   //(2) 不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续
  int x = 0;
  int y = 0;
  int win = 0;
  int select = 0;
  while (win < row * col - EASY_COUNT)
  {
    printf("请选择:1.排查雷 2.标记雷 3.取消标记\t");
    scanf("%d", &select);
    if (select == 1) 
    {
      printf("请输入要排查雷的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          if (mine[x][y] == '1')
          {
            printf("\n\n很遗憾,你被炸死了!\n");
            printf("雷的分布情况,其中('1'表示雷):\n");
            DisplayBoard(mine, ROW, COL);
            break;
          }
          else
          {
            OpenArea(mine, show,ROW,COL, x, y);
            //显示排查出的信息
            DisplayBoard(show, ROW, COL);
            //计算已经排出的非雷位置的个数
            win = get_win(show, ROW, COL);
          }
        }
        else
        {
          printf("该位置已被排查过,请重新输入!\n");
        }
      }
      else
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else if (select == 2)
    {
      printf("请输入要标记的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          show[x][y] = '!';
          DisplayBoard(show, ROW, COL);
        }
        else if(show[x][y]=='!')
        {
          printf("该位置已被标记,请重新选择!\n");
        }
        else
        {
          printf("该位置不能标记,请重新选择!\n");
        }
      }
      else 
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else if (select == 3)
    {
      printf("请输入要取消标记的坐标:>");
      scanf("%d %d", &x, &y );
      if (x >= 1 && x <= row && y >= 1 && y <= col)
      {
        if (show[x][y] == '!')
        {
          show[x][y] = '*';
          DisplayBoard(show, ROW, COL);
        }
        else
        {
          printf("该位置不能取消标记,请重新选择!\n");
        }
      }
      else
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else 
    {
      printf("输入有误,请重新输入!\n");
    }
    //printf("win=%d\n", win);
  }
  if (win == row * col - EASY_COUNT) 
  {
    printf("\n恭喜你,排雷成功!\n");
    printf("雷的分布情况,其中('1'表示雷):\n");
    DisplayBoard(mine, ROW, COL);
  }
}
//基础功能+拓展功能
//1.标记功能(用'!')
//2.展开一片区域的功能(使用递归)      
//*当排查下x,y坐标时:(1)该坐标不是雷  (2)该坐标周围没有雷  (3)该坐标没有被排查过


👀如何排查雷?

基本思路:

              1.输入排查的坐标
               2.检查该坐标处是不是雷

                ❌ 是雷   - 很遗憾,你被炸死了 - 游戏结束
                 ✔️不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续


        printf("请输入要排查雷的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          if (mine[x][y] == '1')
          {
            printf("\n\n很遗憾,你被炸死了!\n");
            printf("雷的分布情况,其中('1'表示雷):\n");
            DisplayBoard(mine, ROW, COL);
            break;
          }
          else
          {
            OpenArea(mine, show,ROW,COL, x, y);
            //显示排查出的信息
            DisplayBoard(show, ROW, COL);
            //计算已经排出的非雷位置的个数
            win = get_win(show, ROW, COL);
            //win++;
          }
        }
        else
        {
          printf("该位置已被排查过,请重新输入!\n");
        }
      }
      else
      {
        printf("坐标不合法,请重新输入!\n");
      }


👀如何标记雷?

因为排查雷和标记雷是两个不同的过程,所以这时我们需要通过使用if-else语句来选择排查雷还是标记雷,标记雷的位置用‘ !’来表示。


//printf("请选择:1.排查雷 2.标记雷\t");
//scanf("%d", &select);
else if (select == 2)
    {
      printf("请输入要标记的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          show[x][y] = '!';
          DisplayBoard(show, ROW, COL);
        }
        else if(show[x][y]=='!')
        {
          printf("该位置已被标记,请重新选择!\n");
        }
        else
        {
          printf("该位置不能标记,请重新选择!\n");
        }
      }
      else 
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else 
    {
      printf("输入有误,请重新输入!\n");
    }
    //printf("win=%d\n", win);
  }


👀 如何判断输赢?

if (win == row * col - EASY_COUNT) 
  {
    printf("\n恭喜你,排雷成功!\n");
    printf("雷的分布情况,其中('1'表示雷):\n");
    DisplayBoard(mine, ROW, COL);
  }


当show棋盘上非雷位置和非标记位置个数mine棋盘上‘0’的个数(即非雷个数)相等时,打印“恭喜你,排雷成功!”,并打印mine棋盘的雷的分布情况。若不等于则继续进行排雷或标记雷的步骤。


打印结果:

ef464045b16b44ca862932dbd2cab8e9.png


3.game.h文件


😄需要使用的头文件


1. #include<stdio.h>
2. #include<stdlib.h>
3. #include<time.h>;


😄定义棋盘行列


1. #define ROW 9
2. #define COL 9
3. 
4. #define ROWS ROW+2
5. #define COLS COL+2


打印棋盘信息时,使用9*9的棋盘,在进行初始化,设置雷,排查雷,标记雷等操作时使用11*11的棋盘。


😄定义雷的个数


#define EASY_COUNT 10


😄初始化棋盘


1. //初始化棋盘
2. void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);


😄打印棋盘


1. //打印棋盘
2. void DisplayBoard(char board[ROWS][COLS], int row, int col);


😄布置雷


1. //布置雷
2. void Setmine(char board[ROWS][COLS],int row,int col);


😄排查雷


1. //排查雷
2. void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col);


四、总代码



注意:此代码分为三个部分的代码


(一)game.h文件


#include<stdio.h>
#include<stdlib.h>
#include<time.h>;
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
//初始化棋盘
void InitBoard(char board[ROWS][COLS], int rows, int cols,char set);
//打印棋盘
void DisplayBoard(char board[ROWS][COLS], int row, int col);
//布置雷
void Setmine(char board[ROWS][COLS],int row,int col);
//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS],int row,int col);


(二)game.c文件


#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//初始化棋盘
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;
    }
}
//打印棋盘信息
void DisplayBoard(char board[ROWS][COLS], int row, int col)
{
  int i = 0;
  int j = 0;
  printf("------扫雷游戏------\n");
  printf("════════════════════\n");//美化棋盘
  for (j = 0; j <= col; j++)
  {
    printf("%d|", j);
  }
  printf("\n-|══════════════════");//美化棋盘
  printf("\n");
  for (i = 1; i <= row; i++)
  {
    printf("%d|", i);
    for (j = 1; j <= col; j++)
    {
      printf("%c|", board[i][j]);
    }
    printf("\n");
  }
  printf("════════════════════\n");//美化棋盘
  printf("------扫雷游戏------\n\n");
}
//设置雷的函数
void Setmine(char board[ROWS][COLS], int row, int col)
{
  int count = EASY_COUNT;
  //行1-9  列1-9
  while (count)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (board[x][y] == '0')
    {
      board[x][y] = '1';
      count--;
    }
  }
}
//统计周围雷数的函数
int get_mine_count(char board[ROWS][COLS],int x,int y)
{
  int count = 0;
  for(int i=-1;i<=1;i++)
    for (int j = -1; j <= 1; j++)
    {
      if (board[x + i][y + j] == '1')
        count++;
    }
  return count;
  /*return (board[x - 1][y] +
    board[x - 1][y - 1] +
    board[x][y - 1] +
    board[x + 1][y - 1] +
    board[x + 1][y] +
    board[x + 1][y + 1] +
    board[x][y + 1] +
    board[x - 1][y + 1] - 8 * '0');*/
}
//递归,展开一片区域的函数
void OpenArea(char mine[ROWS][COLS],char show[ROWS][COLS], int row, int col,int x, int y)
{
  int count = get_mine_count(mine, x, y);
  if (count == 0) 
  {
    show[x][y] = ' ';
    for (int i = x - 1; i <= x + 1; i++) 
    {
      for (int j = y - 1; j <= y + 1; j++) 
      {
        if (show[i][j] == '*' && x >= 1 && x <= row && y >= 1 && y <= col) 
        {
          OpenArea(mine, show,ROW,COL, i, j);
        }
      }
    }
  }
  else 
  {
    show[x][y] = count + '0';
  }
}
// 计算非雷和非标记的位置个数
int get_win(char board[ROWS][COLS], int row, int col)
{
  int win = 0;
  for(int i=1;i<=row;i++)
    for (int j = 1; j <= col; j++)
    {
      if (board[i][j]!='*'&&board[i][j]!='!')
        win++;
    }
  return win;
}
//排雷的函数
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
   //1.输入排查的坐标
     //2.检查该坐标处是不是雷
   //(1) 是雷   - 很遗憾,你被炸死了 - 游戏结束
   //(2) 不是雷 - 统计坐标周围有几个雷 - 存储排查雷的信息到show数组,游戏继续
  int x = 0;
  int y = 0;
  int win = 0;
  int select = 0;
  while (win < row * col - EASY_COUNT)
  {
    printf("请选择:1.排查雷 2.标记雷 3.取消标记\t");
    scanf("%d", &select);
    if (select == 1) 
    {
      printf("请输入要排查雷的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          if (mine[x][y] == '1')
          {
            printf("\n\n很遗憾,你被炸死了!\n");
            printf("雷的分布情况,其中('1'表示雷):\n");
            DisplayBoard(mine, ROW, COL);
            break;
          }
          else
          {
            OpenArea(mine, show,ROW,COL, x, y);
            //显示排查出的信息
            DisplayBoard(show, ROW, COL);
            //计算已经排出的非雷位置的个数
            win = get_win(show, ROW, COL);
          }
        }
        else
        {
          printf("该位置已被排查过,请重新输入!\n");
        }
      }
      else
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else if (select == 2)
    {
      printf("请输入要标记的坐标:>");
      scanf("%d %d", &x, &y);
      //判断坐标合法性
      if (x >= 1 && x <= row && y >= 1 && y <= col) 
      {
        if (show[x][y] == '*')
        {
          show[x][y] = '!';
          DisplayBoard(show, ROW, COL);
        }
        else if(show[x][y]=='!')
        {
          printf("该位置已被标记,请重新选择!\n");
        }
        else
        {
          printf("该位置不能标记,请重新选择!\n");
        }
      }
      else 
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else if (select == 3)
    {
      printf("请输入要取消标记的坐标:>");
      scanf("%d %d", &x, &y );
      if (x >= 1 && x <= row && y >= 1 && y <= col)
      {
        if (show[x][y] == '!')
        {
          show[x][y] = '*';
          DisplayBoard(show, ROW, COL);
        }
        else
        {
          printf("该位置不能取消标记,请重新选择!\n");
        }
      }
      else
      {
        printf("坐标不合法,请重新输入!\n");
      }
    }
    else 
    {
      printf("输入有误,请重新输入!\n");
    }
    //printf("win=%d\n", win);
  }
  if (win == row * col - EASY_COUNT) 
  {
    printf("\n恭喜你,排雷成功!\n");
    printf("雷的分布情况,其中('1'表示雷):\n");
    DisplayBoard(mine, ROW, COL);
  }
}
//基础功能+拓展功能
//1.标记功能(用'!')
//2.展开一片区域的功能(使用递归)      
//*当排查下x,y坐标时:(1)该坐标不是雷  (2)该坐标周围没有雷  (3)该坐标没有被排查过


(三)test.c文件


#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu()
{
  printf("\t\t\t\t\t\t\t\t\t\t\t\n");
  printf("*********************\n");
  printf("*****  1. play  *****\n");
  printf("*****  0. exit  *****\n");
  printf("*********************\n");
}
void game()
{
  char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
  char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息
  //初始化数组的内容为指定内容
  //mine数组在没有布置雷的时候,都是‘0’
  InitBoard(mine, ROWS, COLS,'0');
  //show数组在没有排查雷的时候都是‘*’
  InitBoard(show, ROWS, COLS, '*'); 
  //设置雷
  Setmine(mine, ROW, COL);
  DisplayBoard(show, ROW, COL);
  //DisplayBoard(mine, ROW, COL);
  //排查雷
  FindMine(mine, show, ROW, COL);
}
int main()
{
  int input = 0;
  srand((unsigned int)time(NULL));
  do
  {
    menu();
    printf("请选择:>");
    scanf("%d", &input);
    switch (input)
    {
    case 1:system("cls"); game();
      break;
    case 0:printf("退出游戏\n");
      break;
    default:printf("选择错误,请重新输入!\n");
      break;
    }
  } while (input);
  return 0;
}


五、效果展示



image.png

image.png

image.png

image.png

image.png

image.png

扫雷游戏展示

image.png

image.png

image.png

image.png

image.png

扫雷游戏展示


🔥好了, 今天的内容就分享到这里了。愿这篇博客能够为您带来新的思考和启示。感谢您的耐心阅读和支持。无论在人生的道路上遇到怎样的困难和挑战,记住相信自己的力量,努力前行。期待与您共同探索更多精彩的内容。再次感谢!

目录
相关文章
|
6月前
|
C语言
C语言-------扫雷游戏的代码实现
C语言-------扫雷游戏的代码实现
47 0
|
6月前
|
C语言
LeetCode---消失的数字---C语言实现
LeetCode---消失的数字---C语言实现
|
5月前
|
C语言
C语言---函数----100~n之间的素数
C语言---函数----100~n之间的素数
|
5月前
|
C语言
C语言----循环---n的k次方
C语言----循环---n的k次方
|
5月前
|
C语言
C语言------猜数字游戏----有次数限制版
C语言------猜数字游戏----有次数限制版
|
5月前
|
C语言
C语言----递归--n的k次方
C语言----递归--n的k次方
|
存储 C语言 C++
C语言---数据结构实验---数制转换---表达式求值---回文判断---二叉树创建遍历
C语言---数据结构实验---数制转换---表达式求值---回文判断---二叉树创建遍历
|
C语言
C语言每日一题 ---- 打印从1到最大的n位数(Day 1)
C语言每日一题 ---- 打印从1到最大的n位数(Day 1)
62 0
|
存储 安全 C语言
扫雷----超详解+完整原码(扩展版)(上)
扫雷----超详解+完整原码(扩展版)(上)
85 0
下一篇
无影云桌面