|
|
1.1 ! root 1: /* ! 2: * Guess -- like 20 questions. ! 3: * ! 4: * (NOTE: /usr/games/guess should be setuid to `games'. ! 5: * /usr/games/lib/guess.db should be owned by `games') ! 6: */ ! 7: ! 8: #include <stdio.h> ! 9: ! 10: #define NLINE 128 /* Length of various input buffers */ ! 11: ! 12: struct node{ ! 13: char *question; ! 14: struct node *yes, *no; /* if yes==NULL, this is a leaf node */ ! 15: }; ! 16: struct node cow = { "a cow", NULL }; ! 17: struct node *game = { &cow }; ! 18: char *dbname = "/usr/games/lib/guess.db"; ! 19: char line[NLINE], question[NLINE]; ! 20: ! 21: char * ! 22: copy(s) ! 23: register char *s; ! 24: { ! 25: register char *t, *v; ! 26: int l; ! 27: for(l=0,t=s;*t++;l++); ! 28: v=t=malloc(l+1); ! 29: if(v==NULL){ ! 30: printf("Out of space in copy\n"); ! 31: leave(); ! 32: } ! 33: do;while(*t++ = *s++); ! 34: return(v); ! 35: } ! 36: ! 37: char * ! 38: freads(f, s) ! 39: FILE *f; ! 40: register char *s; ! 41: { ! 42: register char *v; ! 43: if(fgets(s, NLINE, f)==NULL) ! 44: return(NULL); ! 45: v=s; ! 46: while(*s!='\n' && *s!='\0') ! 47: s++; ! 48: *s='\0'; ! 49: return(v); ! 50: } ! 51: readdb(){ ! 52: register c; ! 53: register struct node *p; ! 54: FILE *f; ! 55: int message = 0; ! 56: if((f=fopen(dbname, "r"))==NULL) ! 57: return; ! 58: if(freads(f, line)==NULL){ ! 59: fclose(f); ! 60: return; ! 61: } ! 62: game->question=copy(line); ! 63: for(;;){ ! 64: p=game; ! 65: while((c=getc(f))=='y' || c=='n'){ ! 66: if(p->yes==NULL){ ! 67: p->yes=malloc(sizeof(struct node)); ! 68: p->no=malloc(sizeof(struct node)); ! 69: if(p->yes==NULL || p->no==NULL){ ! 70: printf("Out of space in dbread\n"); ! 71: exit(1); ! 72: } ! 73: p->yes->question="a corrupt database"; ! 74: p->yes->yes=NULL; ! 75: p->no->question="a corrupt database"; ! 76: p->no->yes=NULL; ! 77: } ! 78: if(c=='y') ! 79: p=p->yes; ! 80: else ! 81: p=p->no; ! 82: } ! 83: if(c==EOF) ! 84: break; ! 85: if(c!=':' && !message){ ! 86: printf("Invalid database\n"); ! 87: message++; ! 88: } ! 89: freads(f, line); ! 90: p->question=copy(line); ! 91: } ! 92: fclose(f); ! 93: } ! 94: writedb(p, f, level) ! 95: struct node *p; ! 96: FILE *f; ! 97: { ! 98: fprintf(f, "%s\n", p->question); ! 99: if(p->yes){ ! 100: line[level]='y'; ! 101: line[level+1]='\0'; ! 102: fprintf(f, "%s:", line); ! 103: writedb(p->yes, f, level+1); ! 104: line[level]='n'; ! 105: line[level+1]='\0'; ! 106: fprintf(f, "%s:", line); ! 107: writedb(p->no, f, level+1); ! 108: } ! 109: } ! 110: leave(){ ! 111: FILE *f; ! 112: if((f=fopen(dbname, "w"))==NULL){ ! 113: printf("Can't create the database\n"); ! 114: exit(1); ! 115: } ! 116: writedb(game, f, 0); ! 117: exit(0); ! 118: } ! 119: main(argc, argv) ! 120: char *argv[]; ! 121: { ! 122: register struct node *p; ! 123: register c; ! 124: if(argc>1) ! 125: dbname=argv[1]; ! 126: readdb(); ! 127: for(;;){ ! 128: printf("Think of something.\n"); ! 129: p=game; ! 130: while(p->yes){ ! 131: for(;;){ ! 132: printf("%s? ", p->question); ! 133: c=answer(); ! 134: if(c=='y'){ ! 135: p=p->yes; ! 136: break; ! 137: } ! 138: if(c=='n'){ ! 139: p=p->no; ! 140: break; ! 141: } ! 142: printf("Answer yes or no.\n"); ! 143: } ! 144: } ! 145: for(;;){ ! 146: printf("Is %s what you're thinking of? ", p->question); ! 147: c=answer(); ! 148: if(c=='y') ! 149: break; ! 150: if(c=='n'){ ! 151: printf("I give up. What are you thinking of? "); ! 152: if(gets(line)==NULL) ! 153: leave(); ! 154: printf("What is a yes-or-no answer question to distinguish %s from %s? ", p->question, line); ! 155: if(gets(question)==NULL) ! 156: leave(); ! 157: for(;;){ ! 158: printf("What is the answer for %s? ", line); ! 159: c=answer(); ! 160: if(c=='y' || c=='n') ! 161: break; ! 162: printf("Answer yes or no.\n"); ! 163: } ! 164: p->yes=malloc(sizeof(struct node)); ! 165: p->no=malloc(sizeof(struct node)); ! 166: if(p->yes==NULL || p->no==NULL){ ! 167: printf("Out of space\n"); ! 168: leave(); ! 169: } ! 170: if(c=='y'){ ! 171: p->yes->question=copy(line); ! 172: p->no->question=p->question; ! 173: } ! 174: else{ ! 175: p->yes->question=p->question; ! 176: p->no->question=copy(line); ! 177: } ! 178: p->question=copy(question); ! 179: p->yes->yes=NULL; ! 180: p->no->yes=NULL; ! 181: break; ! 182: } ! 183: printf("Answer yes or no.\n"); ! 184: } ! 185: } ! 186: } ! 187: ! 188: answer() ! 189: { ! 190: char buf[NLINE]; ! 191: ! 192: if(gets(buf)==NULL) ! 193: leave(); ! 194: return(buf[0]); ! 195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.