曾經用C語言做過的動態走迷宮程式,先分享程式碼如下:
程式碼如下:
1 //標頭檔案 2 #include<stdio.h> 3 #include<windows.h>//Sleep(500)函式呼叫此標頭檔案 4 #include<conio.h>//getch()函式呼叫此標頭檔案 5 #include<stdlib.h>//system("cls")函式呼叫此標頭檔案 6 7 //函式狀態碼定義 8 /******************************/ 9 #define TRUE 1 10 #define FALSE 0 11 #define OK 1 12 #define ERROR 0 13 #define INFEASIBLE -1 14 #define OVERFLOW -2 15 typedef int Status; 16 #define STACK_INIT_SIZE 100 17 #define STACKINCREMENT 10 18 #define Pass 0 //可通過 19 #define Wall 1 //牆 20 #define Start 6 //起點 21 #define End 7 //終點 22 #define Back 8 //返回 23 #define Exit 9 //出口:找到終點後標誌出來 24 /******************************/ 25 26 //自定義資料型別 27 /***************************************************/ 28 29 //自定義列舉型別 30 enum direction{East=2,South,West,North};//2,3,4,5分別代表東、南、西、北 31 /*+------------------------ 32 使用列舉型別來表示方向 33 該列舉型別定義的變數只能取值 East,West,South,North 34 且East=2,South=3,West=4,North=5 35 本原始碼上面使用列舉型別,基本等效於下面 36 #define East 2 37 #define South 3 38 #define West 4 39 #define North 5 40 +------------------------*/ 41 42 //自定義座標結構體 43 typedef struct //迷宮x行,y列 44 { 45 int x; 46 int y; 47 }Position;//座標結構體 48 49 //二維陣列構造迷宮,1代表牆,0代表可通過。 50 int Map[10][10]={ 51 {1,6,1,1,1,1,1,1,1,1}, 52 {1,0,0,1,0,0,0,1,0,1}, 53 {1,0,0,1,0,0,0,1,0,1}, 54 {1,0,0,0,0,1,1,0,0,1}, 55 {1,0,1,1,1,0,0,0,0,1}, 56 {1,0,0,0,1,0,0,0,0,1}, 57 {1,0,1,0,0,0,1,0,0,1}, 58 {1,0,1,1,1,0,1,1,0,1}, 59 {1,1,0,0,0,0,0,0,0,7}, 60 {1,1,1,1,1,1,1,1,1,1} 61 }; 62 63 //自定義結構體作為中間變數儲存當前臨時座標資訊 64 typedef struct 65 { 66 int number;//記錄是第幾步 67 Position seat;//通道塊在迷宮中的"位置座標" 68 enum direction direc; 69 //direction為列舉型別,用來表示從此通道走向下一通道的方向 70 //direc只能取值 East,West,South,North 71 //且East=2,South=3,West=4,North=5 72 }SElemType; 73 74 //自定義棧結構便於將上面結構體的臨時座標資訊放到棧記憶體儲 75 typedef struct { 76 SElemType *base; 77 SElemType *top; 78 int stacksize; 79 }SqStack;//棧 80 /*********************************************/ 81 82 //函式宣告 83 /******************************************/ 84 85 void Welcome();//歡迎介面函式 86 void printfMap();//列印迷宮函式 87 Status findPath(SqStack &S,Position start,Position end);//迷宮尋路徑函式 88 Status InitStack(SqStack &S);//初始化棧 89 Status StackEmpty(SqStack S);//判斷棧是否為空 90 Status Push(SqStack &S,SElemType e);//入棧 91 Status Pop(SqStack &S,SElemType &e);//出棧 92 enum direction Judge_direc(Position pos);//根據一個座標探索周圍座標返回可通行的座標 93 Position change_seat(Position &pos,enum direction direc);//根據方向移動到下一個可通行的座標處 94 Status change_Map(int mapid); 95 96 /****************主函式開始***********************/ 97 98 //主函式 99 int main() 100 { 101 Position start,end; 102 int n; 103 SqStack S; 104 InitStack(S);//初始化棧 105 Welcome();//呼叫歡迎介面函式 106 start.x=0;//0 107 start.y=1;//1 108 printf("請選擇地圖:\n\n"); 109 change_Map(0); 110 printf("\t\t預設地圖0\n\n"); 111 printfMap(); 112 change_Map(1); 113 printf("\t\t備選地圖1\n\n"); 114 printfMap(); 115 printf("選擇預設地圖請輸入0,備選地圖請輸入1:\n"); 116 printf("您的選擇:"); 117 scanf("%d",&n); 118 system("cls"); 119 switch(n) 120 { 121 case 0: 122 { 123 change_Map(0);printf("初始迷宮如下所示:\n\n"); 124 end.x=8;end.y=9; 125 printfMap(); 126 printf("按任意鍵繼續!"); 127 getch(); 128 system("cls"); 129 break; 130 } 131 case 1: 132 { 133 change_Map(1);printf("初始迷宮如下所示:\n\n"); 134 end.x=0; 135 end.y=8; 136 printfMap(); 137 printf("按任意鍵繼續!"); 138 getch(); 139 system("cls"); 140 break; 141 } 142 } 143 findPath(S,start,end); 144 printf("\n\n按下任意鍵退出系統!\n"); 145 getch(); 146 147 return 0; 148 } 149 /***************主函式結束***********************/ 150 //列印迷宮 151 void printfMap() 152 { 153 int i,j; 154 for(i=0;i<10;i++) 155 { 156 printf("\t"); 157 for(j=0;j<10;j++) 158 switch(Map[i][j]){ 159 case Pass:printf("□");break;//可通過0 160 case Wall:printf("■");break;//牆1 161 case East:printf("→");break;//東2 162 case South:printf("↓"); break;//南3 163 case West:printf("←");break;//西4 164 case North:printf("↑");break;//北5 165 case Start:printf("⊙");break;//起點6 166 case End:printf("◎");break;//終點7 167 case Back:printf("Θ");break;//返回8 168 case Exit:printf("To");break;//出口9 169 } 170 printf("\n"); 171 } 172 printf("\n"); 173 } 174 175 //走迷宮 176 Status findPath(SqStack &S,Position start,Position end){ 177 Position curpos;//當前座標 178 SElemType elem;//路徑相關資訊結構體 179 int step=1;//記錄步驟數 180 curpos=start;//開始座標 181 while(1){ 182 if(curpos.x==start.x&&curpos.y==start.y)//此段程式碼只執行一次 183 { 184 elem.number=1; 185 elem.direc=Judge_direc(curpos);//判斷下一個位置是什麼方向 186 elem.seat=curpos; 187 step++; 188 Push(S,elem);//第一個起點無條件入棧 189 } 190 191 Map[curpos.x][curpos.y]=(int)elem.direc;//鎖定當前位置 192 curpos=change_seat(curpos,elem.direc);//移動到下一個位置,根據方向改變座標位置 193 if(Map[curpos.x][curpos.y]==End)//找到終點,退出迴圈 194 { 195 elem.seat=curpos; 196 elem.number=step; 197 Push(S,elem); 198 Map[curpos.x][curpos.y]=Exit; 199 system("cls"); 200 printf("\n"); 201 printfMap(); 202 printf("\n\t恭喜您,迷宮路徑已經找到!\n\n"); 203 printf("路徑座標為:\n\n"); 204 while(!StackEmpty(S)) 205 { 206 Pop(S,elem);//出棧 207 curpos=elem.seat; 208 printf("(%d,%d)\t",curpos.x,curpos.y); 209 } 210 break; 211 } 212 if(Map[curpos.x][curpos.y]==Pass)//如果當前路可通 213 { 214 elem.number=step; 215 elem.seat=curpos; 216 elem.direc=Judge_direc(curpos); 217 Push(S,elem);//將當前座標入棧 218 step++; 219 } 220 else//如果當前位置不通 221 { 222 Pop(S,elem); 223 curpos=elem.seat; 224 step=elem.number-1; 225 Map[curpos.x][curpos.y]=Back;//表示四個都不通,標記走過了 226 do 227 { 228 Pop(S,elem);//出棧 229 curpos=elem.seat; 230 /************while迴圈開始*****************/ 231 while(elem.direc<=4) 232 { 233 elem.direc=(enum direction)(elem.direc+1); 234 curpos=change_seat(curpos,elem.direc);//移動到下一個位置,根據方向改變座標位置 235 if(Map[curpos.x][curpos.y]==Pass) 236 { 237 break; 238 } 239 }; 240 /************while迴圈結束*****************/ 241 if(Map[curpos.x][curpos.y]==Pass) 242 { 243 curpos=elem.seat; 244 elem.number=step; 245 elem.seat=curpos; 246 Push(S,elem); 247 step++; 248 break; 249 } 250 else 251 { 252 curpos=elem.seat; 253 Map[curpos.x][curpos.y]=Back; 254 } 255 printf("正在遍歷查詢...\n\n"); 256 printfMap(); 257 Sleep(1000); 258 system("cls"); 259 }while(!StackEmpty(S));//直到棧為空跳出迴圈 260 } 261 printf("正在遍歷查詢...\n\n"); 262 printfMap(); 263 Sleep(1000); 264 system("cls"); 265 } 266 return OK; 267 } 268 269 //改變座標 270 Position change_seat(Position &pos,enum direction direc){ 271 switch(direc) 272 { 273 case East: pos.y=pos.y+1;break;//2 274 case South: pos.x=pos.x+1;break;//3 275 case West: pos.y=pos.y-1;break;//4 276 case North: pos.x=pos.x-1;break;//5 277 } 278 return pos; 279 } 280 //判斷下一個位置方向 281 enum direction Judge_direc(Position pos) 282 { 283 enum direction judge; 284 if(Map[pos.x][pos.y+1]==Pass||Map[pos.x][pos.y+1]==End) 285 judge=East; 286 else 287 { 288 if(Map[pos.x+1][pos.y]==Pass||Map[pos.x+1][pos.y]==End) 289 judge=South; 290 else 291 { 292 if(Map[pos.x][pos.y-1]==Pass||Map[pos.x][pos.y-1]==End) 293 judge=West; 294 else 295 { 296 if(Map[pos.x-1][pos.y]==Pass||Map[pos.x-1][pos.y]==End) 297 judge=North; 298 } 299 } 300 } 301 return judge; 302 } 303 304 Status change_Map(int mapid) 305 { 306 if(mapid==0)//預設地圖 307 { 308 Map[0][8]=Wall; 309 Map[8][9]=End; 310 } 311 if(mapid==1)//其他地圖 312 { 313 Map[8][9]=Wall; 314 Map[0][8]=End; 315 } 316 return OK; 317 } 318 319 //初始化棧 320 Status InitStack(SqStack &S){ 321 S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); 322 if(!S.base)exit(OVERFLOW); 323 S.top=S.base; 324 S.stacksize=STACK_INIT_SIZE; 325 return OK; 326 } 327 328 //判斷棧是否為空 329 Status StackEmpty(SqStack S){ 330 if(S.top==S.base) 331 return TRUE; 332 else 333 return FALSE; 334 } 335 //入棧 336 Status Push(SqStack &S,SElemType e){ 337 if(S.top-S.base>=S.stacksize){ 338 S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType)); 339 if(!S.base)exit(OVERFLOW); 340 S.top=S.base+S.stacksize; 341 S.base+=STACKINCREMENT; 342 } 343 *S.top++=e; 344 return OK; 345 } 346 347 //出棧 348 Status Pop(SqStack &S,SElemType &e){ 349 if(S.top==S.base)return ERROR; 350 e=*--S.top; 351 return OK; 352 } 353 //去棧頂元素 354 Status GetTop(SqStack S,SElemType &e){ 355 356 if(S.top==S.base)return ERROR; 357 358 e=*(S.top-1); //注意top指向待插入位置 359 360 return OK; 361 362 } 363 364 //歡迎介面函式 365 void Welcome(){ 366 system("title 迷宮求解程式");//設定視窗標題 367 system("mode con cols=80 lines=40"); //視窗寬度高度 368 system("color a");//設定文字顏色,所在標頭檔案 369 printf("★**************************************************************★\n"); 370 printf("★ ★\n"); 371 printf("★ 歡迎使用迷宮求解程式 ★\n"); 372 printf("★ ★\n"); 373 printf("★ 檔名稱:資料結構期末實驗 ★\n"); 374 printf("★ ★\n"); 375 printf("★ 專案名稱:迷宮求解程式 ★\n"); 376 printf("★ ★\n"); 377 printf("★ 建立時間:2014-11-28 ★\n"); 378 printf("★ ★\n"); 379 printf("★ 最後修改時間:2014-12-2 ★\n"); 380 printf("★ ★\n"); 381 printf("★**************************************************************★\n"); 382 printf("按任意鍵繼續!\n"); 383 getch();//暫停函式,所在標頭檔案<conio.h> 384 system("cls");//清屏函式 385 }