• c++实现扫雷游戏


    设计思路


      定义一个结构体,里面存放每一个格子是否被翻开,已经地雷和格子周围地雷数量。用结构体定义一个二维数组,随机放入特定数量的地雷。玩家输入要翻开的格子的行数和列数。用一个函数来翻开目标格子,如果是地雷游戏失败,否则用一个函数统计目标格子周围的地雷数。如果周围没有地雷,则递归使用一个函数将附近周围没有地雷的格子全部打开,最后判断是否游戏胜利,没有就继续让玩家输入行数和列数。

    代码实现


      1 #include<stdio.h>
      2 #include<stdlib.h>
      3 #include<time.h>
      4 
      5 #define HEIGHT 10    //定义地图高度
      6 #define WIDHT 10    //定义地图宽度
      7 #define BOON_NUM 10    //定义地雷数量
      8 
      9 struct square
     10 {
     11     bool isOpen;    //定义是否被翻开
     12     int groundBoon;    //定义格子周围的地雷数量,值为-1时代表本格就是地雷
     13 };
     14 square map[HEIGHT][WIDHT];    //定义地图
     15 
     16 //地图初始化
     17 void csh()
     18 {
     19     int *p;
     20     //地图初始化
     21     for (int i = 0;i < HEIGHT;i++)
     22         for (int j = 0;j < WIDHT;j++)
     23         {
     24             map[i][j].groundBoon = 0;
     25             map[i][j].isOpen = false;
     26         }
     27             
     28     //随机地雷
     29     srand(time(NULL));
     30     p = &map[rand() % HEIGHT][rand() % WIDHT].groundBoon;
     31     *p = -1;
     32     for(int i=0;i<BOON_NUM-1;i++)
     33     {
     34         while (*p == -1)
     35         {
     36             p = &map[rand() % HEIGHT][rand() % WIDHT].groundBoon;
     37         }
     38     *p = -1;
     39     }
     40     
     41 }
     42 
     43 //输出地图
     44 void sc()
     45 {    
     46     printf("  ");
     47     for (int i = 0;i < WIDHT;i++)
     48         printf("%d ",i);
     49     printf("
    ");
     50     for (int i = 0;i < HEIGHT;i++)
     51     {    
     52         printf("%d ",i);
     53         for (int j = 0;j < WIDHT;j++)
     54         {            
     55             if (map[i][j].isOpen)
     56                 if (map[i][j].groundBoon==-1)
     57                     printf("* ");
     58                 else if (map[i][j].groundBoon == 0)
     59                     printf("  ");
     60                 else
     61                     printf("%d ", map[i][j].groundBoon);
     62             else
     63                 printf("@ ");
     64         }
     65         printf("
    ");
     66     }    
     67     printf("
    总共%d个地雷
    ",BOON_NUM);
     68 }
     69 //大面积翻开周围没有雷的方块
     70 void bigOpen(int openH, int openW)
     71 {
     72     int temp;    
     73     int ground(int openH, int openW);    //定义判断周围地雷数量的函数
     74     
     75     map[openH][openW].groundBoon = 0;    
     76     map[openH][openW].isOpen = true;
     77 
     78     if (openH - 1 >= 0 && openW - 1 >= 0&&map[openH - 1][openW - 1].isOpen == false)
     79     {
     80         temp = ground(openH-1, openW-1);
     81         map[openH - 1][openW - 1].groundBoon = temp;
     82         map[openH - 1][openW - 1].isOpen = true;
     83     }
     84     if (openH - 1 >= 0 && map[openH - 1][openW].isOpen == false)
     85     {
     86         temp = ground(openH-1, openW);
     87         map[openH - 1][openW].groundBoon = temp;
     88         map[openH - 1][openW].isOpen = true;
     89     }
     90     if (openH - 1 >= 0 && openW + 1 < WIDHT && map[openH - 1][openW + 1].isOpen == false)
     91     {
     92         temp = ground(openH-1, openW+1);
     93         map[openH - 1][openW + 1].groundBoon = temp;
     94         map[openH - 1][openW + 1].isOpen = true;
     95     }
     96     if (openW - 1 >= 0 && map[openH][openW - 1].isOpen == false)
     97     {
     98         temp = ground(openH, openW-1);
     99         map[openH][openW - 1].groundBoon = temp;
    100         map[openH][openW - 1].isOpen = true;
    101     }
    102     if (openW + 1 < WIDHT && map[openH][openW + 1].isOpen == false)
    103     {
    104         temp = ground(openH, openW+1);
    105         map[openH][openW + 1].groundBoon = temp;
    106         map[openH][openW + 1].isOpen = true;
    107     }
    108     if (openH + 1 < HEIGHT && openW - 1 >= 0 && map[openH + 1][openW - 1].isOpen == false)
    109     {
    110         temp = ground(openH+1, openW-1);
    111         map[openH + 1][openW - 1].groundBoon = temp;
    112         map[openH + 1][openW - 1].isOpen = true;
    113     }
    114     if (openH + 1 < HEIGHT && map[openH + 1][openW].isOpen == false)
    115     {
    116         temp = ground(openH+1, openW);
    117         map[openH + 1][openW].groundBoon = temp;
    118         map[openH + 1][openW].isOpen = true;
    119     }
    120     if (openH + 1 < HEIGHT && openW + 1 < WIDHT && map[openH + 1][openW + 1].isOpen == false)
    121     {
    122         temp = ground(openH+1, openW+1);
    123         map[openH + 1][openW + 1].groundBoon = temp;
    124         map[openH + 1][openW + 1].isOpen = true;
    125     }
    126 }
    127 //查找周围地雷数量
    128 int ground(int openH, int openW)
    129 {
    130     int sum = 0;    //用以累计周围地雷数量
    131 
    132     if (openH - 1 >= 0 && openW - 1 >= 0 && map[openH - 1][openW - 1].groundBoon == -1)
    133         sum++;
    134     if (openH - 1 >= 0 && map[openH - 1][openW].groundBoon == -1)
    135         sum++;
    136     if (openH - 1 >= 0 && openW + 1 < WIDHT && map[openH - 1][openW + 1].groundBoon == -1)
    137         sum++;
    138     if ( openW - 1 >= 0 && map[openH ][openW - 1].groundBoon == -1)
    139         sum++;
    140     if (openW + 1 < WIDHT && map[openH][openW +1].groundBoon == -1)
    141         sum++;
    142     if (openH + 1 < HEIGHT && openW - 1 >= 0 && map[openH +1][openW - 1].groundBoon == -1)
    143         sum++;
    144     if (openH + 1 < HEIGHT  && map[openH+  1][openW ].groundBoon == -1)
    145         sum++;
    146     if (openH +1 < HEIGHT && openW + 1 < WIDHT && map[openH + 1][openW + 1].groundBoon == -1)
    147         sum++;
    148     if (sum == 0)    //如果周围没有雷,则大面积翻开周围的同样周围没雷的方块
    149         bigOpen(openH, openW);
    150     return sum;
    151 }
    152 //翻开指定方块 
    153 bool open(int openH,int openW)
    154 {
    155     if (map[openH][openW].isOpen)    //如果翻开重复的方块则返回0
    156         return false;
    157     if (map[openH][openW].groundBoon == -1)    //如果翻开地雷游戏结束
    158         return true;
    159 
    160     map[openH][openW].groundBoon=ground(openH, openW);
    161     map[openH][openW].isOpen = true;    
    162     return false;
    163 }
    164 //游戏结束画面
    165 void end()
    166 {
    167     for (int i = 0;i < HEIGHT;i++)
    168         for (int j = 0;j < WIDHT;j++)
    169             if (map[i][j].groundBoon == -1)
    170                 map[i][j].isOpen = true;
    171     sc();
    172 }
    173 //判断是否胜利
    174 bool win()
    175 {
    176     for (int i = 0;i < HEIGHT;i++)
    177         for (int j = 0;j < WIDHT;j++)
    178             if (!map[i][j].isOpen && map[i][j].groundBoon != -1)    //只要找到没翻开的并且不是地雷的方块就没胜利
    179                 return false;
    180     return true;
    181 }
    182 void main()
    183 {
    184     bool isEnd=false,isWin=false;    //定义游戏结束条件和胜利条件
    185     int openH, openW;    //定义要打开的行数和列数
    186     int isAgain;    //定义结束后是否重开游戏
    187 
    188     csh();
    189     while(!isEnd&&!isWin)
    190     { 
    191         sc();
    192         printf("请输入要打开的格子行数:");
    193         scanf_s("%d",&openH);
    194         while (openH<0||openH>HEIGHT)    //如果输入数字不正确则循环重新输入
    195         {
    196             printf("请输入正确的行数:");
    197             scanf_s("%d", &openH);
    198         }
    199         printf("请输入要打开的格子列数:");
    200         scanf_s("%d", &openW);
    201         while (openW<0 || openW>HEIGHT)    //如果输入数字不正确则循环重新输入
    202         {
    203             printf("请输入正确的列数:");
    204             scanf_s("%d", &openW);
    205         }
    206         isEnd=open(openH,openW);
    207         isWin = win();        
    208         system("cls");
    209     }
    210         end();
    211         if (isWin)
    212             printf("恭喜你,扫雷成功!!!
    ");
    213         else
    214             printf("可惜,扫雷失败!
    ");
    215         printf("输入1重开游戏,输入其他任意数字退出游戏:");
    216         scanf_s("%d",&isAgain);
    217         if (isAgain == 1)
    218         {
    219             system("cls");
    220             main();
    221         }
    222 }

    运行结果


  • 相关阅读:
    《摄像头 —— MIPI CSI2简介》
    《notepad++批量在任意行以及任意位置添加相同字符》
    《摄像头 —— sensor移植以及调试》
    条款18:让接口容易被正确使用,不易被误用
    条款20:宁以 passbyreferencetoconst 替换 passbyvalue
    第13章 运行时类型信息
    两个MATLAB函数dir2par和cplxcomp
    业务连续性计划
    语音识别之——音频特征fbank与mfcc,代码实现与分析
    在logo上面实现类似闪电的动画效果
  • 原文地址:https://www.cnblogs.com/hbsblog/p/13020359.html
Copyright © 2020-2023  润新知