[C] 老鼠走迷宫(使用回圈+堆叠)

来源:互联网 发布:大数据舆情开源 编辑:程序博客网 时间:2024/05/23 12:33

这是最近看到的一个小题目,以C语言来实作练练手。


题目叙述:

设计一个程式,读入文件中的迷宫地图数据,然后利用回圈或递回函数在迷宫中行进。

并且使用堆叠(同堆、stack)记录走过的分岔路口座标,以便走到死路时可从堆中取出分岔路口座标來返回分岔路口。

最后将找到的那条从入口到出口的行进路径输出到一个文件中。


输出行进路径举例:

右, 右, 下, 下, 下, Push(5,4), 下, 下, 遇到死路, (5,4)= Pop(), 右, 右, 右, Push(5,7), 下, 下, ...


输入档案格式:
1)第一列有两个数字m、n,代表地图的大小。
2)接下来有 m * n 个以空格或断行分隔的数字,其值为 0 或 1。(注意:每一列储存n个数字,档案中总共会有 m * n 个数字来标示地图)
3)地图由 m * n 个位置组成,数值0 表示可走之位置,1 表示不可走之位置。
4)入口为 字母M,出口为 字母O。
5)如果无法走到出口请印出“无法离开”讯息。



Input:

input_map.txt 內容

10 10M 1 1 1 1 1 1 1 1 10 0 0 0 1 0 0 1 1 01 0 1 0 0 0 1 1 0 00 0 1 1 0 1 0 1 1 01 0 0 1 0 0 0 0 0 01 1 0 1 1 0 1 1 1 11 1 0 0 1 1 1 1 0 11 0 0 0 0 1 0 0 1 10 0 1 1 0 0 0 0 0 00 1 1 1 1 1 1 1 1 O



Output:

下, 右, Push(2,2), 下, 下, Push(4,2), 左, 遇到死路, (4,2) = Pop(), 下, 右, 下, 下, Push(7,3), 下, Push(8,3), 左, 下, 左, 下, 遇到死路, (8,3) = Pop(), 右, Push(8,4), 上, 遇到死路, (8,4) = Pop(), 右, 下, 右, 右, Push(9,7), 上, 右, 下, 右, 右, 下, 到達


以下是簡陋的流程圖:






以下给出实作代码:

#include <stdio.h>#include <windows.h>#define FILE_MAP "input_map.txt"#define FILE_OUTPUT "output_route.txt"#define MAP_MAXSIZE_X 100#define MAP_MAXSIZE_Y 100#define MAX_STACK (MAP_MAXSIZE_X*MAP_MAXSIZE_Y)/2#define bool int#define true 1#define false 0int max_x=0, max_y=0;char map[MAP_MAXSIZE_X][MAP_MAXSIZE_Y]={1};bool passed[MAP_MAXSIZE_X][MAP_MAXSIZE_Y]={0};struct _POSITION { // coordinate data    int x;    int y;};typedef struct _POSITION POSITION;POSITION stack[MAX_STACK]; // stack declarationint top = -1; // top of the stack// To know whether stack is emptybool IsEmpty(){    if(top == -1)        return true;    return false;}// To know whether stack is fullbool IsFull(){    if(top < MAX_STACK-1)        return false;    return true;}// pop data from stackPOSITION Pop(){    return stack[top--];}// push data into stackvoid Push(POSITION posData){    stack[++top]=posData;}void run(int x, int y){FILE *fptr;POSITION last; // last position dataunsigned int branch = 0; // branch numbersint direction = 1; // 1:east, 2:south, 3:west, 4:northfptr = fopen(FILE_OUTPUT, "w"); while(map[x][y] != 'O') // loop until reach the goal{branch = 0; // reset branch to 0passed[x][y] = 1; // set this position is passed// TODO: choose a way to goif((y+1<max_y) && ((map[x][y+1] == 'O') || (map[x][y+1] == '0'))&& (passed[x][y+1] == 0)){  // if east can go, and hasn't passed yetbranch++; // increase the branch, if this way can godirection = 1;}if((x+1<max_x) && ((map[x+1][y] == 'O') || (map[x+1][y] == '0'))&& (passed[x+1][y] == 0)){branch++;direction = 2;}if((y-1>=0) && ((map[x][y-1] == 'O') || (map[x][y-1] == '0'))&& (passed[x][y-1] == 0)){branch++;direction = 3;}if((x-1>=0) && ((map[x-1][y] == 'O') || (map[x-1][y] == '0'))&& (passed[x-1][y] == 0)){branch++;direction = 4;}// TODO: move forwardif(branch > 1) // if there are many ways can go{if(!IsFull()){ // if stack is not full, push the branch position into the stacklast.x = x;last.y = y;Push(last);printf("Push(%d,%d), ", last.x+1, last.y+1);fprintf(fptr, "Push(%d,%d), ", last.x+1, last.y+1);}}else if(branch == 0) // if there is no route, is a dead end{printf("遇到死路, ");fprintf(fptr, "遇到死路, ");if(!IsEmpty()){last = Pop();x = last.x;y = last.y;printf("(%d,%d) = Pop(), ", last.x+1, last.y+1);fprintf(fptr, "(%d,%d) = Pop(), ", last.x+1, last.y+1);}else{printf("無法離開\n");fprintf(fptr, "無法離開\n");fclose(fptr);return;}continue;}// TODO: choose a way from last one direction, and move forwardswitch(direction){case 1:y = y + 1;printf("右, ");fprintf(fptr, "右, ");break;case 2:x = x + 1;printf("下, ");fprintf(fptr, "下, ");break;case 3:y = y - 1;printf("左, ");fprintf(fptr, "左, ");break;case 4:x = x - 1;printf("上, ");fprintf(fptr, "上, ");break;}}printf("到達\n");fprintf(fptr, "到達\n");fclose(fptr);}int main(){    FILE *fptr;    int i,j,start_x,start_y;        // TODO: Load file    fptr = fopen(FILE_MAP,"r");    if(!fptr)    {        printf("File loaded error!\n");        return 0;    }        // TODO: Read file    fscanf(fptr, "%d %d\n",&max_x, &max_y);    if(max_x==0 || max_y==0)        return 0;    for(i=0;i<max_x;i++)    {        for(j=0;j<max_y;j++)        {           fscanf(fptr, " %c", &map[i][j]);           passed[i][j]=0;           if(map[i][j]=='M')           {               start_y=i;               start_x=j;           }        }    }    fclose(fptr);        // TODO: show maze    for(i=0;i<max_x;i++)    {        for(j=0;j<max_y;j++)        {           printf("%c ", map[i][j]);        }        printf("\n");    }        run(start_y,start_x); // run maze        system("pause");    return 0;}



0 0