/* Problem 4: Jeff Horn's Robots This program finds and prints the shortest path a robot can take through a room with obstacles. */ #include #include #include typedef int BT[10][10]; typedef char GT[10][11]; typedef struct square { /* a position vector within the grid */ int x, y; } square; int main (int argc, char **argv); void process (void); void Bprocess (BT Board, int ct, square *ch, int chct); void append (BT Board, int ct, square *ch, int *chct, int x, int y, char Dir); void ReTourBoard (int pl,char *Tour); int l, w; /* length and width of the board */ GT Grid, Direction; /* Grid is the room map, Direction stores path info*/ FILE *in, *out; int main (int argc, char **argv) { int i; in = fopen ("prob4.in","r"); out = fopen ("prob4.out","w"); while (1) { fscanf (in,"%d %d ",&l,&w); /* Read in length and width */ if (l==0) break; for (i = 0; i < l; i++) fscanf (in,"%s",Grid[i]); /* Read in the grid */ memset (Direction, 0, sizeof Direction); /* Initialize */ process (); } fclose (in); fclose (out); return EXIT_SUCCESS; } /* process computes and prints out the shortest path. It begins at the starting point and finds all reachable positions 1 move away and how to get there. From these it finds the squares two positions away, and how to get there, and so forth, until it has filled the room. Then it prints the path needed to reach the destination square. */ void process (void) { char Tour[101] = {0}; /* path the robot takes */ BT Board; /* contains the path length to every square */ square ch[400]; /* the list of squares x moves from start */ ch[0].x = ch[0].y = 0; /* There is only one square 0 moves away */ memset (Board,-1,sizeof Board); Board[0][0] = 0; Bprocess (Board,1,ch,1); /* Compute the paths of length > 0 */ ReTourBoard (Board[l-1][w-1],Tour); /* Compute the path string */ fprintf (out,"%s\n",Tour); /* Print the path string */ } /* Bprocess accepts the board containing the squares already visited, and finds all squares on the board at least ct squares away from the starting point. ch is the list of squares ct-1 away from the starting point, and chct is the length of this list. */ void Bprocess (BT Board, int ct, square *ch, int chct) { int i, chctnew; square chnew[64]; chctnew = i = 0; for (chctnew = i = 0; i < chct; i++) { /* Each square has four neighbors, add them to the list of squares ct moves from start. */ append (Board,ct,chnew,&chctnew,ch[i].x,ch[i].y-1,'W'); append (Board,ct,chnew,&chctnew,ch[i].x,ch[i].y+1,'E'); append (Board,ct,chnew,&chctnew,ch[i].x-1,ch[i].y,'N'); append (Board,ct,chnew,&chctnew,ch[i].x+1,ch[i].y,'S'); } /* If we haven't made it to the destination, find the ones at least ct+1 moves away. */ if (Board[l-1][w-1]==-1) Bprocess (Board,ct+1,chnew,chctnew); } /* append adds a square to a list of squares, but only if it's valid and has not been visited yet. Board contains the visited squares, ct is the path length so far, ch is the list of squares chct is the length of that list. x and y are the coordinates to be added. Dir represents the direction being moved. */ void append (BT Board, int ct, square *ch, int *chct, int x, int y, char Dir) { if (x>=0 && x=0 && y=0; pl--) { Tour[pl] = Direction[l][w]; /* Pull out the direction */ switch (Tour[pl]) { /* Move accordingly. */ case 'N': l++; break; case 'S': l--; break; case 'E': w--; break; case 'W': w++; } } }