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