設計思路
定義一個結構體,里面存放每一個格子是否被翻開,已經地雷和格子周圍地雷數量。用結構體定義一個二維數組,隨機放入特定數量的地雷。玩家輸入要翻開的格子的行數和列數。用一個函數來翻開目標格子,如果是地雷游戲失敗,否則用一個函數統計目標格子周圍的地雷數。如果周圍沒有地雷,則遞歸使用一個函數將附近周圍沒有地雷的格子全部打開,最后判斷是否游戲勝利,沒有就繼續讓玩家輸入行數和列數。
代碼實現
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 }
運行結果



