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("\n");
 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("\n");
 66     }    
 67     printf("\n总共%d个地雷\n",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("恭喜你,扫雷成功!!!\n");
213         else
214             printf("可惜,扫雷失败!\n");
215         printf("输入1重开游戏,输入其他任意数字退出游戏:");
216         scanf_s("%d",&isAgain);
217         if (isAgain == 1)
218         {
219             system("cls");
220             main();
221         }
222 }

 

运行结果


 

 

 

 

posted @ 2020-05-31 18:16  何必胜  阅读(5006)  评论(0编辑  收藏  举报