C语言经典项目之二——扫雷

来源:互联网 发布:浪漫主义文学 知乎 编辑:程序博客网 时间:2024/06/09 18:25

扫雷是一款家喻户晓的windows自带游戏,为了提高初学者学习兴趣,扫雷也是一个经典的C语言项目,今天就给大家分享一下。

我这个版本提供了可展开,第一次不会被炸死的功能。

game.h----------#define _CRT_SECURE_NO_WARNINGS 1#ifndef __Mine_Clearance__  #define __Mine_Clearance__  #include  <stdio.h>  #include  <stdlib.h>  #include  <time.h>  #define M  10//定义炸弹数量  #define ROW 10//定义棋盘大小 #define COL 10  void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL]);//声明game.c中的函数。  void displayboard(char show[ROW][COL]);  void displaymine(char mine[ROW][COL]);  void Set_Mine(char mine[ROW][COL],  int m);  void sweep_Mine(char mine[ROW][COL], char show[ROW][COL],   int x, int y);  int check_win(char mine[ROW][COL], char show[ROW][COL], int m );  void prevent_first_death(char mine[ROW][COL], int x, int y);  int mineNum(char mine[ROW][COL], int x, int y);  void spread(char mine[ROW][COL], char show[ROW][COL], const x, const y);  #endif  
game.c----------#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"  void init(char mine[ROW][COL], char show[ROW][COL], char spread[ROW][COL])//初始化棋盘  {      int i = 0;     int j = 0;      for (i = 0; i < ROW-1 ; i++)//初始化9*9棋盘      {          for (j = 0; j < COL-1; j++)                         {              mine[i][j] = ' ';                             show[i][j] = '*';          }      }  }  void displayboard(char show[ROW][COL])//打印9*9棋盘  {      int i, j;      printf("  |");      for (i = 1; i < ROW; i++)      {          printf("%d ", i);      }      printf("\n—|——————————\n");      for (i = 0; i < ROW-1; i++)      {          printf("%2d|", i + 1);          for (j = 0; j < COL-1; j++)          {              printf("%c ",show[i][j]);          }          printf("\n");      }  }  void displaymine(char mine[ROW][COL])                //展示雷盘 测试时使用 {      int i, j;      printf("  |");      for (i = 1; i <= 10; i++)      {          printf("%d ", i);      }      printf("\n--|--------------------\n");      for (i = 0; i < ROW-1; i++)      {          printf("%2d|", i + 1);          for (j = 0; j < COL-1; j++)          {              printf("%c ", mine[i][j]);          }          printf("\n");      }  }  void  Set_Mine(char mine[ROW][COL], int m) //随机放置雷,可以通过在头文件中修改 M 的值从而修改 m 的大小 改变布置的雷数  {      int x, y;      while(m)      {          x = rand() % 10 + 0;          y = rand() % 10 + 0;          if (mine[x][y] == ' ')          {                 mine[x][y] = '$';              m--;          }      }      m = M;  }  int mineNum(char mine[ROW][COL], int x, int y)  //统计周边8个格子的雷数{      int count = 0;      if (mine[x - 1][y - 1] == '$')      {          count++;      }      if (mine[x - 1][y] == '$')      {          count++;      }      if (mine[x - 1][y + 1] == '$')      {          count++;      }      if (mine[x][y + 1] == '$')      {          count++;      }      if (mine[x + 1][y + 1] == '$')      {          count++;      }      if (mine[x + 1][y] == '$')      {          count++;      }      if (mine[x + 1][y - 1] == '$')      {          count++;      }      if (mine[x][y - 1] == '$')      {          count++;      }      return count;  }  void spread(char mine[ROW][COL], char show[ROW][COL], const x, const y)   //展开函数  {      int ret = 0;    int i = 0;    int j = 0;                                                           int a = x;    int b = y;     if (   (x >= 0)                                               && (x <= 9)          && (y >= 0)                                                             && (y <= 9))      {          if (mine[x - 1][y - 1] == ' ')                        //如果该区域不是雷          {              a = x - 1;              b = y - 1;              ret = mineNum(mine, a, b);                     //返回以该区域为中心雷的数量             if (ret == 0)                                 //若在这八个区域中哪个区域的周围8个格子无雷              {                  show[a][b] = ' ';                        //如果周围没有雷就向玩家展示‘ ’空格                  mine[a][b] = '0';                        //将雷盘中的区域改为‘0’可方便测试用                  spread(mine, show, a, b);              //则将这个区域的坐标赋值给x和y,再次进行展开              }              else              {                  show[a][b] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x][y - 1] == ' ')                                //以下的另外七个区域同理          {              a = x;              b = y - 1;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[a][b] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[a][b] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x - 1][y] == ' ')          {              a = x - 1;              b = y;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[a][b] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[a][b] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x + 1][y - 1] == ' ')          {              a = x + 1;              b = y - 1;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[a][b] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[a][b] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x + 1][y] == ' ')          {              a = x + 1;              b = y;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[x + 1][y] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[x + 1][y] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x + 1][y + 1] == ' ')          {              a = x + 1;              b = y + 1;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[x + 1][y + 1] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[x + 1][y + 1] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x][y + 1] == ' ')          {              a = x;              b = y + 1;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[x][y + 1] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[x][y + 1] = '0' + ret;                  mine[a][b] = '0';              }          }          if (mine[x - 1][y + 1] == ' ')          {              a = x - 1;              b = y + 1;              ret = mineNum(mine, a, b);              if (ret == 0)              {                  show[x - 1][y + 1] = ' ';                  mine[a][b] = '0';                  spread(mine, show, a, b);              }              else              {                  show[x - 1][y + 1] = '0' + ret;                  mine[a][b] = '0';              }          }      }  }  void sweep_Mine(char mine[ROW][COL], char show[ROW][COL],   int x, int y)   //扫雷函数  {      int ret = 0;      if ( mine[x][y] == ' ')      //玩家没有踩到雷,即展示该区域周边的雷数,如果雷数为0就显示空格      {          ret=mineNum(mine, x, y);          if (ret == 0)          {              show[x][y] = ' ';          }          else          {              show[x][y] = '0' + ret;                           //如果有炸弹就显示炸弹的数量         }          spread(mine, show, x, y);                      //并在此调用展开函数,对周边区域进行展开     }      else if(mine[x][y] == '$')      {          show[x][y] = mine[x][y];                             //如果玩家踩到炸弹就显示$    }  }  void prevent_first_death(char mine[ROW][COL],int x,int y)      //防止玩家第一次被炸死  {      int m = 0;    int n = 0;      if(mine[x][y] == '$')      {          do           {              m = rand() % 11 + 0;              n = rand() % 11 + 0;                  //如果玩家踩到雷,就重新随机一个没有雷的地方,将炸弹移动到那里              if (mine[m][n] == ' ')              {                  mine[x][y] = ' ';             //将该区域设置为空格                mine[m][n] = '$';                  break;              }          }         while (1);      }  }  int check_win(char mine[ROW][COL], char show[ROW][COL], int m )  //判断输赢  {      int i, j,num;      num = M;      for (i = 0; i < ROW; i++)      {          for (j = 0; j < COL;j++)          {              if (show[i][j]=='*')                //如果在展示棋盘上剩余 ‘*’的数量和雷数相同,那么就表示扫雷成功                  {                  num--;              }              else if (show[i][j] == '$')         //如果显示盘上出现了 ‘$’说明玩家踩到了雷            {                  return 1;              }            else if(num == 0)              {                  return 0;             }        }    }    return -1;}
test.c----------#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"  void mune()       {      printf("******************************************************************\n");      printf("————————1.开始扫雷——————0.退出游戏—————————\n");      printf("******************************************************************\n");  }  void game()                                           {       char mine[ROW][COL];      char show[ROW][COL] ;      char spread[ROW][COL];      int x, y,m;      int row, col;      int count=0;      int ret;      row = ROW;      col = COL;      m = M;//将定义中的雷数M赋值给m      init(mine, show, spread);       Set_Mine(mine, m);      //displaymine(mine);//在测试中显示雷      do      {          displayboard(show);          count++;         printf("————————————————");        printf("开始扫雷>:");          scanf("%d %d", &x, &y);          getchar();          x = x - 1;          y = y - 1;          if (count == 1)          {              prevent_first_death(mine, x, y);          }           sweep_Mine(mine, show, x, y);          ret=check_win(mine,show,m);          if(ret == 1)          {              displayboard(show);             printf("————————————————");            printf("踩到炸弹 GG \n\n");              break;          }          else if(ret == 0)          {              displayboard(show);             printf("————————————————");            printf("扫雷成功!\n\n ");              break;          }      } while (1);  }  int main()                       {      int n = 0;      do      {          mune();        printf("——请选择:");        scanf("%d",&n);          printf("—————————————————————————————————\n");        getchar();          if(n == 1)          {              game();          }          else if(n == 0)          {              break;          }          else          {              printf("输入有误 重新输入\n");        }    } while (1);      return 0;  }  

欢迎批评指正!