home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V6 / usr / source / s2 / quiz.c < prev    next >
Encoding:
C/C++ Source or Header  |  1975-05-13  |  5.9 KB  |  461 lines

  1. #define NF 10
  2. #define NL 200
  3. #define NC 200
  4. #define SL 100
  5. #define NA 10
  6.  
  7. int tflag;
  8. int xx[NL];
  9. char score[NL];
  10. int rights;
  11. int wrongs;
  12. int guesses;
  13. int buf[259];
  14. int nl 0;
  15. int na NA;
  16. int inc;
  17. int ptr 0;
  18. int nc 0;
  19. char line[150];
  20. char response[100];
  21. char *tmp[NF];
  22. int select[NF];
  23.  
  24. readline()
  25. {
  26.     char *t;
  27. loop:
  28.     for(t=line;(*t=getc(buf))!=-1;t++) {
  29.         nc++;
  30.         if(*t==' '&&(t==line||t[-1]==' '))
  31.             t--;
  32.         if(*t=='\n') {
  33.             if(t[-1]=='\\')        /*inexact test*/
  34.                 continue;
  35.             while(t>line&&t[-1]==' ')
  36.                 *--t = '\n';
  37.             *++t = 0;
  38.             return(1);
  39.         }
  40.         if(t-line>=NC) {
  41.             printf("Too hard for me\n");
  42.             do {
  43.                 *line = getc(buf);
  44.                 if(*line==0377)
  45.                     return(0);
  46.             } while(*line!='\n');
  47.             goto loop;
  48.         }
  49.     }
  50.     return(0);
  51. }
  52.  
  53. char *eu;
  54. char *ev;
  55. cmp(u,v)
  56. {
  57.     int x;
  58.     eu = u;
  59.     ev = v;
  60.     x = disj(1);
  61.     if(x!=1)
  62.         return(x);
  63.     return(eat(1,0));
  64. }
  65.  
  66. disj(s)
  67. {
  68.     int t, x;
  69.     char *u;
  70.     u = eu;
  71.     t = 0;
  72.     for(;;) {
  73.         x = string(s);
  74.         if(x>1)
  75.             return(x);
  76.         switch(*ev) {
  77.         case 0:
  78.         case ']':
  79.         case '}':
  80.             return(t|x&s);
  81.         case '|':
  82.             ev++;
  83.             t =| s;
  84.             s = 0;
  85.             continue;
  86.         }
  87.         if(s) eu = u;
  88.         if(string(0)>1)
  89.             return(2);
  90.         switch(*ev) {
  91.         case 0:
  92.         case ']':
  93.             return(0);
  94.         case '}':
  95.             return(1);
  96.         case '|':
  97.             ev++;
  98.             continue;
  99.         default:
  100.             return(2);
  101.         }
  102.     }
  103. }
  104.  
  105. string(s)
  106. {
  107.     int x;
  108.     for(;;) {
  109.         switch(*ev) {
  110.         case 0:
  111.         case '|':
  112.         case ']':
  113.         case '}':
  114.             return(1);
  115.         case '\\':
  116.             ev++;
  117.             if(*ev==0)
  118.                 return(2);
  119.             if(*ev=='\n') {
  120.                 ev++;
  121.                 continue;
  122.             }
  123.         default:
  124.             if(eat(s,*ev)==1)
  125.                 continue;
  126.             return(0);
  127.         case '[':
  128.             ev++;
  129.             x = disj(s);
  130.             if(*ev!=']' || x>1)
  131.                 return(2);
  132.             ev++;
  133.             if(s==0)
  134.                 continue;
  135.             if(x==0)
  136.                 return(0);
  137.             continue;
  138.         case '{':
  139.             ev++;
  140.             x = disj(s);
  141.             if(*ev!='}'||x>1)
  142.                 return(2);
  143.             ev++;
  144.             continue;
  145.         }
  146.     }
  147. }
  148.  
  149. eat(s,c)
  150. char c;
  151. {
  152.     if(*ev!=c)
  153.         return(2);
  154.     if(s==0) {
  155.         ev++;
  156.         return(1);
  157.     }
  158.     if(fold(*eu)!=fold(c))
  159.         return(0);
  160.     eu++;
  161.     ev++;
  162.     return(1);
  163. }
  164.  
  165. fold(c)
  166. char c;
  167. {
  168.     if(c<'A'||c>'Z')
  169.         return(c);
  170.     return(c|040);
  171. }
  172.  
  173. publish(t)
  174. char *t;
  175. {
  176.     ev = t;
  177.     pub1(1);
  178. }
  179.  
  180. pub1(s)
  181. {
  182.     for(;;ev++){
  183.         switch(*ev) {
  184.         case '|':
  185.             s = 0;
  186.             ev;
  187.             continue;
  188.         case ']':
  189.         case '}':
  190.         case 0:
  191.             return;
  192.         case '[':
  193.         case '{':
  194.             ev++;
  195.             pub1(s);
  196.             ev;
  197.             continue;
  198.         case '\\':
  199.             if(*++ev=='\n')
  200.                 continue;
  201.         default:
  202.             if(s)
  203.                 putchar(*ev);
  204.         }
  205.     }
  206. }
  207.  
  208. segment(u,w)
  209. char *u, *w[];
  210. {
  211.     char *s;
  212.     int i;
  213.     char *t;
  214.     s = u;
  215.     for(i=0;i<NF;i++) {
  216.         u = s;
  217.         t = w[i];
  218.         while(*s!=':'&&*s!='\n'&&s-u<SL) {
  219.             if(*s=='\\')  {
  220.                 if(s[1] == '\n') {
  221.                     s =+ 2;
  222.                     continue;
  223.                 }
  224.                 *t++ = *s++;
  225.             }
  226.             *t++ = *s++;
  227.         }
  228.  
  229.         while(*s!=':'&&*s!='\n')
  230.             s++;
  231.         *t = 0;
  232.         if(*s++=='\n') {
  233.             return(i+1);
  234.         }
  235.     }
  236.     printf("Too many facts about one thing\n");
  237. }
  238.  
  239. perm(u,m,v,n,p)
  240. int p[];
  241. char *u[], *v[];
  242. {
  243.     int i, j;
  244.     int x;
  245.     for(i=0;i<m;i++) {
  246.         for(j=0;j<n;j++) {
  247.             x = cmp(u[i],v[j]);
  248.             if(x>1) badinfo();
  249.             if(x==0)
  250.                 continue;
  251.             p[i] = j;
  252.             goto uloop;
  253.         }
  254.         return(0);
  255. uloop:        ;
  256.     }
  257.     return(1);
  258. }
  259.  
  260. find(u,m)
  261. char *u[];
  262. {
  263.     int n;
  264.     while(readline()){
  265.         n = segment(line,tmp);
  266.         if(perm(u,m,tmp+1,n-1,select))
  267.             return(1);
  268.     }
  269.     return(0);
  270. }
  271.  
  272. readindex()
  273. {
  274.     xx[0] = nc = 0;
  275.     while(readline()) {
  276.         xx[++nl] = nc;
  277.         if(nl>=NL) {
  278.             printf("I've forgotten some of it\n");
  279.             break;
  280.         }
  281.     }
  282. }
  283.  
  284. talloc()
  285. {
  286.     int i;
  287.     for(i=0;i<NF;i++)
  288.         tmp[i] = alloc(SL);
  289. }
  290.  
  291. main(argc,argv)
  292. char *argv[];
  293. {
  294.     int i;
  295.     int x;
  296.     char *info;
  297.     int tvec[2];
  298.     char *t;
  299.     extern done();
  300.     int count;
  301.     info = "/usr/lib/quiz/index";
  302.     time(tvec);
  303.     inc = tvec[1]&077774|01;
  304. loop:
  305.     if(argc>1&&*argv[1]=='-') {
  306.         switch(argv[1][1]) {
  307.         case 'i':
  308.             if(argc>2) 
  309.                 info = argv[2];
  310.             argc =- 2;
  311.             argv =+ 2;
  312.             goto loop;
  313.         case 't':
  314.             tflag = 1;
  315.             argc--;
  316.             argv++;
  317.             goto loop;
  318.         }
  319.     }
  320.     if(fopen(info,buf)== -1) {
  321.         printf("No info\n");
  322.         exit();
  323.     }
  324.     talloc();
  325.     if(argc<=2)
  326.         instruct(info);
  327.     signal(2,done);
  328.     argv[argc] = 0;
  329.     if(find(&argv[1],argc-1)==0)
  330.         dunno();
  331.     close(buf[0]);
  332.     if(fopen(tmp[0],buf)== -1) 
  333.         dunno();
  334.     readindex();
  335.     if(!tflag || na>nl)
  336.         na = nl;
  337.     for(;;) {
  338.         i = next();
  339.         seek(buf[0],xx[i],0);
  340.         read(buf[0],line,xx[i+1]-xx[i]);
  341.         segment(line,tmp);
  342.         if(*tmp[select[0]] == '\0' || *tmp[select[1]] == '\0') {
  343.             score[i] = 1;
  344.             continue;
  345.         }
  346.         publish(tmp[select[0]]);
  347.         printf("\n");
  348.         for(count=0;;count++) {
  349.             if(query(response)==0) {
  350.                 publish(tmp[select[1]]);
  351.                 printf("\n");
  352.                 if(count==0) wrongs++;
  353.                 score[i] = tflag?-1:1;
  354.                 break;
  355.             }
  356.             x = cmp(response,tmp[select[1]]);
  357.             if(x>1) badinfo();
  358.             if(x==1) {
  359.                 printf("Right!\n");
  360.                 if(count==0) rights++;
  361.                 if(++score[i]>=1 && na<nl)
  362.                     na++;
  363.                 break;
  364.             }
  365.             printf("What?\n");
  366.             if(count==0) wrongs++;
  367.             score[i] = tflag?-1:1;
  368.         }
  369.         guesses =+ count;
  370.     }
  371. }
  372.  
  373. query(r)
  374. char *r;
  375. {
  376.     char *t;
  377.     for(t=r;;t++) {
  378.         if(read(0,t,1)==0)
  379.             done();
  380.         if(*t==' '&&(t==r||t[-1]==' '))
  381.             t--;
  382.         if(*t=='\n') {
  383.             while(t>r&&t[-1]==' ')
  384.                 *--t = '\n';
  385.             break;
  386.         }
  387.     }
  388.     *t = 0;
  389.     return(t-r);
  390. }
  391.  
  392. next()
  393. {
  394.     int flag;
  395.     inc = inc*3125&077777;
  396.     ptr = (inc>>2)%na;
  397.     flag = 0;
  398.     while(score[ptr]>0)
  399.         if(++ptr>=na) {
  400.             ptr = 0;
  401.             if(flag) done();
  402.             flag = 1;
  403.         }
  404.     return(ptr);
  405. }
  406.  
  407. done()
  408. {
  409.     printf("\nRights %d, wrongs %d, ", rights, wrongs);
  410.     if(guesses)
  411.         printf("extra guesses %d, ", guesses);
  412.     printf("score %d%%\n",100*rights/(rights+wrongs));
  413.     exit();
  414. }
  415. instruct(info)
  416. {
  417.     char *t;
  418.     int i, n;
  419.     printf("Subjects:\n\n");
  420.     while(readline()) {
  421.         printf("-");
  422.         n = segment(line,tmp);
  423.         for(i=1;i<n;i++) {
  424.             printf(" ");
  425.             publish(tmp[i]);
  426.         }
  427.         printf("\n");
  428.     }
  429.     printf("\n");
  430.     if(fopen(info,buf)== -1)
  431.         abort();
  432.     readline();
  433.     segment(line,tmp);
  434.     printf("For example,\n");
  435.     printf("    quiz ");
  436.     publish(tmp[1]);
  437.     printf(" ");
  438.     publish(tmp[2]);
  439.     printf("\nasks you a ");
  440.     publish(tmp[1]);
  441.     printf(" and you answer the ");
  442.     publish(tmp[2]);
  443.     printf("\n    quiz ");
  444.     publish(tmp[2]);
  445.     printf(" ");
  446.     publish(tmp[1]);
  447.     printf("\nworks the other way around\n");
  448.     printf("\nType empty line to get correct answer.\n");
  449.     exit();
  450. }
  451.  
  452. badinfo(){
  453.     printf("Bad info %s\n",line);
  454. }
  455.  
  456. dunno()
  457. {
  458.     printf("I don't know about that\n");
  459.     exit();
  460. }
  461.