/* program DATABASE.C *\ \* WARNING: "advent.c" allocates GLOBAL storage space by *\ \* including "advdef.h". *\ \* All other modules use "advdec.h". */ #include "stdio.h" /* drv = 1.1st file 2.def 3.A */ #include "advent.h" #include "advdec.h" extern long atoi(); extern int fgetc(); extern char *fgets(); extern int fputc(); extern long fseek(); extern char *rindex(); extern char *strcpy(); extern int tolower(); /* Routine to fill travel array for a given location */ gettrav(loc) int loc; { int i; long t; char atrav[256], *aptr; strcpy(atrav, cave[loc - 1]); while (aptr = rindex(atrav, ',')) *aptr = '\0'; /* terminate substring */ aptr = &atrav[0]; for (i = 0; i < MAXTRAV; ++i) { t = atoi(aptr); /* convert to long int */ travel[i].tcond = (t % 1000); t /= 1000; travel[i].tverb = (t % 1000); t /= 1000; travel[i].tdest = (t % 1000); while (*aptr++) ; /* to next substring */ if (!(*aptr)) { travel[++i].tdest = -1;/* end of array */ if (dbugflg) for (i = 0; i < MAXTRAV; ++i) printf("cave[%d] = %d %d %d\n", \ loc, travel[i].tdest, \ travel[i].tverb, travel[i].tcond); return; /* terminate for loop */ } } bug(33); } /* Function to scan a file up to a specified point and either print or return a string. */ rdupto(fdi, uptoc, print, string) FILE *fdi; char uptoc, print, *string; { int c; while ((c = fgetc(fdi)) != uptoc) { if (c == EOF) return(0); if (c == '\r') continue; if (print) fputc(c, stdout); else *string++ = c; } if (!print) *string = '\0'; return(1); } /* Function to read a file skipping a given character a specified number of times, with or without repositioning the file. */ rdskip(fdi, skipc, n, rewind) FILE *fdi; char skipc, rewind; int n; { int c; if (rewind) if (fseek(fdi, 0, 0) == -1) bug(31); while (n--) while ((c = fgetc(fdi)) != skipc) if (c == EOF) bug(32); } /* Routine to request a yes or no answer to a question. */ yes(msg1, msg2, msg3) int msg1, msg2, msg3; { char answer[80]; if (msg1) rspeak(msg1); fputc('>', stdout); fgets(answer, 80, stdin); if (tolower(answer[0]) == 'n') { if (msg3) rspeak(msg3); return(0); } if (msg2) rspeak(msg2); return(1); } /* Print a location description from "advent4.txt" */ rspeak(msg) int msg; { if (msg == 54) printf("ok.\n"); else { if (dbugflg) printf("Seek loc msg #%d @ %ld\n", msg, idx4[msg]); fseek(fd4, idx4[msg - 1], 0); rdupto(fd4, '#', 1, 0); } return; } /* Print an item message for a given state from "advent3.txt" */ pspeak(item, state) int item, state; { fseek(fd3, idx3[item - 1], 0); rdskip(fd3, '/', state+2, 0); rdupto(fd3, '/', 1, 0); } /* Print a long location description from "advent1.txt" */ desclg(loc) int loc; { fseek(fd1, idx1[loc - 1], 0); rdupto(fd1, '#', 1, 0); } /* Print a short location description from "advent2.txt" */ descsh(loc) int loc; { fseek(fd2, idx2[loc - 1], 0); rdupto(fd2, '#', 1, 0); } /* look-up vocabulary word in lex-ordered table. words may have two entries with different codes. if minimum acceptable value = 0, then return minimum of different codes. last word CANNOT have two entries(due to binary sort). word is the word to look up. val is the minimum acceptable value, if != 0 return %1000 */ vocab(word, val) char *word; int val; { int v1, v2; if ((v1 = binary(word, wc, MAXWC)) >= 0) { v2 = binary(word, wc, MAXWC-1); if (v2 < 0) v2 = v1; if (!val) return(wc[v1].acode < wc[v2].acode\ ? wc[v1].acode : wc[v2].acode); if (val <= wc[v1].acode) return(wc[v1].acode % 1000); else if (val <= wc[v2].acode) return(wc[v2].acode % 1000); else return(-1); } else return(-1); } binary(w, wctable, maxwc) char *w; int maxwc; struct wac wctable[]; { int lo, mid, hi, check; lo = 0; hi = maxwc - 1; while (lo <= hi) { mid = (lo + hi) / 2; if ((check = strcmp(w, wctable[mid].aword)) < 0) hi = mid - 1; else if (check > 0) lo = mid + 1; else return(mid); } return(-1); } /* Utility Routines */ /* Routine to test for darkness */ dark() { return(!(cond[loc] & LIGHT) && (!prop[LAMP] || !here(LAMP))); } /* Routine to tell if an item is present. */ here(item) int item; { return(place[item] == loc || toting(item)); } /* Routine to tell if an item is being carried. */ toting(item) int item; { return(place[item] == -1); } /* Routine to tell if a location causes a forced move. */ forced(atloc) int atloc; { return(cond[atloc] == 2); } /* Routine true x% of the time. */ pct(x) int x; { return(rand() % 100 < x); } /* Routine to tell if player is on either side of a two sided object. */ at(item) int item; { return(place[item] == loc || fixed[item] == loc); } /* Routine to destroy an object */ dstroy(obj) int obj; { move(obj, 0); } /* Routine to move an object */ move(obj, where) int obj, where; { int from; from = (obj0 && from<=300) carry(obj, from); drop(obj, where); } /* Juggle an object currently a no-op */ juggle(loc) int loc; { } /* Routine to carry an object */ carry(obj, where) int obj, where; { if (objj ? i : j)); } /* Determine liquid at a location */ liqloc(loc) int loc; { if (cond[loc]&LIQUID) return(liq2(cond[loc]&WATOIL)); else return(liq2(1)); } /* Convert 0 to WATER 1 to nothing 2 to OIL */ liq2(pbottle) int pbottle; { return((1-pbottle)*WATER+(pbottle>>1)*(WATER+OIL)); } /* Fatal error routine */ bug(n) int n; { printf("Fatal error number %d\n", n); exit(); }