home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / games / volume15 / dinkum / part05 / parse.c < prev   
C/C++ Source or Header  |  1993-01-27  |  14KB  |  711 lines

  1. #define PARSE
  2. #include "dink_sym.h"
  3. #include "dink_glb.h"
  4. #include <string.h>
  5.  
  6. void parse()
  7. /*********************************************************/
  8. /*                                                       */
  9. /*      --- English Language Parsing Subroutine ---      */
  10. /*                                                       */
  11. /*  This subroutine parses a sentence of up to nineteen  */
  12. /*  words and decodes the words into integers and passes */
  13. /*  a twenty element vector back to the calling          */
  14. /*  program.  The digit 0, implies an unused word.  The  */
  15. /*  digit -1 (V_LINE_END), indicates end of sentence.    */
  16. /*                                                       */
  17. /*      Program by Gary A. Allen, Jr.   5 March 1990     */
  18. /*        (c) Copywrite 1990 by Gary A. Allen, Jr.       */
  19. /*                                                       */
  20. /*********************************************************/
  21. {
  22. #ifdef __TURBOC__ 
  23. char getche(void) ;
  24. void purge(int, int*) ;
  25. #endif
  26.  
  27. register int i, j ;
  28. int m, n, j_point, jacc, i_ws, sw_adverb, sw_purge, j_purge, sw_punct ;
  29. int sw_movement, sw_adverb_fnd ;
  30. int j_old = 0 ; /* this is to keep Lint happy */
  31. /* a sentence can have 19 words of 15 letters */ 
  32. char words[20][15], word[15] ;
  33. char letter ;
  34.  
  35. /* flush the "sent vector" */
  36. for (i=0; i<=19; i++) sent[i]=0 ;
  37.  
  38. /* flush the tag vector */
  39. for (i=0; i<= tag_max; i++) tag[i] = FALSE ;
  40.  
  41. /* Parse and load in the words */
  42. input:
  43. sw_punct = FALSE ;
  44. for (i=0; i <= 18; i++) {
  45.     for (j=0; j <= 14; j++) {
  46. #ifndef __TURBOC__
  47.         letter = getchar() ;    
  48. #endif
  49.  
  50. #ifdef __TURBOC__
  51.         letter = getche() ;    
  52. #endif
  53.  
  54.         switch (letter) {
  55.             case '\n':
  56.             case 13 :
  57.                 if ((i == 0) && (j == 0)) goto input ;
  58.                 words[i][j] = '\0' ;  
  59.                 goto decode; 
  60.  
  61.             case 8:
  62.                 if (sw_punct) {
  63.                     if (--i < 0) i = 0 ;
  64.                     j = j_old ;
  65.                     sw_punct = FALSE ;
  66.                 }
  67.                 else if (--j < 0) j = 0 ;
  68.                 --j ;
  69.                 continue ;
  70.  
  71.             case '\"':
  72.             case ' ':
  73.             case ',':
  74.             case '.':
  75.             case ';':
  76.             case ':':
  77.             case '?':
  78.             case '!':
  79.             case '&':
  80.             case '{':
  81.             case '}':
  82.             case '[':
  83.             case ']':
  84.             case ')':
  85.             case '(':
  86.             case '\'':
  87.             case '`':
  88.             case '\t':
  89.                 words[i][j] = '\0' ;  
  90.                 sw_punct = TRUE ;
  91.                 j_old = j ;
  92.                 break;
  93.  
  94.             default:
  95.                 words[i][j] = letter ;
  96.                 sw_punct = FALSE ;
  97.                 continue ;
  98.         }
  99.         break ;
  100.     }
  101.     if (j > 14) {
  102. printf("\nYou're saying nonsense! Type the sentence again. \n");
  103.         break ;
  104.     }
  105.     if (j == 0) i-- ;
  106. }
  107. if (i > 18) 
  108. printf ("\nYour sentence is too long. Type something shorter! \n") ;
  109.  
  110. #ifndef __TURBOC__
  111. /* Purge the input buffer */
  112.     for (;;) if ('\n' == getchar()) break ;
  113. goto input;
  114. /* decode the words from the known vocabulary */
  115. decode:
  116. #endif
  117.  
  118. #ifdef __TURBOC__
  119. goto input;
  120. /* decode the words from the known vocabulary */
  121. decode:
  122. printf("\n") ;
  123. #endif
  124.  
  125. m=i ;
  126. jacc=0;
  127. for (i=0; i<=m; i++) {
  128.     for (j=0; j<=14; j++) {
  129.         word[j] = words[i][j] ; 
  130.     }
  131.     for (j=0; j<=letmax; j++) {
  132.         n = strcmp (word,vocab[j]);
  133.         if (n == 0) {
  134.             if ((j>9)&&(j<20)) j -= 10;
  135.             sent[jacc++]=j+1 ;
  136.             break; 
  137.         }
  138.     }
  139. }
  140.  
  141. if (jacc == 0) {
  142.     printf ("Nothing you said was understandable! Try again. \n");
  143.     goto input; 
  144. }
  145.  
  146. /* mark last word */
  147. sent[jacc] = V_LINE_END ;
  148.  
  149. /* Check to see if this is a simple move command */
  150. if (sent[0] <= 10) {
  151.     tag[V_MOVE] = TRUE ;
  152.     tag[V_DIRECTION] = TRUE ;
  153.     verb = sent[0] ;
  154.     return ; 
  155. }
  156.  
  157. /* adjective and "in/out" preposition scan */
  158. sw_purge = FALSE ;
  159. for (j = 0; j <= jacc-1; j++) {
  160.  
  161.     /* check for adjectives*/
  162.     for (i = 0; i <= adj_max; i++) {
  163.         if (sent[j] == adjective[i][Aj_adj]) {
  164.  
  165.         /* does a noun have to be ignored ? */
  166.         if (adjective[i][Aj_adj_cmd] == F_ignore) {
  167.         if (adjective[i][Aj_trig_noun] != sent[j+1]) break ;
  168.         }
  169.  
  170.         /* does a noun have to be replaced? */
  171.         if (adjective[i][Aj_adj_cmd] == F_replace) {
  172.             if (adjective[i][Aj_trig_noun] == sent[j+1]) {
  173.             sent[j+1] = adjective[i][Aj_act_noun] ;
  174.             }
  175.         }
  176.         sw_purge = TRUE ;
  177.         j_purge = j ;
  178.         }
  179.     }
  180. }
  181.  
  182. /* purge processed adjective from sentence */
  183. if (sw_purge) purge(j_purge, &jacc) ;
  184.  
  185. /* Verb grammer check */
  186. /* see if the sentence is of a command sentax */
  187. for (i = 0; i <= verb_max; i++) {
  188.     if (sent[0] == verb_table[i]) goto synonym ;
  189. }
  190.  
  191. /* the first word is --not-- a verb, so one must be swapped in */
  192. if (jacc != 1) for (j = 1; j <= jacc-1; j++) {
  193.     /* Check to see if the word is a move command */
  194.     if (sent[j] <= 10) {
  195.         tag[V_MOVE] = TRUE ;
  196.         i_ws = sent[0] ;
  197.         sent[0] = sent[j] ;
  198.         sent[j] = i_ws ;
  199.         goto synonym ;
  200.     }
  201.     /* if not a move command then check the verb table */
  202.     for (i = 0; i <= verb_max; i++) {
  203.         if (sent[j] == verb_table[i]) {
  204.             i_ws = sent[0] ;
  205.             sent[0] = sent[j] ;
  206.             sent[j] = i_ws ;
  207.             goto synonym ;
  208.         }
  209.     }
  210. }
  211.  
  212. /* Check to see if this is a "question" sentence */
  213. for (i = 0; i <= quest_max; i++) {
  214.     if (sent[0] == quest[i]) {
  215.         /* shift the sentence over and load in "question" */ 
  216.         for (j = jacc; j >= 0; j--) sent[j+1] = sent[j] ;
  217.         sent[0] = V_QUESTION ;
  218.         tag[V_QUESTION] = TRUE ; 
  219.         if (++jacc == 2) {
  220.         /* Sentence is a one word command */
  221.             tag[V_VERB_ONLY] = TRUE ;
  222.             tag[sent[1]] = TRUE ;
  223.             verb = V_QUESTION ;
  224.             return ;
  225.         }
  226.         goto synonym ;
  227.     } 
  228. }
  229.  
  230. /* Verb error routine */
  231. printf ("If there was a verb in that sentence, I didn't understand ") ;
  232. printf ("it.\n") ;
  233. goto input ;
  234.  
  235. synonym:
  236. /* prescan for verb connected movement commands */
  237. switch(sent[0]) { 
  238. case V_go:
  239. case V_move:
  240. case V_walk:
  241. case V_run:
  242. case V_jump:
  243. case V_bop:
  244. case V_hop:
  245. case V_stroll:
  246. case V_saunter:
  247. case V_swagger:
  248.     sw_movement = TRUE ;
  249.     break ;
  250. default:
  251.     sw_movement = FALSE ;
  252. }
  253.  
  254. /* adverb scan, sent[0] is the verb */
  255. sw_adverb = FALSE ;
  256. sw_adverb_fnd = FALSE ;
  257. for (i = 0; i <= adv_max; i++) {
  258.     for (j = 1; j <= jacc-1; j++) {
  259.         /* see if this is an adverb */
  260.         if (sent[j] == adverb[i][Av_adv]) {
  261.             j_point = j ;
  262.             sw_adverb = TRUE ;
  263.  
  264.             /* does the sentence have the companion verb? */
  265.             if (adverb[i][Av_verb_old] == sent[0]) {
  266.                 sent[0] = adverb[i][Av_verb_new] ;
  267.                 sw_adverb = FALSE ;
  268.                 sw_adverb_fnd = TRUE ;
  269.  
  270.             /* purge processed adverb from sentence */
  271.                 purge(j, &jacc) ;
  272.             }
  273.         }
  274.     }
  275. }
  276.  
  277. /* purge unprocessed adverb from sentence */
  278. if (sw_adverb && (!sw_movement)) purge(j_point, &jacc) ;
  279.  
  280. /* scan the sentence for the movement direction */
  281. if ((!sw_adverb_fnd) && sw_movement) {
  282.     for (j = 0; j <= jacc-1; j++) {
  283.         if (sent[j] <= 10) {
  284.             tag[V_MOVE] = TRUE ;
  285.             tag[V_DIRECTION] = TRUE ;
  286.             verb = sent[j] ;
  287.             return ;
  288.         }
  289.         if (sent[j] == V_LINE_END) break ;
  290.     }
  291.     printf("Where to?  In what direction?\n") ;
  292.     goto input ;
  293.  
  294. tag[sent[0]] = TRUE ;  /* activate the tag for the verb */
  295.  
  296. if (jacc == 1) {
  297. /* Sentence is a one word command */
  298.     tag[V_VERB_ONLY] = TRUE ;
  299.     verb = sent[0] ;
  300.     if (sent[0] <= 4) return ; /* first 5 elements are reserved */
  301.     return ;
  302. }
  303.  
  304. /* Load the "tag" matrix for detected words and synonyms */
  305. for (j=1; j <= 19; j++) {
  306.     if (sent[j] == V_LINE_END) break ;
  307.     if (sent[j] <= 10) tag[V_DIRECTION] = TRUE ;
  308.     if (sent[j] <= 4) continue ; /* first 5 elements are reserved */
  309.     tag[sent[j]] = TRUE ;  /* activate an element for each word */
  310.  
  311.     /* Deal with synonym nouns */
  312.     switch(sent[j]) {
  313.  
  314.     case V_automatic:
  315.     case V_AUTO:
  316.         tag[V_auto] = TRUE ;
  317.         continue ;
  318.  
  319.     case V_bar:
  320.         tag[V_gold] = TRUE ;
  321.         continue ;
  322.  
  323.     case V_beer:
  324.     case V_fourex:
  325.     case V_Fourex:
  326.         tag[V_can] = TRUE ;
  327.         continue ;
  328.  
  329.     case V_cockroaches:
  330.         tag[V_PLURAL] = TRUE ;
  331.         tag[V_cockroach] = TRUE ;
  332.         continue ;
  333.  
  334.     case V_diamond:
  335.         tag[V_ring] = TRUE ;
  336.         continue ;
  337.  
  338.     case V_doormat:
  339.         tag[V_mat] = TRUE ;
  340.         continue ;
  341.  
  342.     case V_drop:
  343.         tag[V_bear] = TRUE ;
  344.         continue ;
  345.  
  346.     case V_everything:
  347.         tag[V_all] = TRUE ;
  348.         continue ;
  349.  
  350.     case V_lager:
  351.         tag[V_bottle] = TRUE ;
  352.         continue ;
  353.  
  354.     case V_fuse:
  355.         tag[V_cap] = TRUE ;
  356.         continue ;
  357.  
  358.     case V_gleeps:
  359.         tag[V_PLURAL] = TRUE ;
  360.         tag[V_gleep] = TRUE ;
  361.         continue ;
  362.  
  363.     case V_hoop:
  364.         tag[V_snake] = TRUE ;
  365.         continue ;
  366.  
  367.     case V_M16:
  368.     case V_m16:
  369.     case V_gun:
  370.         tag[V_rifle] = TRUE ;
  371.         continue ;
  372.  
  373.     case V_kangaroos:
  374.         tag[V_PLURAL] = TRUE ;
  375.         tag[V_kangaroo] = TRUE ;
  376.         continue ;
  377.  
  378.     case V_magazine:
  379.     case V_ammo:
  380.         tag[V_clip] = TRUE ;
  381.         continue ;
  382.  
  383.     case V_mail:
  384.     case V_envelope:
  385.         tag[V_letter] = TRUE ;
  386.         continue ;
  387.  
  388.     case V_matches:
  389.         tag[V_PLURAL] = TRUE ;
  390.         tag[V_match] = TRUE ;
  391.         continue ;
  392.  
  393.     case V_Ned:
  394.     case V_kelly:
  395.     case V_Kelly:
  396.         tag[V_ned] = TRUE ;
  397.         continue ;
  398.  
  399.     case V_off_q:
  400.         tag[V_off] = TRUE ;
  401.         continue ;
  402.  
  403.     case V_on_q:
  404.         tag[V_on] = TRUE ;
  405.         continue ;
  406.  
  407.     case V_plan:
  408.         tag[V_map] = TRUE ;
  409.         continue ;
  410.  
  411.     case V_painting:
  412.         tag[V_picture] = TRUE ;
  413.         continue ;
  414.  
  415.     case V_doors:
  416.         tag[V_PLURAL] = TRUE ;
  417.         tag[V_door] = TRUE ;
  418.         continue ;
  419.  
  420.     case V_pills:
  421.     case V_packet:
  422.         tag[V_PLURAL] = TRUE ;
  423.     case V_atropine:
  424.         tag[V_pill] = TRUE ;
  425.         continue ;
  426.  
  427.     case V_safety:
  428.     case V_SAFE:
  429.         tag[V_safe] = TRUE ;
  430.         continue ;
  431.  
  432.     case V_silver:
  433.         tag[V_coin] = TRUE ;
  434.         continue ;
  435.  
  436.     case V_spinifexes:
  437.         tag[V_PLURAL] = TRUE ;
  438.         tag[V_spinifex] = TRUE ;
  439.         continue ;
  440.  
  441.     case V_stick:
  442.         tag[V_dynamite] = TRUE ;
  443.         continue ;
  444.  
  445.     case V_switch:
  446.         tag[V_button] = TRUE ;
  447.         continue ;
  448.  
  449.     case V_treasure:
  450.         tag[V_all] = TRUE ;
  451.         continue ;
  452.  
  453.     case V_I:
  454.         tag[V_single] = TRUE ;
  455.         continue ;
  456.  
  457.     case V_III:
  458.         tag[V_triple] = TRUE ;
  459.         continue ;
  460.  
  461.     case V_zero:
  462.         tag[V_0] = TRUE ;
  463.         continue ;
  464.  
  465.     case V_forty_nine:
  466.         tag[V_49] = TRUE ;
  467.         continue ;
  468.  
  469.     case V_sixty_seven:
  470.         tag[V_67] = TRUE ;
  471.         continue ;
  472.  
  473.     case V_eighty_two:
  474.         tag[V_82] = TRUE ;
  475.         continue ;
  476.  
  477.     default:
  478.         continue ;
  479.     }
  480. } /* end of sentence tag word scan */
  481. verb = sent[0] ;
  482. return ;
  483.  
  484. } /* --- end of "parse" subroutine --- */
  485.  
  486. void purge(k_start, k_finish)
  487. /***********************************/
  488. /*                                 */
  489. /*   Sentence Purging Subroutine   */
  490. /*                                 */
  491. /* Version: Mk 1.0  3 March 1990   */
  492. /*                                 */
  493. /***********************************/
  494.  
  495. int k_start, *k_finish ;
  496. {
  497. register int k ;
  498. int k_end ;
  499.  
  500. k_end = *k_finish ;
  501. for (k = k_start; k <= k_end-1; k++) sent[k] = sent[k+1] ;
  502. *k_finish = --k_end ;
  503. } /* --- end of "purge" subroutine --- */
  504.  
  505. void filler()
  506. /***********************************/
  507. /*                                 */
  508. /*        Looker Subroutine        */
  509. /*                                 */
  510. /* Version: Mk 1.0  18 August 1989 */
  511. /*                                 */
  512. /***********************************/
  513. {
  514.  
  515. if (tag[V_VERB_ONLY]) {
  516.     printf("Fill what?\n") ;
  517.     return ;
  518. }
  519. if (tag[V_can]) {
  520.     if (object[O_can][J_loc] != B_have) 
  521. printf("You don't have the Fourex can in your possession!\n") ;
  522. else printf("I can't do it!  There's a hole in the can's bottom.\n") ;
  523.     return ;
  524. }
  525. if (tag[V_bottle]) {
  526.     if (object[O_bottle][J_loc] != B_have) 
  527. printf("You don't have the bottle in your possession!\n") ;
  528. else printf("I can't do it!  The bottle has a crack in it's bottom.\n");
  529.     return ;
  530. }
  531. printf("I can't fill that!\n") ;
  532. } /* --- end of the "filler" subroutine --- */
  533.  
  534. void looker(n)
  535. /***********************************/
  536. /*                                 */
  537. /*        Looker Subroutine        */
  538. /*                                 */
  539. /* Version: Mk 1.0  18 August 1989 */
  540. /*                                 */
  541. /***********************************/
  542. int n ;
  543. {
  544. #ifdef __TURBOC__
  545. void long_descp(int), describe(int), objlooker(int), gleeper(int) ;
  546. void actor(int), rdtxt(int) ;
  547. #endif
  548.  
  549. int m ;
  550.  
  551. /* an isolated "look" means to just look at the room */
  552. if (tag[V_VERB_ONLY]) { 
  553.     /* goto long description test*/
  554.     if ((room[n][M_rm_type] == T_was_long)||(n == R_lift_inside))
  555.        long_descp(n);
  556.     else describe (n) ;
  557.     objlooker(n) ; /* Check if there are objects in the room */
  558.     gleeper(n) ;   /* check for gleeps and update the gleep count */
  559.     /* describe unmovable action objects and status */
  560.     if (room[n][M_rm_type] == T_action_obj) actor(n) ;
  561.     return ;
  562. }
  563.  
  564. /* Gleep tank */
  565. if (tag[V_tank]) {
  566.     if (n == R_gleep_tank) {
  567. printf("You look inside the gleep tank and see a blue fluid which\n") ;
  568. printf("smells of chlorine") ;
  569.         if (gleep_score == 0) {
  570. printf(".\n") ;
  571.             return ;
  572.         }
  573.         if (gleep_score == 1) {
  574. printf(" and a single gleep submerged in the fluid.\n") ;
  575.             return ;
  576.         }
  577. printf(" and %d gleeps submerged in the fluid.\n",
  578.         gleep_score) ;
  579.         return ;
  580.     }
  581.     else {
  582.         printf("There is no gleep tank here!\n") ;
  583.         return ;
  584.     }
  585. }
  586.  
  587. /* wall safe */
  588. if (tag[V_safe]) {
  589.     if ((n == R_office_mang)&&
  590.         (room[R_office_mang][M_rm_status] >= S_revealed)) {
  591.         m = O_safe ;
  592.         rdtxt(m);
  593.     }
  594.     else printf("I see no safe here for me to describe.\n");
  595.     return ;
  596. }
  597.  
  598. for (;;) {
  599.     /* map from the manager's office */
  600.     if (tag[V_map]) {
  601.         m = O_map_frag ;
  602.         break ;
  603.     }
  604.  
  605.     /* Fourex can */
  606.     if (tag[V_can]) {
  607.         m = O_can ;
  608.         break ;
  609.     }
  610.  
  611.     /* Atropine pills */
  612.     if (tag[V_pill]) {
  613.         m = O_pills ;
  614.         break ;
  615.     }
  616.  
  617.     /* Qadaffi's letter bomb */
  618.     if (tag[V_letter]) {
  619.         m = O_letter ;
  620.         break ;
  621.     }
  622.  
  623.     /* paper from the safe */
  624.     if (tag[V_paper]) {
  625.          m = O_paper ;
  626.         break ;
  627.     }
  628.  
  629.     /* ammo clip */            
  630.     if (tag[V_clip]) {
  631.         m = O_clip ;
  632.         break ;
  633.     }
  634.  
  635.     /* orange clip */
  636.     if (tag[V_org_clip]) {
  637.         m = O_org_clip ;
  638.         break ;
  639.     }
  640.  
  641.     /* rifle */
  642.     if (tag[V_rifle]) {
  643.         m = O_rifle ;
  644.         break ;
  645.     }
  646.  
  647.     /* Semtex detector */
  648.     if (tag[V_detector]) {
  649.         m = O_detector ;
  650.         break ;
  651.     }
  652.  
  653.     /* Deal with unreadable objects */
  654.     printf("There is nothing more that I can describe about it.\n");
  655.     return ;
  656. } /* end of infinite for block */
  657.  
  658. if (object[m][J_loc] == B_have) rdtxt(m);
  659. else 
  660. printf("I can examine an object only if it is in my possession.\n");
  661.  
  662. } /* --- end of the "looker" subroutine --- */
  663.  
  664. void pass()
  665. /***********************************/
  666. /*                                 */
  667. /*        Password Subroutine      */
  668. /*                                 */
  669. /* Version: Mk 1.0  29 July 1989   */
  670. /*                                 */
  671. /***********************************/
  672. {
  673.  
  674. #ifdef __TURBOC__
  675. void exit(int);
  676. char getch(void) ;
  677. #endif
  678.  
  679. register int i ;
  680. char chr ;
  681. static char *passwd = "2Xngootx7Ysd4Du9" ;
  682.  
  683. /* Request password */
  684. printf("Enter password:  ") ;
  685.  
  686. #ifndef __TURBOC__
  687. for (i = 2; i <= 7; i++) {
  688.     chr = getchar() ;
  689.     if (chr+i-1 != passwd[i]) exit(0) ;
  690. }    
  691. if (getchar() != '\n') exit(0) ;
  692. printf(".\n") ;  /* indicate that the password was accepted */
  693. #endif
  694.  
  695. #ifdef __TURBOC__
  696. for (i = 2; i <= 7; i++) {
  697.     chr = getch() ;
  698.     if (chr+i-1 != passwd[i]) { 
  699.         for (;;) if (getch() == 3) break ;
  700.         printf("\r                    \n") ;
  701.         exit(0) ;
  702.     }
  703. }
  704. printf("\r.                     \n") ;
  705. #endif
  706.  
  707. sw_wizard = TRUE ; /* toggle wizard switch */
  708.  
  709. } /* --- end of the "pass" subroutine */
  710.