学会了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;
}


🌺结束语


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


相关文章
|
5天前
|
算法 C语言 C++
【C语言实战项目】三子棋游戏
【C语言实战项目】三子棋游戏
33 1
|
5天前
|
程序员 C语言
【C语言实战项目】猜数字游戏
【C语言实战项目】猜数字游戏
32 0
【C语言实战项目】猜数字游戏
|
5天前
|
C语言
C语言 扫雷详解
C语言 扫雷详解
|
5天前
|
C语言
C语言-------扫雷游戏的代码实现
C语言-------扫雷游戏的代码实现
29 0
|
5天前
|
算法 C语言 C++
【C语言-扫雷游戏全功能详解】
【C语言-扫雷游戏全功能详解】
40 1
|
3天前
|
C语言
C语言扫雷代码(蹦蹦炸弹)(下)
C语言扫雷代码(蹦蹦炸弹)(下)
4 0
|
3天前
|
存储 C语言
关于我在C语言中玩扫雷(上)
关于我在C语言中玩扫雷(上)
4 0
|
5天前
|
存储 算法 C语言
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
|
5天前
|
C语言
以c语言为基础实现的简易扫雷游戏(游戏代码附在文章最后,如有需要请自取)
以c语言为基础实现的简易扫雷游戏(游戏代码附在文章最后,如有需要请自取)
52 1
|
5天前
|
C语言
爱上C语言:扫雷小游戏,展开一片功能实现
爱上C语言:扫雷小游戏,展开一片功能实现
爱上C语言:扫雷小游戏,展开一片功能实现

相关实验场景

更多