学会了C语言,不来自己写个【扫雷】小项目吗?

简介: 学会了C语言,不来自己写个【扫雷】小项目吗?

🌟什么是扫雷


这款游戏的玩法是在一个9*9的方块矩阵中随机布置10个地雷。由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷。


ac2da2837974130cb1a3f9500bdd357b_a39f352777b24fbcab41130d2e844e78.png


下面我们就用尝试用C语言实现这个游戏。


🌟菜单界面


⭐️游戏菜单


游戏总需要一个界面吧,不然不知道应该干什么,通过【printf】函数实现菜单界面,打开游戏自动跳出 1.开始游戏 0.退出游戏。

void menu()
{
  printf("****************************\n");
  printf("*******  1.开始游戏  *******\n");
  printf("*******  0.退出游戏  *******\n");
  printf("****************************\n");
}


⭐️实现选择


有了菜单,下一步就是选择选项了,这里需要考虑一下输入错误的情况偶。

void choice()
{
  int num;
  do
  {
    menu();
    printf("请输入您的选项:");
    scanf("%d",&num);
    switch (num)
    {
      case(1):
        game(); break;
      case(0):
        printf("退出游戏\n"); break;
      default:
        printf("输入错误,小笨蛋~~\n");
      break;
    }
  }
  while(num);
}


🌟棋盘界面


⭐️创建雷盘


菜单界面,选择都完成了。扫雷最重要的扫雷界面还没有建立。我们需要两个二维数组来存储扫雷信息,第一个用来存放雷,也就是用来埋雷的。第二个用来显示扫雷界面,及显示玩家扫雷位置的。

为了更好的计算我们要扫的位置处周围有多少雷,我们把数组长度定义为11。

#define ROW 9  
#define COL 9
char mine[ROW+2][COL+2] = { 0 };//存放雷
char show[ROW+2][COL+2] = { 0 };//扫雷界面


⭐️初始化雷盘


拥有了棋盘还不够,棋盘里面没有东西呀,我们将布雷棋盘内填满 0 ,在显示棋盘内填满 *

void Init(char board[ROWS][COLS], int row, int col, char set)
{
  int i = 0 ;
  int j = 0 ;
  for (i = 0; i < row + 2; i++)
  {
    for (j = 0; j < col + 2; j++)
    {
      board[i][j] = set;
    }
  }
}
Init(mine, ROW, COL, '0');
Init(show, ROW, COL, '*');


⭐️打印雷盘


打印时我们可以多输出一次坐标,方便游玩时查找坐标

void Display(char board[ROWS][COLS], int row, int col)
{
  int i = 0;
  int j = 0;
  printf("******扫雷游戏*******\n");
  for (i = 0; i < row + 1; i++)
  {
    printf("%d ", i);
    for (j = 1; j < col + 1; j++)
    {
      if (i == 0)
        printf("%d ", j);
      else
        printf("%c ", board[i][j]);
    }
    printf("\n");
  }
}


🌟扫雷界面


⭐️布置雷


我们实现了玩家下棋的逻辑之后,就要实现电脑下棋的逻辑了,电脑的逻辑就是生成两个随机数,分别%3,得到的就是符合三子棋二维数组坐标要求的两个数。


⚡️随机数函数


在这里我们需要两个随机数,可以使用【 rand() 】函数


使用rand()函数需要引用【#include<stdlib.h>】头文件


默认情况下【 rand() 】函数并不是一个真随机函数,而是一个假随机函数。在使用时侯还需调用【srand()】函数,【srand()】函数会设置供【 rand() 】函数使用的随机数种子,每一个种子对应一组根据算法预先生成的随机数;

  srand((unsigned) time(NULL));//产生种子

void Set_Mine(char mine[ROWS][COLS], int row, int col, int count)
{
  while (count)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (mine[x][y] == '0')
    {
      mine[x][y] = '1';
      count--;
    }
  }
}


🌟扫雷


⭐️选择位置


void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count)
{
  int x = 0;
  int y = 0;
  int judge = 0;
  while (judge < row*col - count)
  {
    printf("请输入要扫除的坐标: \n");
    scanf("%d %d", &x, &y);
    if (x < 0 || y < 0 || x > row || y > col)
      printf("输入错误,小笨蛋~~\n");
    else if (show[x][y] != '*')
      printf("该坐标已被扫了偶\n");
     if(judge == 0)
      No_mine(mine, show, x, y, row, col);
     if (mine[x][y] != '1')
     {
       Spread(x, y, mine, show, row, col);
       Display(show, row, col);
     }
     else
     {
       printf("你被炸死了\n");
       break;
     }
     Stat_judge(show, &judge, row, col);
  }


⭐️第一次不为雷


void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count)
{
  int x = 0;
  int y = 0;
  int judge = 0;
  while (judge < row*col - count)
  {
    printf("请输入要扫除的坐标: \n");
    scanf("%d %d", &x, &y);
    if (x < 0 || y < 0 || x > row || y > col)
      printf("输入错误,小笨蛋~~\n");
    else if (show[x][y] != '*')
      printf("该坐标已被扫了偶\n");
     if(judge == 0)
      No_mine(mine, show, x, y, row, col);
     if (mine[x][y] != '1')
     {
       Spread(x, y, mine, show, row, col);
       Display(show, row, col);
     }
     else
     {
       printf("你被炸死了\n");
       break;
     }
     Stat_judge(show, &judge, row, col);
  }


⭐️落子周围雷数


int Count_Mine(int x, int y, char mine[ROWS][COLS])
{
  return mine[x - 1][y - 1]
    + mine[x - 1][y]
    + mine[x - 1][y + 1]
    + mine[x][y - 1]
    + mine[x][y + 1]
    + mine[x + 1][y - 1]
    + mine[x + 1][y]
    + mine[x + 1][y + 1] - 8 * '0';
}


⭐️落子周围无雷


void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col
)
{
  char count = Count_Mine(x, y, mine) + '0';
  if (count != '0')
    show[x][y] = count;
  else
  {
    show[x][y] = ' ';
    if (x - 1 > 0 && show[x - 1][y] == '*')
      Spread(x - 1, y, mine, show, row, col);
    if (y - 1 > 0 && show[x][y - 1] == '*')
      Spread(x, y - 1, mine, show, row, col);
    if (y + 1 < col + 1 && show[x][y + 1] == '*')
      Spread(x, y + 1, mine, show, row, show);
    if (x + 1 < row + 1 && show[x + 1][y] == '*')
      Spread(x + 1, y, mine, show, row, col);
  }
}


🌟判断胜利


void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col)
{
    *judge=0;
  int i = 0;
  int j = 0;
  for (i = 1; i < row + 1; i++)
  {
    for (j = 1; j < col + 1; j++)
    {
      if (show[i][j] != '*')
        (*judge)++;
    }
  }
}


🌟游戏函数


void game()
{
  srand((unsigned long)time(NULL)); //生成随机数种子
  char mine[ROWS][COLS] = { 0 };
  char show[ROWS][COLS] = { 0 };
  Init_board(mine, ROWS, COLS, '0');//初始化雷盘
  Init_board(show, ROWS, COLS, '*');//初始化展示的雷盘
  Set_Mine(mine,ROW,COL,10);
  Sweep(mine,show,ROW,COL,10);
}


🌟代码详细


下面是完整代码,可以试一试自己完整的写一遍。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 9  
#define COL 9
#define ROWS ROW + 2
#define COLS ROW + 2
void game();
void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count);
void No_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col);
void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);
void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col);
void menu()
{
  printf("****************************\n");
  printf("*******  1.开始游戏  *******\n");
  printf("*******  0.退出游戏  *******\n");
  printf("****************************\n");
}
void choice()
{
  int num;
  do
  {
    menu();
    printf("请输入您的选项:");
    scanf("%d",&num);
    switch (num)
    {
      case(1):
        game(); break;
      case(0):
        printf("退出游戏\n"); break;
      default:
        printf("输入错误,小笨蛋~~\n");
      break;
    }
  }
  while(num);
}
void Init_board(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 Set_Mine(char mine[ROWS][COLS], int row, int col, int count)
{
  while (count)
  {
    int x = rand() % row + 1;
    int y = rand() % col + 1;
    if (mine[x][y] == '0')
    {
      mine[x][y] = '1';
      count--;
    }
  }
}
void Display(char board[ROWS][COLS], int row, int col)
{
  int i = 0;
  int j = 0;
  printf("******扫雷游戏*******\n");
  for (i = 0; i < row + 1; i++)
  {
    printf("%d ", i);
    for (j = 1; j < col + 1; j++)
    {
      if (i == 0)
        printf("%d ", j);
      else
        printf("%c ", board[i][j]);
    }
    printf("\n");
  }
}
void Sweep(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count)
{
    int judge = 0;
  int x = 0;
  int y = 0;
  while (judge < row*col - count)
  {
    printf("请输入要扫除的坐标: \n");
    scanf("%d %d", &x, &y);
    if (x < 0 || y < 0 || x > row || y > col)
      printf("输入错误,小笨蛋~~\n");
    else if (show[x][y] != '*')
      printf("该坐标已被扫除了偶:\n");
     if(judge == 0)
      No_mine(mine, show, x, y, row, col);
     if (mine[x][y] != '1')
     {
       Spread(x, y, mine, show, row, col);
       Display(show, row, col);
     }
     else
     {
       printf("你被炸死了\n");
       break;
     }
     Stat_judge(show, &judge, row, col);
  }
  if (judge == row * col - count)
  {
    printf("恭喜你排雷成功\n");
  }
}
void No_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int row, int col)
{
  if (mine[i][j] == '1')
  {
    while (1)
    {
      int x = rand() % row + 1;
      int y = rand() % col + 1;
      if (mine[x][y] == '0')
      {
        mine[x][y] = '1';
        break;
      }
    }
    mine[i][j] = '0';
  }
}
int Count_Mine(int x, int y, char mine[ROWS][COLS])
{
  return mine[x - 1][y - 1]
    + mine[x - 1][y]
    + mine[x - 1][y + 1]
    + mine[x][y - 1]
    + mine[x][y + 1]
    + mine[x + 1][y - 1]
    + mine[x + 1][y]
    + mine[x + 1][y + 1] - 8 * '0';
}
void Spread(int x, int y, char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
  char count = Count_Mine(x, y, mine) + '0';
  if (count != '0')
    show[x][y] = count;
  else
  {
    show[x][y] = ' ';
    if (x - 1 > 0 && show[x - 1][y] == '*')
      Spread(x - 1, y, mine, show, row, col);
    if (y - 1 > 0 && show[x][y - 1] == '*')
      Spread(x, y - 1, mine, show, row, col);
    if (y + 1 < col + 1 && show[x][y + 1] == '*')
      Spread(x, y + 1, mine, show, row, col);
    if (x + 1 < row + 1 && show[x + 1][y] == '*')
      Spread(x + 1, y, mine, show, row, col);
  }
}
void Stat_judge(char show[ROWS][COLS], int* judge, int row, int col)
{
    *judge=0;
  int i = 0;
  int j = 0;
  for (i = 1; i < row + 1; i++)
  {
    for (j = 1; j < col + 1; j++)
    {
      if (show[i][j] != '*')
        (*judge)++;
    }
  }
}
void game()
{
  srand((unsigned long)time(NULL)); //生成随机数种子
  char mine[ROWS][COLS] = { 0 };
  char show[ROWS][COLS] = { 0 };
  Init_board(mine, ROWS, COLS, '0');//初始化雷盘
  Init_board(show, ROWS, COLS, '*');//初始化展示的雷盘
  Set_Mine(mine,ROW,COL,10);
  Sweep(mine,show,ROW,COL,10);
}
int main()
{
  choice();
  return 0;
}


🌺结束语


       本人不才,如有错误,欢迎各位大佬在评论区讨论。有帮助的话还请【关注点赞收藏】,不行的话我再努努力💪💪💪


相关文章
|
2月前
|
C语言
扫雷游戏(用C语言实现)
扫雷游戏(用C语言实现)
128 0
|
4月前
|
机器学习/深度学习 C语言
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
【8月更文挑战第5天】本篇文章用C语言采用多文件编写实现了一个基础的扫雷游戏(附源码),并讲解了关于函数递归的基础概念及其相对应的习题练习(附源码)
47 1
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
|
1月前
|
C语言 Windows
C语言课设项目之2048游戏源码
C语言课设项目之2048游戏源码,可作为课程设计项目参考,代码有详细的注释,另外编译可运行文件也已经打包,windows电脑双击即可运行效果
34 1
|
3月前
|
存储 安全 算法
C 语言——实现扫雷小游戏
本文介绍了使用二维数组创建棋盘并实现扫雷游戏的方法。首先,通过初始化数组创建一个9x9的棋盘,并添加行列标识以便操作。接着,利用随机数在棋盘上布置雷。最后,通过判断玩家输入的坐标来实现扫雷功能,包括显示雷的数量和处理游戏胜利或失败的情况。文中提供了完整的代码实现。
58 1
C 语言——实现扫雷小游戏
|
2月前
|
存储 算法 安全
C语言实现扫雷游戏
C语言实现扫雷游戏
|
2月前
|
C语言
初学者指南:使用C语言实现简易版扫雷游戏
初学者指南:使用C语言实现简易版扫雷游戏
46 0
|
2月前
|
C语言
C语言扫雷游戏(详解)
C语言扫雷游戏(详解)
45 0
|
2月前
|
存储 编译器 C语言
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
【C语言篇】数组和函数的实践:扫雷游戏(附源码)
42 0
|
4月前
|
C语言
扫雷(C语言)
扫雷(C语言)
51 4
|
5月前
|
存储 编译器 C语言