home *** CD-ROM | disk | FTP | other *** search
- /* Maze solver
-
- Solve maze by finding shortest path in graph. Starting from node A, marked
- by 1, each node adjacent to n which has not already been marked with a lower
- value is marked with n+1; this process finishes when all paths to B have been
- tried and the shortest found. Trace unique path back from B to A.
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <system.h>
-
- int sx=-1, sy, /* start A */
- ex=-1, ey=-1, /* finish B */
- xs=0, ys=0, /* size of maze */
- fd=1000;
-
- char *maze[100], *work[100];
-
- main()
- {
- int x=0, y;
- char in[100];
-
- while(*(work[ys]=strcpy(malloc(xs+1),
- maze[ys]=strcpy(malloc(xs?((*in>0)&&(xs!=strlen(in))?
- (exit(0),0):xs)+1:(xs=strlen(in))+1),gets(in)))))
- ys++;
-
- for(x=y=0; y<ys; x=0, y++)
- while(work[y][x])
- switch(work[y][x++])
- {
- case 'A': if(sx!=-1)
- printf("more than one start"),
- exit(0);
-
- sx=x-1; sy=y; work[sy][sx]=1; /* start 1 */
- break;
-
- case 'B': if(ex!=-1)
- printf("more than one end"),
- exit(0);
-
- ex=x-1; ey=y; work[ey][ex]=(char)255; /* finish -1 */
- break;
-
- case ' ': work[y][x-1]=(char)254; /* blanks -2 */
- break;
-
- default : work[y][x-1]=(char)253; /* border -3 */
- break;
- }
-
- next(sx,sy,1); /* find all accessible paths from start A */
-
- if(fd<1000)
- {
- back(ex,ey,fd); /* trace path of length fd from B back to A */
- for(y=0; y<ys; y++)
- printf("%s\n",maze[y]);
- }
- else
- printf("no solutions");
- }
-
- next(int x, int y, int t)
- {
- int xl, xr, xu, xd;
-
- work[y][x]=t++;
-
- xl=work[y][x-1]; xr=work[y][x+1];
- xu=work[y-1][x]; xd=work[y+1][x];
-
- /* if next to B and no shorter paths, store path length in fd */
-
- if(!(xl+1)|!(xr+1)|!(xu+1)|!(xd+1)) fd=t<fd?t:fd;
-
- /* if next square unreached or by longer path, recurse */
-
- if(xl==-2 || xl>t) next(x-1,y,t);
- if(xr==-2 || xr>t) next(x+1,y,t);
- if(xu==-2 || xu>t) next(x,y-1,t);
- if(xd==-2 || xd>t) next(x,y+1,t);
- }
-
- back(int x, int y, int t)
- {
- if(!(x==ex && y==ey)) maze[y][x]='+'; work[y][x]=252;
- if(--t==1) return;
-
- if(work[y][x-1]==t) { back(x-1,y,t); return; }
- if(work[y][x+1]==t) { back(x+1,y,t); return; }
- if(work[y-1][x]==t) { back(x,y-1,t); return; }
- if(work[y+1][x]==t) { back(x,y+1,t); return; }
- }
-