自動尋找走出迷宮的最短路徑
阿新 • • 發佈:2019-01-26
演算法心得:
1.利用廣度優先遍歷(bfs)實現尋找最短路徑
2.利用樹的思想,將每走一步的終點與它的起點相連線,這樣就能在最後把整條最短路徑找出來
#include<stdio.h> #include<stdlib.h> #include<time.h> #include<windows.h> #define size 50 void set_map(); void print_map(); void set_startplace(); void set_endplace(); void color(const unsigned short color1); //void change(int x, int y, int dir); void gotoxy(int x, int y); void bfs(); void dfs(int x, int y, int step); void printline(int x, int y); void move(); void print_sentence(); void print_loose(); char ch[size][2*size] = { ' ' }; int start_x, start_y; int end_x, end_y; int sx, sy; int min = 9999; int book[size*size*2][2]; int mark[size][2*size] = { 0 }; int i = 1; //設定一個結構體,儲存座標 struct note { int x; int y; }que[size*size]; //儲存座標和連線指標 struct tree { int x; int y; struct tree *next; }*ans[size][2*size]; int main() { set_map(); print_map(); set_startplace(); set_endplace(); system("cls"); print_map(); bfs(); move(); system("pause"); } //設定地圖 void set_map() { int i = 1500, x, y; srand(time(0)); while (i>0) { x = rand() % size; y = rand() % (2*size); ch[x][y] = 6; i--; } } //列印地圖 void print_map() { int i, j; for (i = 0;i < size;i++) { for (j = 0;j < 2*size;j++) { if (i == sx && j == sy) { color(12); } if (i == end_x && j == end_y) { color(12); } else { color(10); } printf("%c", ch[i][j]); } printf("\n"); } } //設定起始位置 void set_startplace() { color(6); printf("請輸入起始位置\n"); scanf_s("%d%d", &start_x, &start_y); ch[start_x][start_y] = 12; sx = start_x; sy = start_y; } //設定終點 void set_endplace() { color(6); printf("請輸入終點位置\n"); scanf_s("%d%d", &end_x, &end_y); ch[end_x][end_y] = 3; } //控制命令臺輸出字型顏色函式 void color(const unsigned short color1) { if (color1 >= 0 && color1 <= 15) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color1); else SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7); } //廣度搜索和樹的結合 void bfs() { int next[4][2] = { { 0,1 },{ 1,0 },{ 0,-1 },{ -1,0 } }; int head, tail; int k, flag = 0, tx, ty; head = 1; tail = 1; que[tail].x = start_x; que[tail].y = start_y; mark[start_x][start_y] = 1; ans[start_x][start_y] = (struct tree*)malloc(sizeof(struct tree)); ans[start_x][start_y]->x = start_x; ans[start_x][start_y]->y = start_y; ans[start_x][start_y]->next = NULL; tail++; while (head < tail) { for (k = 0;k < 4;k++) { tx = que[head].x + next[k][0]; ty = que[head].y + next[k][1]; if (tx<0 || tx>size - 1 || ty <0 || ty > 2*size - 1) { continue; } if (ch[tx][ty] != 6 && ch[tx][ty] != 3 && mark[tx][ty] == 0) { que[tail].x = tx; que[tail].y = ty; mark[tx][ty] = 1; ans[tx][ty] = (struct tree*)malloc(sizeof(struct tree)); ans[tx][ty]->x = tx; ans[tx][ty]->y = ty; ans[tx][ty]->next = ans[que[head].x][que[head].y]; tail++; } if (tx == end_x && ty == end_y) { flag = 1; ans[tx][ty] = (struct tree*)malloc(sizeof(struct tree)); ans[tx][ty]->x = tx; ans[tx][ty]->y = ty; ans[tx][ty]->next = ans[que[head].x][que[head].y]; break; } } if (flag == 1) { printline(tx, ty); break; } head++; } if (flag == 0) { print_loose(); } } //儲存路線 void printline(int x, int y) { struct tree *p; p = ans[x][y]; while (p != NULL) { book[i][0] = p->x; book[i][1] = p->y; //printf("%d %d\n", p->x, p->y); p = p->next; i++; } } //移動函式 void move() { char c = 12; //char m=7; int k; int num = 1; gotoxy(start_y, start_x); color(6); printf("*"); gotoxy(book[i][1], book[i][0]); color(12); printf("%c", c); for (k = i;k >= 2;k--) { gotoxy(book[k][1], book[k][0]); color(6); printf("*"); gotoxy(book[k - 1][1], book[k - 1][0]); color(12); printf("%c", c); gotoxy(size-2, size+1); printf("Coordinate(%d,%d)", book[k][0], book[k][1]); gotoxy(size - 2, size + 2); printf("Step number %d", num); num++; Sleep(200); } print_sentence(); }
//這是移動游標的函式 void gotoxy(int x, int y) { COORD coord = { x, y }; /*COORD是Windows API中定義的一種結構,表示一個字元在控制檯螢幕上的座標。其定義為: typedef struct _COORD { SHORT X; // horizontal coordinate SHORT Y; // vertical coordinate } COORD;*/ SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } //結束語 void print_sentence() { int s; system("cls"); color(12); gotoxy(size, size / 2); printf("恭喜你走出了迷宮\n"); Sleep(2000); system("cls"); gotoxy(size, size / 2); printf("你以為就這樣結束了?"); Sleep(2000); system("cls"); gotoxy(size, size / 2); printf("接下來有請陸銘坤給我們演示我們的打地鼠小遊戲!!"); gotoxy(size, size); } void print_loose() { /* int s; system("cls"); color(12); for (s = 1;s<10;s++) { printf("\n"); } for (s = 1;s<16;s++) { printf(" "); } */ system("cls"); gotoxy(size, size / 2); printf("對不起,你這個迷宮打死我也走不出來!!\n"); }