18867Smckusick 2*17680Sralph static char sccsid[] = " quiz.c 4.2 85/01/09 "; 38867Smckusick 48867Smckusick #include <stdio.h> 58867Smckusick #include <signal.h> 68867Smckusick #define NF 10 78867Smckusick #define NL 300 88867Smckusick #define NC 200 98867Smckusick #define SL 100 108867Smckusick #define NA 10 118867Smckusick 128867Smckusick int tflag; 138867Smckusick int xx[NL]; 148867Smckusick char score[NL]; 158867Smckusick int rights; 168867Smckusick int wrongs; 178867Smckusick int guesses; 188867Smckusick FILE *input; 198867Smckusick int nl = 0; 208867Smckusick int na = NA; 218867Smckusick int inc; 228867Smckusick int ptr = 0; 238867Smckusick int nc = 0; 248867Smckusick char line[150]; 258867Smckusick char response[100]; 268867Smckusick char *tmp[NF]; 278867Smckusick int select[NF]; 288867Smckusick 298867Smckusick readline() 308867Smckusick { 318867Smckusick char *t; 328867Smckusick loop: 338867Smckusick for(t=line;(*t=getc(input))!=-1;t++) { 348867Smckusick nc++; 358867Smckusick if(*t==' '&&(t==line||t[-1]==' ')) 368867Smckusick t--; 378867Smckusick if(*t=='\n') { 388867Smckusick if(t[-1]=='\\') /*inexact test*/ 398867Smckusick continue; 408867Smckusick while(t>line&&t[-1]==' ') 418867Smckusick *--t = '\n'; 428867Smckusick *++t = 0; 438867Smckusick return(1); 448867Smckusick } 458867Smckusick if(t-line>=NC) { 468867Smckusick printf("Too hard for me\n"); 478867Smckusick do { 488867Smckusick *line = getc(input); 498867Smckusick if(*line==0377) 508867Smckusick return(0); 518867Smckusick } while(*line!='\n'); 528867Smckusick goto loop; 538867Smckusick } 548867Smckusick } 558867Smckusick return(0); 568867Smckusick } 578867Smckusick 588867Smckusick char *eu; 598867Smckusick char *ev; 608867Smckusick cmp(u,v) 618867Smckusick char *u,*v; 628867Smckusick { 638867Smckusick int x; 648867Smckusick eu = u; 658867Smckusick ev = v; 668867Smckusick x = disj(1); 678867Smckusick if(x!=1) 688867Smckusick return(x); 698867Smckusick return(eat(1,0)); 708867Smckusick } 718867Smckusick 728867Smckusick disj(s) 738867Smckusick { 748867Smckusick int t, x; 758867Smckusick char *u; 768867Smckusick u = eu; 778867Smckusick t = 0; 788867Smckusick for(;;) { 798867Smckusick x = string(s); 808867Smckusick if(x>1) 818867Smckusick return(x); 828867Smckusick switch(*ev) { 838867Smckusick case 0: 848867Smckusick case ']': 858867Smckusick case '}': 868867Smckusick return(t|x&s); 878867Smckusick case '|': 888867Smckusick ev++; 898867Smckusick t |= s; 908867Smckusick s = 0; 918867Smckusick continue; 928867Smckusick } 938867Smckusick if(s) eu = u; 948867Smckusick if(string(0)>1) 958867Smckusick return(2); 968867Smckusick switch(*ev) { 978867Smckusick case 0: 988867Smckusick case ']': 998867Smckusick return(0); 1008867Smckusick case '}': 1018867Smckusick return(1); 1028867Smckusick case '|': 1038867Smckusick ev++; 1048867Smckusick continue; 1058867Smckusick default: 1068867Smckusick return(2); 1078867Smckusick } 1088867Smckusick } 1098867Smckusick } 1108867Smckusick 1118867Smckusick string(s) 1128867Smckusick { 1138867Smckusick int x; 1148867Smckusick for(;;) { 1158867Smckusick switch(*ev) { 1168867Smckusick case 0: 1178867Smckusick case '|': 1188867Smckusick case ']': 1198867Smckusick case '}': 1208867Smckusick return(1); 1218867Smckusick case '\\': 1228867Smckusick ev++; 1238867Smckusick if(*ev==0) 1248867Smckusick return(2); 1258867Smckusick if(*ev=='\n') { 1268867Smckusick ev++; 1278867Smckusick continue; 1288867Smckusick } 1298867Smckusick default: 1308867Smckusick if(eat(s,*ev)==1) 1318867Smckusick continue; 1328867Smckusick return(0); 1338867Smckusick case '[': 1348867Smckusick ev++; 1358867Smckusick x = disj(s); 1368867Smckusick if(*ev!=']' || x>1) 1378867Smckusick return(2); 1388867Smckusick ev++; 1398867Smckusick if(s==0) 1408867Smckusick continue; 1418867Smckusick if(x==0) 1428867Smckusick return(0); 1438867Smckusick continue; 1448867Smckusick case '{': 1458867Smckusick ev++; 1468867Smckusick x = disj(s); 1478867Smckusick if(*ev!='}'||x>1) 1488867Smckusick return(2); 1498867Smckusick ev++; 1508867Smckusick continue; 1518867Smckusick } 1528867Smckusick } 1538867Smckusick } 1548867Smckusick 1558867Smckusick eat(s,c) 1568867Smckusick char c; 1578867Smckusick { 1588867Smckusick if(*ev!=c) 1598867Smckusick return(2); 1608867Smckusick if(s==0) { 1618867Smckusick ev++; 1628867Smckusick return(1); 1638867Smckusick } 1648867Smckusick if(fold(*eu)!=fold(c)) 1658867Smckusick return(0); 1668867Smckusick eu++; 1678867Smckusick ev++; 1688867Smckusick return(1); 1698867Smckusick } 1708867Smckusick 1718867Smckusick fold(c) 1728867Smckusick char c; 1738867Smckusick { 1748867Smckusick if(c<'A'||c>'Z') 1758867Smckusick return(c); 1768867Smckusick return(c|040); 1778867Smckusick } 1788867Smckusick 1798867Smckusick publish(t) 1808867Smckusick char *t; 1818867Smckusick { 1828867Smckusick ev = t; 1838867Smckusick pub1(1); 1848867Smckusick } 1858867Smckusick 1868867Smckusick pub1(s) 1878867Smckusick { 1888867Smckusick for(;;ev++){ 1898867Smckusick switch(*ev) { 1908867Smckusick case '|': 1918867Smckusick s = 0; 1928867Smckusick ev; 1938867Smckusick continue; 1948867Smckusick case ']': 1958867Smckusick case '}': 1968867Smckusick case 0: 1978867Smckusick return; 1988867Smckusick case '[': 1998867Smckusick case '{': 2008867Smckusick ev++; 2018867Smckusick pub1(s); 2028867Smckusick ev; 2038867Smckusick continue; 2048867Smckusick case '\\': 2058867Smckusick if(*++ev=='\n') 2068867Smckusick continue; 2078867Smckusick default: 2088867Smckusick if(s) 2098867Smckusick putchar(*ev); 2108867Smckusick } 2118867Smckusick } 2128867Smckusick } 2138867Smckusick 2148867Smckusick segment(u,w) 2158867Smckusick char *u, *w[]; 2168867Smckusick { 2178867Smckusick char *s; 2188867Smckusick int i; 2198867Smckusick char *t; 2208867Smckusick s = u; 2218867Smckusick for(i=0;i<NF;i++) { 2228867Smckusick u = s; 2238867Smckusick t = w[i]; 2248867Smckusick while(*s!=':'&&*s!='\n'&&s-u<SL) { 2258867Smckusick if(*s=='\\') { 2268867Smckusick if(s[1] == '\n') { 2278867Smckusick s += 2; 2288867Smckusick continue; 2298867Smckusick } 2308867Smckusick *t++ = *s++; 2318867Smckusick } 2328867Smckusick *t++ = *s++; 2338867Smckusick } 2348867Smckusick 2358867Smckusick while(*s!=':'&&*s!='\n') 2368867Smckusick s++; 2378867Smckusick *t = 0; 2388867Smckusick if(*s++=='\n') { 2398867Smckusick return(i+1); 2408867Smckusick } 2418867Smckusick } 2428867Smckusick printf("Too many facts about one thing\n"); 2438867Smckusick } 2448867Smckusick 2458867Smckusick perm(u,m,v,n,p) 2468867Smckusick int p[]; 2478867Smckusick char *u[], *v[]; 2488867Smckusick { 2498867Smckusick int i, j; 2508867Smckusick int x; 2518867Smckusick for(i=0;i<m;i++) { 2528867Smckusick for(j=0;j<n;j++) { 2538867Smckusick x = cmp(u[i],v[j]); 2548867Smckusick if(x>1) badinfo(); 2558867Smckusick if(x==0) 2568867Smckusick continue; 2578867Smckusick p[i] = j; 2588867Smckusick goto uloop; 2598867Smckusick } 2608867Smckusick return(0); 2618867Smckusick uloop: ; 2628867Smckusick } 2638867Smckusick return(1); 2648867Smckusick } 2658867Smckusick 2668867Smckusick find(u,m) 2678867Smckusick char *u[]; 2688867Smckusick { 2698867Smckusick int n; 2708867Smckusick while(readline()){ 2718867Smckusick n = segment(line,tmp); 2728867Smckusick if(perm(u,m,tmp+1,n-1,select)) 2738867Smckusick return(1); 2748867Smckusick } 2758867Smckusick return(0); 2768867Smckusick } 2778867Smckusick 2788867Smckusick readindex() 2798867Smckusick { 2808867Smckusick xx[0] = nc = 0; 2818867Smckusick while(readline()) { 2828867Smckusick xx[++nl] = nc; 2838867Smckusick if(nl>=NL) { 2848867Smckusick printf("I've forgotten some of it;\n"); 2858867Smckusick printf("I remember %d items.\n", nl); 2868867Smckusick break; 2878867Smckusick } 2888867Smckusick } 2898867Smckusick } 2908867Smckusick 2918867Smckusick talloc() 2928867Smckusick { 2938867Smckusick int i; 294*17680Sralph char *malloc(); 295*17680Sralph 2968867Smckusick for(i=0;i<NF;i++) 2978867Smckusick tmp[i] = malloc(SL); 2988867Smckusick } 2998867Smckusick 3008867Smckusick main(argc,argv) 3018867Smckusick char *argv[]; 3028867Smckusick { 3038867Smckusick register j; 3048867Smckusick int i; 3058867Smckusick int x; 3068867Smckusick int z; 3078867Smckusick char *info; 3088867Smckusick int tvec[2]; 3098867Smckusick char *t; 3108867Smckusick extern done(); 3118867Smckusick int count; 3128867Smckusick info = "/usr/games/lib/quiz.k/index"; 3138867Smckusick time(tvec); 3148867Smckusick inc = tvec[1]&077774|01; 3158867Smckusick loop: 3168867Smckusick if(argc>1&&*argv[1]=='-') { 3178867Smckusick switch(argv[1][1]) { 3188867Smckusick case 'i': 3198867Smckusick if(argc>2) 3208867Smckusick info = argv[2]; 3218867Smckusick argc -= 2; 3228867Smckusick argv += 2; 3238867Smckusick goto loop; 3248867Smckusick case 't': 3258867Smckusick tflag = 1; 3268867Smckusick argc--; 3278867Smckusick argv++; 3288867Smckusick goto loop; 3298867Smckusick } 3308867Smckusick } 3318867Smckusick input = fopen(info,"r"); 3328867Smckusick if(input==NULL) { 3338867Smckusick printf("No info\n"); 3348867Smckusick exit(0); 3358867Smckusick } 3368867Smckusick talloc(); 3378867Smckusick if(argc<=2) 3388867Smckusick instruct(info); 3398867Smckusick signal(SIGINT,done); 3408867Smckusick argv[argc] = 0; 3418867Smckusick if(find(&argv[1],argc-1)==0) 3428867Smckusick dunno(); 3438867Smckusick fclose(input); 3448867Smckusick input = fopen(tmp[0],"r"); 3458867Smckusick if(input==NULL) 3468867Smckusick dunno(); 3478867Smckusick readindex(); 3488867Smckusick if(!tflag || na>nl) 3498867Smckusick na = nl; 3508867Smckusick stdout->_flag |= _IONBF; 3518867Smckusick for(;;) { 3528867Smckusick i = next(); 3538867Smckusick fseek(input,xx[i]+0L,0); 3548867Smckusick z = xx[i+1]-xx[i]; 3558867Smckusick for(j=0;j<z;j++) 3568867Smckusick line[j] = getc(input); 3578867Smckusick segment(line,tmp); 3588867Smckusick if(*tmp[select[0]] == '\0' || *tmp[select[1]] == '\0') { 3598867Smckusick score[i] = 1; 3608867Smckusick continue; 3618867Smckusick } 3628867Smckusick publish(tmp[select[0]]); 3638867Smckusick printf("\n"); 3648867Smckusick for(count=0;;count++) { 3658867Smckusick if(query(response)==0) { 3668867Smckusick publish(tmp[select[1]]); 3678867Smckusick printf("\n"); 3688867Smckusick if(count==0) wrongs++; 3698867Smckusick score[i] = tflag?-1:1; 3708867Smckusick break; 3718867Smckusick } 3728867Smckusick x = cmp(response,tmp[select[1]]); 3738867Smckusick if(x>1) badinfo(); 3748867Smckusick if(x==1) { 3758867Smckusick printf("Right!\n"); 3768867Smckusick if(count==0) rights++; 3778867Smckusick if(++score[i]>=1 && na<nl) 3788867Smckusick na++; 3798867Smckusick break; 3808867Smckusick } 3818867Smckusick printf("What?\n"); 3828867Smckusick if(count==0) wrongs++; 3838867Smckusick score[i] = tflag?-1:1; 3848867Smckusick } 3858867Smckusick guesses += count; 3868867Smckusick } 3878867Smckusick } 3888867Smckusick 3898867Smckusick query(r) 3908867Smckusick char *r; 3918867Smckusick { 3928867Smckusick char *t; 3938867Smckusick for(t=r;;t++) { 3948867Smckusick if(read(0,t,1)==0) 3958867Smckusick done(); 3968867Smckusick if(*t==' '&&(t==r||t[-1]==' ')) 3978867Smckusick t--; 3988867Smckusick if(*t=='\n') { 3998867Smckusick while(t>r&&t[-1]==' ') 4008867Smckusick *--t = '\n'; 4018867Smckusick break; 4028867Smckusick } 4038867Smckusick } 4048867Smckusick *t = 0; 4058867Smckusick return(t-r); 4068867Smckusick } 4078867Smckusick 4088867Smckusick next() 4098867Smckusick { 4108867Smckusick int flag; 4118867Smckusick inc = inc*3125&077777; 4128867Smckusick ptr = (inc>>2)%na; 4138867Smckusick flag = 0; 4148867Smckusick while(score[ptr]>0) 4158867Smckusick if(++ptr>=na) { 4168867Smckusick ptr = 0; 4178867Smckusick if(flag) done(); 4188867Smckusick flag = 1; 4198867Smckusick } 4208867Smckusick return(ptr); 4218867Smckusick } 4228867Smckusick 4238867Smckusick done() 4248867Smckusick { 4258867Smckusick printf("\nRights %d, wrongs %d, ", rights, wrongs); 4268867Smckusick if(guesses) 4278867Smckusick printf("extra guesses %d, ", guesses); 4288867Smckusick printf("score %d%%\n",100*rights/(rights+wrongs)); 4298867Smckusick exit(0); 4308867Smckusick } 4318867Smckusick instruct(info) 4328867Smckusick { 4338867Smckusick char *t; 4348867Smckusick int i, n; 4358867Smckusick printf("Subjects:\n\n"); 4368867Smckusick while(readline()) { 4378867Smckusick printf("-"); 4388867Smckusick n = segment(line,tmp); 4398867Smckusick for(i=1;i<n;i++) { 4408867Smckusick printf(" "); 4418867Smckusick publish(tmp[i]); 4428867Smckusick } 4438867Smckusick printf("\n"); 4448867Smckusick } 4458867Smckusick printf("\n"); 4468867Smckusick input = fopen(info,"r"); 4478867Smckusick if(input==NULL) 4488867Smckusick abort(); 4498867Smckusick readline(); 4508867Smckusick segment(line,tmp); 4518867Smckusick printf("For example,\n"); 4528867Smckusick printf(" quiz "); 4538867Smckusick publish(tmp[1]); 4548867Smckusick printf(" "); 4558867Smckusick publish(tmp[2]); 4568867Smckusick printf("\nasks you a "); 4578867Smckusick publish(tmp[1]); 4588867Smckusick printf(" and you answer the "); 4598867Smckusick publish(tmp[2]); 4608867Smckusick printf("\n quiz "); 4618867Smckusick publish(tmp[2]); 4628867Smckusick printf(" "); 4638867Smckusick publish(tmp[1]); 4648867Smckusick printf("\nworks the other way around\n"); 4658867Smckusick printf("\nType empty line to get correct answer.\n"); 4668867Smckusick exit(0); 4678867Smckusick } 4688867Smckusick 4698867Smckusick badinfo(){ 4708867Smckusick printf("Bad info %s\n",line); 4718867Smckusick } 4728867Smckusick 4738867Smckusick dunno() 4748867Smckusick { 4758867Smckusick printf("I don't know about that\n"); 4768867Smckusick exit(0); 4778867Smckusick } 478