Annotation of coherent/d/usr/games/guess.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.