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 }

 

運行結果


 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM