/* $Id: mazeserver.c 53 2008-05-01 05:50:20Z edsko $ */ /* $Source: /home/jgroup/judge1/edsko/maze/RCS/mazeserver.c,v $ */ #include #include #include #include #include #define TRUE 1 #define FALSE 0 #define MAXW 20 #define MAXH 20 #define SSIZE 81 int ubgets(char *buf, int bufsiz, int timeout); int cx; int cy; int ex; int ey; int h; int w; int m[MAXW][MAXH]; int ReadMaze(FILE *f) { int exitCount=0; int startCount=0; int len; int n; int x; int y; char s[SSIZE]; ex=-1; ey=-1; cx=-1; cy=-1; fgets(s,SSIZE,f); len=strlen(s); if (s[len - 1] != '\n') { fprintf(stderr,"maze configuration: first line missing newline or line too long\n"); exit(2); } else { s[len - 1]='\0'; } n=sscanf(s,"%d %d",&h,&w); if (n != 2) { fprintf(stderr,"maze configuration: unable to convert two integers from first line\n"); exit(2); } if ((h < 1) || (h > 20)) { fprintf(stderr,"maze configuration: rows must be in [1..20]\n"); exit(2); } if ((w < 1) || (w > 20)) { fprintf(stderr,"maze configuration: columns must be in [1..20]\n"); exit(2); } for (y=0; y < h; y++) { if (fgets(s,SSIZE,f) == NULL) { fprintf(stderr,"maze configuration: unexpected end-of-file on row %d\n",y); exit(2); } len=strlen(s); if (s[len - 1] != '\n') { fprintf(stderr,"maze configuration: row %d line missing newline or line too long\n",y); exit(2); } else { s[len - 1]='\0'; } len=strlen(s); if (len != w) { fprintf(stderr,"maze configuration: row %d must be %d characters long\n",y,w); exit(2); } for (x=0; x < w; x++) { switch (s[x]) { case ' ': m[x][y]=FALSE; break; case '*': m[x][y]=TRUE; break; case '-': m[x][y]=FALSE; cx=x; cy=y; startCount++; break; case 'E': m[x][y]=FALSE; ex=x; ey=y; exitCount++; break; default: fprintf(stderr,"maze configuration: row %d, unexpected character '%c'\n",y,s[x]); exit(2); } } } if (fgets(s,SSIZE,f) != NULL) { fprintf(stderr,"maze configuration: unexpected data after row %d\n",h-1); exit(2); } if ((ex < 0) || (ey < 0)) { fprintf(stderr,"maze configuration: no exit 'E' specified\n"); exit(2); } if (exitCount > 1) { fprintf(stderr,"maze configuration: only one exit may be specified\n"); exit(2); } if ((cx < 0) || (cy < 0)) { fprintf(stderr,"maze configuration: no starting point '-' specified\n"); exit(2); } if (startCount > 1) { fprintf(stderr,"maze configuration: only one starting point may be specified\n"); exit(2); } /* check for proper edges */ y=0; for (x=0; x < w; x++) { if (!m[x][y] && ((x != ex) || (y != ey))) { fprintf(stderr,"maze configuration: unexpected pathway at edge (%d,%d)\n",y,x); exit(2); } } y=h - 1; for (x=0; x < w; x++) { if (!m[x][y] && ((x != ex) || (y != ey))) { fprintf(stderr,"maze configuration: unexpected pathway at edge (%d,%d)\n",y,x); exit(2); } } x=0; for (y=0; y < h; y++) { if (!m[x][y] && ((x != ex) || (y != ey))) { fprintf(stderr,"maze configuration: unexpected pathway at edge (%d,%d)\n",y,x); exit(2); } } x=w - 1; for (y=0; y < h; y++) { if (!m[x][y] && ((x != ex) || (y != ey))) { fprintf(stderr,"maze configuration: unexpected pathway at edge (%d,%d)\n",y,x); exit(2); } } } void Newxy(int *nx, int *ny, int cx, int cy, int d) { static int dx[6]= { 0, 1, 1, 0,-1,-1}; static int dy[2][6]={-1, 0, 1, 1, 1, 0 ,-1,-1, 0, 1, 0,-1}; #ifdef DEBUG { int DX=dx[d - 1]; int DY=dy[cx%2][d - 1]; int y; for (y=0; y < 6; y++) { fprintf(stdout,"%2d: [%2d] [%2d][%2d]\n",y+1,dx[y],dy[0][y],dy[1][y]); } fprintf(stdout," DX=%d, DY=%d\n",DX,DY); } #endif *nx=cx + dx[d - 1]; *ny=cy + dy[cx%2][d - 1]; } void DisplayMaze(FILE *f) { int x; int y; for (y=0; y < h; y++) { fprintf(f,"%2d: ",y); for (x=0; x < w; x++) { if ((x == cx) && (y == cy)) { fputc('-',f); } else if ((x == ex) && (y == ey)) { fputc('E',f); } else if (m[x][y]) { fputc('*',f); } else { fputc(' ',f); } } fputc('\n',f); } } int main(int argc, char *argv[]) { int len; FILE *mazeFile; int moveLimit=0; int moves=0; int nx; int ny; char s[SSIZE]; FILE *transcriptFile; int x; int y; for (y=0; y < MAXH; y++) { for (x=0; x < MAXW; x++) { m[x][y]=TRUE; } } mazeFile=fopen(argv[1],"r"); if (mazeFile == NULL) { fprintf(stderr,"Could not open maze file \"%s\": %s\n",argv[1],strerror(errno)); exit(1); } transcriptFile=fopen(argv[2],"w"); if (transcriptFile == NULL) { fprintf(stderr,"Could not open transcript file \"%s\": %s\n",argv[2],strerror(errno)); exit(1); } ReadMaze(mazeFile); moveLimit=2*h*w; fprintf(transcriptFile,"Start=(%d,%d) Exit=(%d,%d) Limit=%d moves\n",cy,cx,ey,ex,moveLimit); fflush(transcriptFile); fprintf(transcriptFile,"move: direction response (row,column)\n"); fflush(transcriptFile); do { int d; char *response; # ifdef DEBUG DisplayMaze(stdout); # endif len=ubgets(s,sizeof(s),1000); /* fgets(s,sizeof(s),stdin); len=strlen(s); */ moves++; if (len == -1) { fprintf(stderr,"move %d: Wrong Answer (unexpected end-of-file)\n",moves); exit(0); } if (len == 0) { fprintf(stderr,"move %d: Time Limit Exceeded\n",moves); exit(0); } if (s[len-1] != '\n') { fprintf(stderr,"move %d: Run Time Error (no newline)\n",moves); exit(0); } else { s[len-1]='\0'; } if (len != 2) { fprintf(stderr,"'%s'\n",s); fprintf(stderr,"move %d: Run Time Error (line too long/too short)\n",moves); exit(0); } if ((s[0] < '1') || (s[0] > '6')) { fprintf(stderr,"'%s'\n",s); fprintf(stderr,"move %d: Run Time Error (unexpected character)\n",moves); exit(0); } if (moves > moveLimit) { fprintf(stderr,"'%s'\n",s); fprintf(stderr,"move %d: Wrong Answer (too many moves, limit=%d)\n",moves,moveLimit); exit(0); } sscanf(s,"%d",&d); # ifdef WEIRD fprintf(transcriptFile,"%d: '%s'",d,s); # endif Newxy(&nx,&ny,cx,cy,d); if (m[nx][ny]) { response="n"; } else { cx=nx; cy=ny; if ((cx == ex) && (cy == ey)) { response="E"; } else { response="y"; } } #ifdef VERIFY fprintf(stdout," (%d,%d)",cy,cx); #endif fprintf(stdout,"%s\n",response); fflush(stdout); fprintf(transcriptFile,"%3d: %d %s (%d,%d)\n",moves,d,response,cy,cx); fflush(transcriptFile); } while ((cx != ex) || (cy != ey)); len=ubgets(s,sizeof(s),1000); if (len == -1) { fprintf(stderr,"Correct. Congratulations.\n"); fflush(stderr); } else { fprintf(stderr,"%s",s); fprintf(stderr,"Presentation Error (input after finding exit)\n"); fflush(stderr); } exit(0); }