home *** CD-ROM | disk | FTP | other *** search
/ Teach Yourself Game Programming in 21 Days / TYGAMES_R.ISO / source / day_19 / shadow.c next >
Encoding:
C/C++ Source or Header  |  1994-09-13  |  62.2 KB  |  2,247 lines

  1.  
  2. // I N C L U D E S ///////////////////////////////////////////////////////////
  3.  
  4. #include <io.h>
  5. #include <conio.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <dos.h>
  9. #include <bios.h>
  10. #include <fcntl.h>
  11. #include <memory.h>
  12. #include <malloc.h>
  13. #include <math.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16.  
  17. // D E F I N E S /////////////////////////////////////////////////////////////
  18.  
  19. // size of universe in blocks
  20.  
  21. #define NUM_ROWS               32
  22. #define NUM_COLUMNS            32
  23.  
  24. // id's for objects and geometry in universe
  25.  
  26. #define EMPTY_ID               ' '
  27. #define WALL_ID                '*'
  28.  
  29. #define LAMP_ID                'l'
  30. #define SANDWICH_ID            's'
  31. #define KEYS_ID                'k'
  32.  
  33. // general directions
  34.  
  35. #define EAST                   0
  36. #define WEST                   1
  37. #define NORTH                  2
  38. #define SOUTH                  3
  39.  
  40. // language details
  41.  
  42. #define MAX_TOKENS             64
  43. #define NUM_TOKENS             28
  44.  
  45. #define FIRST_WORD             0
  46. #define SECOND_WORD            1
  47. #define THIRD_WORD             2
  48. #define FOURTH_WORD            3
  49. #define FIFTH_WORD             4
  50.  
  51. #define OBJECT_START           50
  52.  
  53. #define OBJECT_LAMP            50
  54. #define OBJECT_SANDWICH        51
  55. #define OBJECT_KEYS            52
  56.  
  57. #define OBJECT_END             52
  58.  
  59. // directions (adjectives)
  60.  
  61. #define DIR_1_START            100
  62.  
  63. #define DIR_1_EAST             100
  64. #define DIR_1_WEST             101
  65. #define DIR_1_NORTH            102
  66. #define DIR_1_SOUTH            103
  67.  
  68. #define DIR_1_END              103
  69.  
  70.  
  71.  
  72. #define DIR_2_START            150
  73.  
  74. #define DIR_2_FORWARD          150
  75. #define DIR_2_BACKWARD         151
  76. #define DIR_2_RIGHT            152
  77. #define DIR_2_LEFT             153
  78.  
  79. #define DIR_2_END              153
  80.  
  81.  
  82. // define actions (verbs)
  83.  
  84. #define ACTION_START           200
  85.  
  86. #define ACTION_MOVE            200
  87. #define ACTION_TURN            201
  88. #define ACTION_SMELL           202
  89. #define ACTION_LOOK            203
  90. #define ACTION_LISTEN          204
  91. #define ACTION_PUT             205
  92. #define ACTION_GET             206
  93. #define ACTION_EAT             207
  94. #define ACTION_INVENTORY       208
  95. #define ACTION_WHERE           209
  96. #define ACTION_EXIT            210
  97.  
  98. #define ACTION_END             210
  99.  
  100. // articles
  101.  
  102. #define ART_START              300
  103.  
  104. #define ART_THE                300
  105.  
  106. #define ART_END                300
  107.  
  108. // prepositions
  109.  
  110. #define PREP_START             325
  111.  
  112. #define PREP_IN                325
  113. #define PREP_ON                326
  114. #define PREP_TO                327
  115. #define PREP_DOWN              328
  116.  
  117. #define PREP_END               328
  118.  
  119. // the phrases that add meaning to us, but not to the computer
  120.  
  121. #define PHRASE_TO              0
  122. #define PHRASE_THE             1
  123. #define PHRASE_TO_THE          2
  124. #define PHRASE_DOWN            3
  125. #define PHRASE_DOWN_THE        4
  126.  
  127. // S T R U C T U R E S ///////////////////////////////////////////////////////
  128.  
  129. // this is the structure for a single token
  130.  
  131. typedef struct token_typ
  132.         {
  133.  
  134.         char symbol[16];   // the string that represents the token
  135.         int value;         // the integer value of the token
  136.  
  137.         } token, *token_ptr;
  138.  
  139. // this is the structure used to hold a single string that is used to
  140. // describe something in the game like a smell, sight, sound...
  141.  
  142. typedef struct info_string_typ
  143.         {
  144.         char type;        // the type of info string i.e. what does it describe
  145.         char string[100]; // the actual description string
  146.  
  147.         } info_string, *info_string_ptr;
  148.  
  149. // this structure holds everything pertaining to the player
  150.  
  151. typedef struct player_typ
  152.         {
  153.         char name[16];   // name of player
  154.         int x,y;         // postion of player
  155.         int direction;   // direction of player, east,west north,south
  156.  
  157.         char inventory[8]; // objects player is holding (like pockets)
  158.         int num_objects;   // number of objects player is holding
  159.  
  160.         } player, *player_ptr;
  161.  
  162. // this structure holds an object
  163.  
  164. typedef struct object_typ
  165.         {
  166.         char thing;     // the actual object
  167.         int x,y;        // position of object in universe
  168.  
  169.         } object, *object_ptr;
  170.  
  171. // P R O T O T Y P E S //////////////////////////////////////////////////////
  172.  
  173. void Introduction();
  174.  
  175. int Vision_System(int depth,
  176.                   int direction,
  177.                   object *stuff,
  178.                   int *num_objects);
  179.  
  180. int Check_For_Phrase(int phrase,int index);
  181.  
  182. void Print_Info_Strings(info_string strings[],char where);
  183.  
  184. char *Get_Line(char *buffer);
  185.  
  186. int Get_Token(char *input,char *output,int *current_pos);
  187.  
  188. int Extract_Tokens(char *string);
  189.  
  190. void Verb_Parser(void);
  191.  
  192. int Verb_MOVE(void);
  193.  
  194. int Verb_TURN(void);
  195.  
  196. int Verb_SMELL(void);
  197.  
  198. int Verb_LOOK(void);
  199.  
  200. int Verb_LISTEN(void);
  201.  
  202. int Verb_PUT(void);
  203.  
  204. int Verb_GET(void);
  205.  
  206. int Verb_EAT(void);
  207.  
  208. int Verb_INVENTORY(void);
  209.  
  210. int Verb_EXIT(void);
  211.  
  212. int Verb_WHERE(void);
  213.  
  214. // G L O B A L S //////////////////////////////////////////////////////////////
  215.  
  216. // this is the entire "language" of the language.
  217.  
  218. token language[MAX_TOKENS] = {
  219.  
  220.  {"LAMP",      OBJECT_LAMP     },
  221.  {"SANDWICH",  OBJECT_SANDWICH },
  222.  {"KEYS",      OBJECT_KEYS     },
  223.  {"EAST",      DIR_1_EAST      },
  224.  {"WEST",      DIR_1_WEST      },
  225.  {"NORTH",     DIR_1_NORTH     },
  226.  {"SOUTH",     DIR_1_SOUTH     },
  227.  {"FORWARD",   DIR_2_FORWARD   },
  228.  {"BACKWARD",  DIR_2_BACKWARD  },
  229.  {"RIGHT",     DIR_2_RIGHT     },
  230.  {"LEFT",      DIR_2_LEFT      },
  231.  {"MOVE",      ACTION_MOVE     },
  232.  {"TURN",      ACTION_TURN     },
  233.  {"SMELL",     ACTION_SMELL    },
  234.  {"LOOK",      ACTION_LOOK     },
  235.  {"LISTEN",    ACTION_LISTEN   },
  236.  {"PUT",       ACTION_PUT      },
  237.  {"GET",       ACTION_GET      },
  238.  {"EAT",       ACTION_EAT      },
  239.  {"INVENTORY", ACTION_INVENTORY},
  240.  {"WHERE",     ACTION_WHERE    },
  241.  {"EXIT",      ACTION_EXIT     },
  242.  {"THE",       ART_THE         },
  243.  {"IN",        PREP_IN         },
  244.  {"ON",        PREP_ON         },
  245.  {"TO",        PREP_TO         },
  246.  {"DOWN",      PREP_DOWN       },
  247.  
  248. };
  249.  
  250. // now for the definition of the universe and the objects within it
  251.  
  252. // this array holds the geometry of the universe
  253.  
  254. // l - living room
  255. // b - bedroom
  256. // k - kitchen
  257. // w - washroom
  258. // h - hall way
  259. // r - restroom
  260. // e - entry way
  261. // o - office
  262.  
  263. //           ^
  264. //         NORTH
  265. //
  266. // < WEST           EAST >
  267. //
  268. //         SOUTH
  269. //           v
  270.  
  271. char *universe_geometry[NUM_ROWS]={"********************************",
  272.                                    "*lllllllll*bbbbbbbbbbbbbbbbbbbb*",
  273.                                    "*llllllllll*bbbbbbbbbbbbbbbbbbb*",
  274.                                    "*lllllllllll*bbbbbbbbbbbbbbbbbb*",
  275.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  276.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  277.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  278.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  279.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  280.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  281.                                    "*llllllllllll*bbbbbbbbbbbbbbbbb*",
  282.                                    "*llllllllllll*bbbb*rrr**********",
  283.                                    "*lllllllllllhhhhhh*rrrrrrrrrrrr*",
  284.                                    "*lllllllllllhhhhhh*rrrrrrrrrrrr*",
  285.                                    "*lllllllllhhh******rrrrrrrrrrrr*",
  286.                                    "*********hhhh*rrrrrrrrrrrrrrrrr*",
  287.                                    "*kkkkkkk*hhhh*rrrrrrrrrrrrrrrrr*",
  288.                                    "*kkkkkkk*hhhh*rrrrrrrrrrrrrrrrr*",
  289.                                    "*kkkkkkk*hhhh*rrrrrrrrrrrrrrrrr*",
  290.                                    "*kkkkkkkhhhhh*******************",
  291.                                    "*kkkkkkkhhhhhhhhhhhwwwwwwwwwwww*",
  292.                                    "*kkkkkkkhhhhhhhhhhhwwwwwwwwwwww*",
  293.                                    "*kkkkkkk*hhhhhhhhhhwwwwwwwwwwww*",
  294.                                    "*kkkkkkk*hhhh*ooooo*************",
  295.                                    "*kkkkkkk*hhhh*ooooooooooooooooo*",
  296.                                    "*kkkkkkk*hhhh*ooooooooooooooooo*",
  297.                                    "*kkkkkk*hhhhh*ooooooooooooooooo*",
  298.                                    "*******hhhhhh*ooooooooooooooooo*",
  299.                                    "*eeeeeeeeeeee*ooooooooooooooooo*",
  300.                                    "*eeeeeeeeeeee*ooooooooooooooooo*",
  301.                                    "*eeeeeeeeeeee*ooooooooooooooooo*",
  302.                                    "********************************",};
  303.  
  304. // this array holds the objects within the universe
  305.  
  306. // l - lamp
  307. // s - sandwich
  308. // k - keys
  309.  
  310. //           ^
  311. //         NORTH
  312. //
  313. // < WEST           EAST >
  314. //
  315. //         SOUTH
  316. //           v
  317.  
  318. char *universe_objects[NUM_ROWS]={"                                ",
  319.                                   " l                            k ",
  320.                                   "                                ",
  321.                                   "                                ",
  322.                                   "                                ",
  323.                                   "                                ",
  324.                                   "                                ",
  325.                                   "                                ",
  326.                                   "                                ",
  327.                                   " l                              ",
  328.                                   "                                ",
  329.                                   "                                ",
  330.                                   "                                ",
  331.                                   "                                ",
  332.                                   "                                ",
  333.                                   "                                ",
  334.                                   "                                ",
  335.                                   "                                ",
  336.                                   "                                ",
  337.                                   "                                ",
  338.                                   "                                ",
  339.                                   "                                ",
  340.                                   "                                ",
  341.                                   "  s                             ",
  342.                                   "                                ",
  343.                                   "                                ",
  344.                                   "                                ",
  345.                                   "                                ",
  346.                                   "          s                     ",
  347.                                   "                             l  ",
  348.                                   "                                ",
  349.                                   "                                ",};
  350.  
  351. // these info strings hold the views in each room
  352.  
  353. info_string views[]={
  354.  
  355. {'l',"You see an expansive white room with a vaulted ceiling. The walls are adorned "},
  356. {'l',"with medevil art.  To the North, is a plate glass window through which colored"},
  357. {'l',"strands of light pierce. They reflect off the carpeted floor and create a     "},
  358. {'l',"silhouette of the towering pines just outdside. In the Northeast corner of    "},
  359. {'l',"the room, you see a fire place with a half burnt log in it. Finally, against  "},
  360. {'l',"the West wall there's a white leather couch and in each corner of the room    "},
  361. {'l',"are large green palms potted in hexogonal black pots.                         "},
  362.  
  363. {'b',"You see a black lacquer bedroom set surrounding a king size platform bed."},
  364. {'b',"On the walls, you see pictures of mystical landscapes and underwater cities.   "},
  365. {'b',"To the North there is a window thru which you see a group of large trees just  "},
  366. {'b',"beyond a small pond. On the floor of the room you see black silk stockings     "},
  367. {'b',"and lingerie thrown with abandon about the area.                               "},
  368.  
  369. {'k',"You are surrounded by stone washed granite counters. On the counters are the"},
  370. {'k',"normal appliances found in a kitchen. To the West there is a large glass    "},
  371. {'k',"door refrigerator with a varitable plethora of food. Against the South wall"},
  372. {'k',"there is a small nook with a white refuge container. Above your head dangle"},
  373. {'k',"down many cooking utensils and exotic pans suspended from a anodized        "},
  374. {'k',"aluminum structure.                                                         "},
  375.  
  376. {'w',"There is a large vanity mirror and a black porcellin wash basin. To the East"},
  377. {'w',"is a rack of black and white towels hung on brass rails. On the counter     "},
  378. {'w',"surrounding the walls there are small spherically shaped soap balls in a    "},
  379. {'w',"myriad of colors set in cyrstal dishes. The floor is made of black and white"},
  380. {'w',"marble with a hint of grey running thru it.                                 "},
  381.  
  382. {'h',"You see an ordinary hallway with track lighting above head. "},
  383.  
  384. {'r',"You see a large wash area with two basins. To the West through a glass  "},
  385. {'r',"enclosure you see the outline of a young woman apperantly bathing... To "},
  386. {'r',"the East you see a second smaller room with many plants hanging from the"},
  387. {'r',"celing along with the shadow of a dark,muscular man moving around. On   "},
  388. {'r',"the floor below you are plush tapestries of Egyption origin.            "},
  389.  
  390. {'e',"To the West you see a small opening into what appears to be a kitchen.        "},
  391. {'e',"The lights are low and you can't make out much more in this direction.        "},
  392. {'e',"Under your feet is a large black rectangular cut of carpet. Lastly, leading to"},
  393. {'e',"the East and North are hallways to the remainder of the house.                "},
  394.  
  395. {'o',"You are astounded by the amount of computer equipment in every corner of the "},
  396. {'o',"room. To the South is a Silicon Graphics OYNX Super Computer, the screen of  "},
  397. {'o',"which seems to displaying a mesmorizing array of mathematical equations. To  "},
  398. {'o',"the North you are faced with literally hundreds of books on every topic from "},
  399. {'o',"quantum mechanics to molecular bio-chemistry. Against the East wall there    "},
  400. {'o',"is a full collection of electrical engineering equipment with a oscilloscope "},
  401. {'o',"displaying a curious waveform apparently an input from a black box resting on"},
  402. {'o',"the floor. As you look around the walls of the room, you see schematics of   "},
  403. {'o',"digital hardware and paintings of great scientific pioneers such as Einstein,"},
  404. {'o',"Newton and Maxwell. Strewn about the floor are small electronic              "},
  405. {'o',"components and pieces of paper with scribbles upon them.                     "},
  406. {'X',""},  // terminate
  407.  
  408. };
  409.  
  410. // these info strings hold the smells in each room
  411.  
  412. info_string smells[]={
  413.  
  414. {'l',"You smell the sweet odor of Jasmine with an undertone of potpourri. "},
  415.  
  416. {'b',"The sweet smell of perfume dances within your nostrils...Realities possibly. "},
  417.  
  418. {'k',"You take a deep breath and your senses are tantallized with the smell of"},
  419. {'k',"tender breasts of chicken marinating in a garlic sauce. Also, there is "},
  420. {'k',"a sweet berry smell emminanting from the oven.                          "},
  421.  
  422. {'w',"You are almost overwhealmed by the smell of bathing fragrance as you"},
  423. {'w',"inhale.                                                              "},
  424.  
  425. {'h',"You smell nothing to make note of. "},
  426.  
  427. {'r',"Your nose is filled with steam and the smell of baby oil... "},
  428.  
  429. {'e',"You smell pine possible from the air coming thru a small orifice near"},
  430. {'e',"the front door.                                                            "},
  431.  
  432. {'o',"You are greeted with the familiar odor of burning electronics. As you inhale"},
  433. {'o',"a second time, you can almost taste the rustic smell of aging books.        "},
  434. {'X',""}, // terminate
  435.  
  436. };
  437.  
  438. // these info strings hold the sounds in each room
  439.  
  440. info_string sounds[]={
  441.  
  442. {'l',"You hear the faint sounds of Enigma playing in the background along with"},
  443. {'l',"the wind howling against the exterior of the room.                      "},
  444.  
  445. {'b',"You hear the wind rubbing against the window making a sound similar to"},
  446. {'b',"sheets being pulled off a bed.                                        "},
  447.  
  448. {'k',"You hear expansion of the hot ovens along with the relaxing sounds produced"},
  449. {'k',"by the cooling fans.                                                       "},
  450.  
  451. {'w',"You hear nothing but a slight echo in the heating ducts."},
  452.  
  453. {'h',"You hear the sounds of music, but you can't make out any of the words or"},
  454. {'h',"melodies.                                                               "},
  455.  
  456. {'r',"You hear the sound of driping water and the whispers of a femal voice"},
  457. {'r',"ever so faintly in the background.                                   "},
  458.  
  459. {'e',"You hear the noises of the outside world muffled by the closed door to the"},
  460. {'e',"South.                                                                    "},
  461.  
  462. {'o',"You hear nothing but the perpetual hum of all the cooling fans within the"},
  463. {'o',"electronic equipment.                                                    "},
  464. {'X',""},
  465.  
  466. };
  467.  
  468. int sentence[8];               // this array holds the current sentence
  469. int num_tokens;                // number of words in current sentecne
  470.  
  471. // this is the player
  472.  
  473. player you={"Andre'",10,29,NORTH,{' ',' ',' ',' ',' ',' ',' ',' '},0};
  474.  
  475. int global_exit=0;             // global exit flag
  476.  
  477. char global_input[128],        // input string
  478.      global_output[128];       // output string
  479.  
  480. // F U N C T I O N S //////////////////////////////////////////////////////////
  481.  
  482. char *Get_Line(char *buffer)
  483. {
  484. // this function gets a single line of input and tolerates white space
  485.  
  486. int c,index=0;
  487.  
  488. // loop while user hasn't hit return
  489.  
  490. while((c=getch())!=13)
  491.      {
  492.  
  493. // implement backspace
  494.  
  495.      if (c==8 && index>0)
  496.         {
  497.  
  498.         buffer[--index] = ' ';
  499.         printf("%c %c",8,8);
  500.  
  501.         } // end if backspace
  502.      else
  503.      if (c>=32 && c<=122)
  504.         {
  505.         buffer[index++] = c;
  506.         printf("%c",c);
  507.  
  508.         } // end if in printable range
  509.  
  510.      } // end while
  511.  
  512. // terminate string
  513.  
  514. buffer[index] = 0;
  515.  
  516. // return pointer to buffer or NULL
  517.  
  518. if (strlen(buffer)==0)
  519.    return(NULL);
  520. else
  521. return(buffer);
  522.  
  523. } // end Get_Line
  524.  
  525. ////////////////////////////////////////////////////////////////////////////////
  526.  
  527. int Get_Token(char *input,char *output,int *current_pos)
  528. {
  529.  
  530. int index,   // loop index and working index
  531.     start,   // points to start of token
  532.     end;     // points to end of token
  533.  
  534. // set current positions
  535.  
  536. index=start=end=*current_pos;
  537.  
  538. // eat white space
  539.  
  540. while(isspace(input[index]) || ispunct(input[index]))
  541.      {
  542.  
  543.      index++;
  544.  
  545.      } // end while
  546.  
  547. // test if end of string found
  548.  
  549. if (input[index]==NULL)
  550.    {
  551.    // emit nothing
  552.  
  553.    strcpy(output,"");
  554.    return(0);
  555.  
  556.    } // end if no more tokens
  557.  
  558. // at this point, we must have a token of some kind, so find the end of it
  559.  
  560. start = index; // mark front of it
  561. end   = index;
  562.  
  563. // find end of Token
  564.  
  565. while(!isspace(input[end]) && !ispunct(input[end]) && input[end]!=NULL)
  566.      {
  567.  
  568.      end++;
  569.  
  570.      } // end while
  571.  
  572. // build up output string
  573.  
  574. for (index=start; index<end; index++)
  575.     {
  576.  
  577.     output[index-start] = toupper(input[index]);
  578.  
  579.     } // end copy string
  580.  
  581. // place terminator
  582.  
  583. output[index-start] = 0;
  584.  
  585. // update current string position
  586.  
  587. *current_pos  = end;
  588.  
  589. return(end);
  590.  
  591. } // end Get_Token
  592.  
  593. ///////////////////////////////////////////////////////////////////////////////
  594.  
  595. int Extract_Tokens(char *string)
  596. {
  597. // this function breaks the input string down into tokens and fills up
  598. // the global sentence array with the tokens so that it can be processed
  599.  
  600. int curr_pos=0,      // current position in string
  601.     curr_token=0,    // current token number
  602.     found,           // used to flag if the token is valid in language
  603.     index;           // loop index
  604.  
  605. char output[16];
  606.  
  607. // reset number of tokens and clear the sentence out
  608.  
  609. num_tokens=0;
  610.  
  611. for (index=0; index<8; index++)
  612.     sentence[index]=0;
  613.  
  614. // extract all the words in the sentence (tokens)
  615.  
  616. while(Get_Token(string,output,&curr_pos))
  617.      {
  618.  
  619.      // test to see if this is a valid token
  620.  
  621.      for (index=0,found=0; index<NUM_TOKENS; index++)
  622.          {
  623.  
  624.          // do we have a match?
  625.  
  626.          if (strcmp(output,language[index].symbol)==0)
  627.             {
  628.             // set found flag
  629.  
  630.             found=1;
  631.  
  632.             // enter token into sentence
  633.  
  634.             sentence[curr_token++] = language[index].value;
  635.         //    printf("\nEntering %s, %d in sentence",
  636.         //                               output,language[index].value);
  637.  
  638.             break;
  639.  
  640.             } // end if
  641.  
  642.          } // end for index
  643.  
  644.          // test if token was part of language (grammar)
  645.  
  646.          if (!found)
  647.             {
  648.             printf("\n%s, I don't know what \"%s\" means.",you.name
  649.                                                           ,output);
  650.  
  651.             // failure
  652.  
  653.             return(0);
  654.  
  655.             } // end if not found
  656.  
  657.          // else
  658.  
  659.          num_tokens++;
  660.  
  661.      } // end while
  662.  
  663. } // end Extract_Tokens
  664.  
  665. ///////////////////////////////////////////////////////////////////////////////
  666.  
  667. void Verb_Parser(void)
  668. {
  669. // this function breaks down the sentence and based on the verb calls the
  670. // appropriate "method" or function to apply that verb
  671. // note: syntactic analysis could be done here, but I decided to place it
  672. // in the action verb functions, so that you can see the way the errors are
  673. // detected for each verb (even though there is a a lot of redundancy)
  674.  
  675. // what is the verb?
  676.  
  677. switch(sentence[FIRST_WORD])
  678.       {
  679.  
  680.       case ACTION_MOVE:
  681.            {
  682.            // call the appropriate function
  683.  
  684.            Verb_MOVE();
  685.  
  686.            } break;
  687.  
  688.       case ACTION_TURN:
  689.            {
  690.            // call the appropriate function
  691.  
  692.            Verb_TURN();
  693.  
  694.            } break;
  695.  
  696.       case ACTION_SMELL:
  697.            {
  698.            // call the appropriate function
  699.  
  700.            Verb_SMELL();
  701.  
  702.            } break;
  703.  
  704.       case ACTION_LOOK:
  705.            {
  706.            // call the appropriate function
  707.  
  708.            Verb_LOOK();
  709.  
  710.            } break;
  711.  
  712.       case ACTION_LISTEN:
  713.            {
  714.            // call the appropriate function
  715.  
  716.            Verb_LISTEN();
  717.  
  718.            } break;
  719.  
  720.       case ACTION_PUT:
  721.            {
  722.            // call the appropriate function
  723.  
  724.            Verb_PUT();
  725.  
  726.            } break;
  727.  
  728.       case ACTION_GET:
  729.            {
  730.            // call the appropriate function
  731.  
  732.            Verb_GET();
  733.  
  734.            } break;
  735.  
  736.       case ACTION_EAT:
  737.            {
  738.            // call the appropriate function
  739.  
  740.            Verb_EAT();
  741.  
  742.            } break;
  743.  
  744.       case ACTION_WHERE:
  745.            {
  746.            // call the appropriate function
  747.  
  748.            Verb_WHERE();
  749.  
  750.            } break;
  751.  
  752.       case ACTION_INVENTORY:
  753.            {
  754.            // call the appropriate function
  755.  
  756.            Verb_INVENTORY();
  757.  
  758.            } break;
  759.  
  760.       case ACTION_EXIT:
  761.            {
  762.            // call the appropriate function
  763.  
  764.            Verb_EXIT();
  765.  
  766.            } break;
  767.  
  768.       default:
  769.              {
  770.              printf("\n%s, you must start a sentence with an action verb!",
  771.                     you.name);
  772.  
  773.              return;
  774.  
  775.              } break;
  776.  
  777.       } // end switch
  778.  
  779. } // end Verb_Parser
  780.  
  781. // THE ACTION VERBS ///////////////////////////////////////////////////////////
  782.  
  783. int Verb_MOVE(void)
  784. {
  785. // this function will figure out which way the player wants to move,
  786. // then move the player and test for syntax errors
  787.  
  788. int token_index,   // current token being processed
  789.     dx,dy;         // ised to hold translation factors
  790.  
  791. // these look up tables are used to compute the translation factors
  792. // needed to move the player in the requested direction based on the
  793. // current direction, the problem occurs since the directives are not
  794. // absolute directions, they are relative to the direction the player
  795. // is facing
  796.  
  797. static int forward_x[]={1,-1,0,0};
  798. static int forward_y[]={0,0,-1,1};
  799.  
  800. static int backward_x[]={-1,1,0,0};
  801. static int backward_y[]={0,0,1,-1};
  802.  
  803. static int left_x[]={0, 0,-1,1};
  804. static int left_y[]={-1,1,0,0};
  805.  
  806. static int right_x[]={0,0,1,-1};
  807. static int right_y[]={1,-1,0,0};
  808.  
  809. // test if player didn't say which way, if so just move forward
  810. // this functionality was added after the fact so is a slight cludge
  811. // it is accomplished by synthetically inserting the direction "forward" into
  812. // the sentence
  813.  
  814. if (num_tokens==1)
  815.    {
  816.    // no direction given so assume forward
  817.  
  818.    sentence[SECOND_WORD] = DIR_2_FORWARD;
  819.  
  820.    num_tokens++;
  821.  
  822.    } // end if no direction
  823.  
  824.    // begin further processing to figure out direction
  825.  
  826.    // check if the next word is a direction and if so move in that
  827.    // direction
  828.  
  829.    // first test if the words 'to' or 'to the' are inserted bewteen action
  830.    // verb and noun (object).  In this case the phrase "move to the right"
  831.    // sounds ok and should be passed, but "move to the forward" will also
  832.    // be passed even though it is grammatically incorrent, but that's life
  833.  
  834.    token_index=1;
  835.  
  836.    if (Check_For_Phrase(PHRASE_TO_THE,token_index))
  837.       {
  838.       // consume preposition since it has to bearing on the final
  839.       // meaning sentence
  840.  
  841.       // index token scan to directon
  842.  
  843.       token_index=3;
  844.  
  845.       } // end if prep and article
  846.    else
  847.    if (Check_For_Phrase(PHRASE_TO,token_index))
  848.       {
  849.       // consume preposition since it has to bearing on the final
  850.       // meaning sentence
  851.  
  852.       // index token scan to directon
  853.  
  854.       token_index=2;
  855.  
  856.       } // end if prep
  857.  
  858.    // at this point the token_index is pointing to the direction
  859.  
  860.    if (sentence[token_index] >= DIR_2_START &&
  861.        sentence[token_index] <= DIR_2_END)
  862.       {
  863.       // at this point we finally know what the user is asking for, so
  864.       // let's do it
  865.  
  866.       // based on direction asked for do movement and collision detection
  867.       // note: the use of look up tables to decrease the complexity of the
  868.       // conditional logic
  869.  
  870.       dx=dy=0;
  871.  
  872.       switch(sentence[token_index])
  873.             {
  874.  
  875.             case DIR_2_FORWARD:  // move player forward
  876.                  {
  877.                  // compute translation factors using look up tables
  878.  
  879.                  dx = forward_x[you.direction];
  880.                  dy = forward_y[you.direction];
  881.  
  882.                  } break;
  883.  
  884.             case DIR_2_BACKWARD: // move player backward
  885.                  {
  886.                  // compute translation factors using look up tables
  887.  
  888.                  dx = backward_x[you.direction];
  889.                  dy = backward_y[you.direction];
  890.  
  891.                  } break;
  892.  
  893.             case DIR_2_RIGHT:    // parry right
  894.                  {
  895.                  // compute translation factors using look up tables
  896.  
  897.                  dx = right_x[you.direction];
  898.                  dy = right_y[you.direction];
  899.  
  900.                  } break;
  901.  
  902.             case DIR_2_LEFT:     // parry left
  903.                  {
  904.                  // compute translation factors using look up tables
  905.  
  906.                  dx = left_x[you.direction];
  907.                  dy = left_y[you.direction];
  908.  
  909.                  } break;
  910.  
  911.             } // end switch direction of motion
  912.  
  913.       // based on the translation factors move the player
  914.  
  915.       you.x+=dx;
  916.       you.y+=dy;
  917.  
  918.       // test for collision with a wall
  919.  
  920.       if (universe_geometry[you.y][you.x]==WALL_ID)
  921.          {
  922.          // let' user know he hit a wall
  923.          printf("\nOuch! that hurt. Can't you see this wall %s?\n",you.name);
  924.  
  925.          // back player up
  926.  
  927.          you.x-=dx;
  928.          you.y-=dy;
  929.  
  930.          } // end collision detection
  931.       else
  932.          {
  933.          printf("\nYou take a few steps.\n");
  934.  
  935.          } // end else ok
  936.  
  937.       return(1);
  938.  
  939.       } // end if direction is valid
  940.    else
  941.       {
  942.       printf("\n%\"%s\" is an invalid sentence.",global_input);
  943.       printf("\nI don't understand the direction you wish me to move in?");
  944.       return(0);
  945.  
  946.       } // end else invalid direction
  947.  
  948. } // end Verb_MOVE
  949.  
  950. ////////////////////////////////////////////////////////////////////////////////
  951.  
  952. int Verb_TURN(void)
  953. {
  954. // this function will figure out which way the player wants to turn,
  955. // then turn the player and test for syntax errors
  956.  
  957. int token_index;
  958.  
  959. // if the player look in general then give him the full view, otherwise
  960. // look for walls and objects
  961.  
  962. token_index=0;
  963.  
  964. // first test for a direction
  965.  
  966. if (num_tokens==1)
  967.    {
  968.    // no direction, so tell user to give one next time
  969.  
  970.    printf("\n%s, I don't know which way to turn?\n",you.name);
  971.    return(0);
  972.  
  973.    } // end if only turn
  974. else
  975.    {
  976.    // check if the next word is a direction and if so turn in that
  977.    // direction
  978.  
  979.    // first test if the words 'to' or 'to the' are inserted bewteen action
  980.    // verb and noun (object)
  981.  
  982.    token_index=1;
  983.  
  984.    if (Check_For_Phrase(PHRASE_TO_THE,token_index))
  985.       {
  986.       // consume preposition since it has to bearing on the final
  987.       // meaning sentence
  988.  
  989.       // index token scan to directon
  990.  
  991.       token_index=3;
  992.  
  993.       } // end if prep and article
  994.    else
  995.    if (Check_For_Phrase(PHRASE_TO,token_index))
  996.       {
  997.       // consume preposition since it has to bearing on the final
  998.       // meaning sentence
  999.  
  1000.       // index token scan to directon
  1001.  
  1002.       token_index=2;
  1003.  
  1004.       } // end if prep
  1005.  
  1006.    // at this point the token_index is pointing to the direction
  1007.  
  1008.    if (sentence[token_index] >= DIR_1_START &&
  1009.        sentence[token_index] <= DIR_1_END)
  1010.       {
  1011.       // at this point we finally know what the user is asking for, so
  1012.       // let's do it
  1013.  
  1014.       // update the players direction based on new direction
  1015.  
  1016.       you.direction = sentence[token_index]-DIR_1_START;
  1017.  
  1018.       printf("\nYou turn...");
  1019.  
  1020.       return(1);
  1021.  
  1022.       } // end if direction is valid
  1023.    else
  1024.       {
  1025.       printf("\n%\"%s\" is an invalid sentence.",global_input);
  1026.       printf("\nI don't understand the direction you wish me to turn to?");
  1027.       return(0);
  1028.       } // end else invalid direction
  1029.  
  1030.    } // end else
  1031.  
  1032. } // end Verb_TURN
  1033.  
  1034. ////////////////////////////////////////////////////////////////////////////////
  1035.  
  1036. int Verb_SMELL(void)
  1037. {
  1038. // this function will just smell without paying attention to the rest
  1039. // of the sentence
  1040.  
  1041. if (num_tokens==1)
  1042.    {
  1043.  
  1044.    Print_Info_Strings(smells,universe_geometry[you.y][you.x]);
  1045.    return(1);
  1046.    } // end if smell
  1047. else
  1048.    {
  1049.  
  1050.    printf("\n%\"%s\" is an invalid sentence.",global_input);
  1051.    printf("\nI don't understand what you want me to smell?");
  1052.    return(0);
  1053.    } // end else invalid
  1054.  
  1055. } // end Verb_SMELL
  1056.  
  1057. ////////////////////////////////////////////////////////////////////////////////
  1058.  
  1059. int Verb_LOOK(void)
  1060. {
  1061. // this function will look in the direction commanded to
  1062.  
  1063. int token_index,   // current word being processed
  1064.     direction,     // direction player wants to look
  1065.     num_items,     // number of objects seen during vision scan
  1066.     index;         // used as look index
  1067.  
  1068. object objects[8]; // holds the objects
  1069.  
  1070. // if the player look in general then give him the full view, otherwise
  1071. // look for walls and objects
  1072.  
  1073. token_index=0;
  1074.  
  1075. // first test for a direction
  1076.  
  1077. if (num_tokens==1)
  1078.    {
  1079.    // no direction, so give long version
  1080.  
  1081.    Print_Info_Strings(views,universe_geometry[you.y][you.x]);
  1082.    return(1);
  1083.    } // end if only look
  1084. else
  1085.    {
  1086.    // check if the next word is a direction and if so look in that
  1087.    // direction
  1088.  
  1089.    // first test if the words 'to' or 'to the' are inserted bewteen action
  1090.    // verb and noun (object)
  1091.  
  1092.    token_index=1;
  1093.  
  1094.    if (Check_For_Phrase(PHRASE_TO_THE,token_index))
  1095.       {
  1096.       // consume preposition since it has to bearing on the final
  1097.       // meaning sentence
  1098.  
  1099.       // index token scan to directon
  1100.  
  1101.       token_index=3;
  1102.  
  1103.       } // end if prep and article
  1104.    else
  1105.    if (Check_For_Phrase(PHRASE_TO,token_index))
  1106.       {
  1107.       // consume preposition since it has to bearing on the final
  1108.       // meaning sentence
  1109.  
  1110.       // index token scan to directon
  1111.  
  1112.       token_index=2;
  1113.  
  1114.       } // end if prep
  1115.  
  1116.    // at this point the token_index is pointing to the direction
  1117.  
  1118.    if (sentence[token_index] >= DIR_1_START &&
  1119.        sentence[token_index] <= DIR_1_END)
  1120.       {
  1121.       // at this point we finally know what the user is asking for, so
  1122.       // let's do it
  1123.  
  1124.       printf("\nYou see walls");
  1125.  
  1126.       // compute direction
  1127.  
  1128.       direction = sentence[token_index] - DIR_1_START;
  1129.  
  1130.       // test if there are any objects in sight
  1131.  
  1132.       if (Vision_System(24,direction,objects,&num_items))
  1133.          {
  1134.  
  1135.          // print out what was seen
  1136.  
  1137.          printf(" and,");
  1138.  
  1139.          for (index=0; index<num_items; index++)
  1140.              {
  1141.  
  1142.              // print out the correct description
  1143.  
  1144.              switch(objects[index].thing)
  1145.                    {
  1146.  
  1147.                    case LAMP_ID:
  1148.                         {
  1149.                         printf("\na torch lamp.");
  1150.                         } break;
  1151.  
  1152.                    case KEYS_ID:
  1153.                         {
  1154.                         printf("\na set of car keys.");
  1155.                         } break;
  1156.  
  1157.                    case SANDWICH_ID:
  1158.                         {
  1159.                         printf("\na turkey sandwich.");
  1160.                         } break;
  1161.  
  1162.                    default:break;
  1163.  
  1164.                    } // end switch
  1165.  
  1166.              } // end for index
  1167.  
  1168.          } // end if we saw something
  1169.  
  1170.       return(1);
  1171.  
  1172.       } // end if direction is valid
  1173.    else
  1174.       {
  1175.       printf("\n%\"%s\" is an invalid sentence.",global_input);
  1176.       printf("\nI don't understand the direction you wish me to look in?");
  1177.       return(0);
  1178.       } // end else invalid direction
  1179.  
  1180.    } // end else
  1181.  
  1182. } // end Verb_LOOK
  1183.  
  1184. ////////////////////////////////////////////////////////////////////////////////
  1185.  
  1186. int Verb_LISTEN(void)
  1187. {
  1188. // this function will just listen without paying attention to the rest of
  1189. // the sentence
  1190.  
  1191.  
  1192. if (num_tokens==1)
  1193.    {
  1194.  
  1195.    Print_Info_Strings(sounds,universe_geometry[you.y][you.x]);
  1196.    return(1);
  1197.    } // end if sound
  1198. else
  1199.    {
  1200.  
  1201.    printf("\n%\"%s\" is an invalid sentence.",global_input);
  1202.    printf("\nI don't understand what you want me to listen to?");
  1203.    return(0);
  1204.    } // end else invalid
  1205.  
  1206. } // end Verb_LISTEN
  1207.  
  1208. ////////////////////////////////////////////////////////////////////////////////
  1209.  
  1210. int Verb_PUT(void)
  1211. {
  1212. // this function will put down the object requested
  1213.  
  1214. // this look up table is used to convert object token numbers into object id's
  1215.  
  1216. static char object_to_id[]={'l','s','k'};
  1217.  
  1218. int token_index, // current toek nbeing precessed
  1219.           index; // loop index
  1220.  
  1221. char object;     // object we are currently looking at
  1222.  
  1223. token_index=0;
  1224.  
  1225. // first test for a object
  1226.  
  1227. if (num_tokens==1)
  1228.    {
  1229.    // no object, so tell user to give one next time
  1230.  
  1231.    printf("\n%s, I don't know what you want me to put down?\n",you.name);
  1232.    return(0);
  1233.  
  1234.    } // end if only put
  1235. else
  1236.    {
  1237.    // check if the next word is an object, if so put is down
  1238.    // direction
  1239.  
  1240.    // first test if the words 'down' or 'down the' are inserted bewteen action
  1241.    // verb and noun (object)
  1242.  
  1243.    token_index=1;
  1244.  
  1245.    if (Check_For_Phrase(PHRASE_DOWN_THE,token_index))
  1246.       {
  1247.       // consume preposition since it has to bearing on the final
  1248.       // meaning sentence
  1249.  
  1250.       // index token scan to object
  1251.  
  1252.       token_index=3;
  1253.  
  1254.       } // end if prep and article
  1255.    else
  1256.    if (Check_For_Phrase(PHRASE_DOWN,token_index))
  1257.       {
  1258.       // consume preposition since it has to bearing on the final
  1259.       // meaning sentence
  1260.  
  1261.       // index token scan to object
  1262.  
  1263.       token_index=2;
  1264.  
  1265.       } // end if prep
  1266.  
  1267.    // at this point the token_index is pointing to the object
  1268.  
  1269.    if (sentence[token_index] >= OBJECT_START &&
  1270.        sentence[token_index] <= OBJECT_END)
  1271.       {
  1272.       // at this point we finally know what the user is asking for, so
  1273.       // let's do it
  1274.  
  1275.       // check to see if object is in inventory..if so then put it down
  1276.       // in the current square
  1277.  
  1278.       // first convert object token to object id
  1279.  
  1280.       object = object_to_id[sentence[token_index]-OBJECT_START];
  1281.  
  1282.       // do scan in pockets
  1283.  
  1284.       for (index=0; index<you.num_objects; index++)
  1285.           {
  1286.           // test if this pocket has the object we are looking for
  1287.  
  1288.           if (you.inventory[index]==object)
  1289.              {
  1290.              // take object out of pocket
  1291.  
  1292.              you.inventory[index] = EMPTY_ID;
  1293.  
  1294.              // decrement number of objects
  1295.  
  1296.              you.num_objects--;
  1297.  
  1298.              // place the object back into object universe
  1299.  
  1300.              universe_objects[you.y][you.x] = object;
  1301.  
  1302.              // say something
  1303.  
  1304.              printf("\nPutting down the ");
  1305.  
  1306.              switch(object)
  1307.                    {
  1308.                    case LAMP_ID:
  1309.                         {printf("torch lamp.\n");}break;
  1310.  
  1311.                    case SANDWICH_ID:
  1312.                         {printf("sandwich.\n");}break;
  1313.  
  1314.                    case KEYS_ID:
  1315.                         {printf("keys.\n");}break;
  1316.  
  1317.                    default:break;
  1318.  
  1319.                    } // end switch
  1320.  
  1321.              // **************************************************************
  1322.              // if the player puts the keys in the kitchen where they should be
  1323.              // then he will win! Test that condition here
  1324.  
  1325.              if (object==KEYS_ID && universe_geometry[you.y][you.x]=='k')
  1326.                 {
  1327.  
  1328.                 printf("\nCongratulation %s! You have solved the game.\n",you.name);
  1329.  
  1330.                 } // end if win
  1331.  
  1332.              // **************************************************************
  1333.  
  1334.              return(1);
  1335.  
  1336.              } // end if found object
  1337.  
  1338.           } // end for index
  1339.  
  1340.       // if we get this far then the player wasn't carrying the requested
  1341.       // object to be dropped
  1342.  
  1343.       printf("\n%s, you don't have that to drop!\n",you.name);
  1344.  
  1345.       return(1);
  1346.  
  1347.       } // end if object is valid
  1348.    else
  1349.       {
  1350.       printf("\n%\"%s\" is an invalid sentence.",global_input);
  1351.       printf("\nI don't understand the object you wish me to put down?");
  1352.       return(0);
  1353.       } // end else invalid object
  1354.  
  1355.    } // end else
  1356.  
  1357. } // end Verb_PUT
  1358.  
  1359. ////////////////////////////////////////////////////////////////////////////////
  1360.  
  1361. int Verb_GET(void)
  1362. {
  1363. // this function will get the object in the current square
  1364.  
  1365. object objects[8];  // the objects within reaching distance of player
  1366.  
  1367. // this look up table is used to convert object token numbers into object id's
  1368.  
  1369. static char object_to_id[]={'l','s','k'};
  1370.  
  1371. int token_index=0,   // current token being processed
  1372.           index,     // loop index
  1373.           index_2,   // loop index
  1374.           num_items; // number of items found during vision scan
  1375.  
  1376. char object;       // item we are currently looking at
  1377.  
  1378. // first test for a object
  1379.  
  1380. if (num_tokens==1)
  1381.    {
  1382.    // no object, so ask what get
  1383.  
  1384.    printf("\n%s, what do you want me to pick up?\n",you.name);
  1385.  
  1386.    return(1);
  1387.  
  1388.    } // end if only get
  1389. else
  1390.    {
  1391.    // check if the next word is an object
  1392.  
  1393.    // first test if the word 'the' is inserted bewteen action
  1394.    // verb and noun (object)
  1395.  
  1396.    token_index=1;
  1397.  
  1398.    if (Check_For_Phrase(PHRASE_THE,token_index))
  1399.       {
  1400.       // consume article since it has to bearing on the final
  1401.       // meaning sentence
  1402.  
  1403.       // index token scan to directon
  1404.  
  1405.       token_index=2;
  1406.  
  1407.       } // end if article
  1408.  
  1409.    // at this point the token_index is pointing to the object to pick up
  1410.  
  1411.    if (sentence[token_index] >= OBJECT_START &&
  1412.        sentence[token_index] <= OBJECT_END)
  1413.       {
  1414.       // at this point we finally know what the user is asking for, so
  1415.       // let's do it
  1416.  
  1417.       // using vision system scan forward a depth of 2 units this will simulate
  1418.       // the player reaching for the object within a reasonable radius
  1419.  
  1420.       // convert object to id
  1421.  
  1422.       object = object = object_to_id[sentence[token_index]-OBJECT_START];
  1423.  
  1424.        // do forward radial scan
  1425.  
  1426.       if (Vision_System(3,you.direction,objects,&num_items))
  1427.          {
  1428.  
  1429.          // test if the object we desire to pick up is within the objects array
  1430.  
  1431.          for (index=0; index<num_items; index++)
  1432.              {
  1433.              // is this what player wants to pick up?
  1434.  
  1435.              if (object==objects[index].thing)
  1436.                 {
  1437.  
  1438.                 // remove object from universe
  1439.  
  1440.                 universe_objects[objects[index].y][objects[index].x] = EMPTY_ID;
  1441.  
  1442.                 // update players inventory (find an empty pocket and place
  1443.                 // object in it)
  1444.  
  1445.                 for (index_2=0; index_2<8; index_2++)
  1446.                     {
  1447.                     if (you.inventory[index_2]==EMPTY_ID)
  1448.                        {
  1449.                        // put it in pocket
  1450.  
  1451.                        you.inventory[index_2]=object;
  1452.  
  1453.                        you.num_objects++;
  1454.  
  1455.                        break;
  1456.  
  1457.                        } // end if an open spot was found
  1458.  
  1459.                     } // end for index_2
  1460.  
  1461.                 // let user know it was picked up
  1462.  
  1463.                 printf("\nGot it!\n");
  1464.  
  1465.                 return(1);
  1466.  
  1467.                 } // end if object found
  1468.  
  1469.              } // end for index
  1470.  
  1471.          } // end if any objects within reach
  1472.       else
  1473.          {
  1474.  
  1475.          printf("\nYou are too far from it!\n");
  1476.          return(0);
  1477.  
  1478.          } // end else can't reach
  1479.  
  1480.       } // end if object is valid
  1481.    else
  1482.       {
  1483.       printf("\nI don't understand what you want me to pick up?");
  1484.       return(0);
  1485.  
  1486.       } // end else invalid object
  1487.  
  1488.    } // end else
  1489.  
  1490. } // end Verb_GET
  1491.  
  1492. ////////////////////////////////////////////////////////////////////////////////
  1493.  
  1494. int Verb_EAT(void)
  1495. {
  1496. // the function will eat the object it is directed to
  1497.  
  1498. // this look up table is used to convert object token numbers into object id's
  1499.  
  1500. static char object_to_id[]={'l','s','k'};
  1501.  
  1502. int token_index=0, // current token being processed
  1503.           index;   // loop index
  1504.  
  1505. char object;       // object we are currently looking at
  1506.  
  1507. // first test for a direction
  1508.  
  1509. if (num_tokens==1)
  1510.    {
  1511.    // no object, so ask what to eat
  1512.  
  1513.    printf("\n%s, what do you want me to eat?\n",you.name);
  1514.  
  1515.    return(1);
  1516.  
  1517.    } // end if only eat
  1518. else
  1519.    {
  1520.    // check if the next word is an object
  1521.  
  1522.    // first test if the word 'the' is inserted bewteen action
  1523.    // verb and noun (object)
  1524.  
  1525.    token_index=1;
  1526.  
  1527.    if (Check_For_Phrase(PHRASE_THE,token_index))
  1528.       {
  1529.       // consume article since it has to bearing on the final
  1530.       // meaning sentence
  1531.  
  1532.       // index token scan to directon
  1533.  
  1534.       token_index=2;
  1535.  
  1536.       } // end if article
  1537.  
  1538.    // at this point the token_index is pointing to the object to eat
  1539.  
  1540.    if (sentence[token_index] >= OBJECT_START &&
  1541.        sentence[token_index] <= OBJECT_END)
  1542.       {
  1543.       // at this point we finally know what the user is asking for, so
  1544.       // let's do it
  1545.  
  1546.       // scan thru the inventory and test if the player is carrying the
  1547.       // object.  Actually, the only thing he can eat is the sandwich, but
  1548.       // we need a little comedy relief and this is a good place for it
  1549.  
  1550.       for (index=0; index<8; index++)
  1551.           {
  1552.  
  1553.           // test if this pocket has object we are interested in
  1554.  
  1555.  
  1556.           // first convert object token to object id
  1557.  
  1558.           object = object_to_id[sentence[token_index]-OBJECT_START];
  1559.  
  1560.           if (you.inventory[index]==object)
  1561.           {
  1562.  
  1563.           switch(you.inventory[index])
  1564.                 {
  1565.  
  1566.                 case LAMP_ID:
  1567.                      {
  1568.                      printf("\nI don't think I can fit this 6 foot long lamp in my mouth!\n");
  1569.                      return(1);
  1570.                      } break;
  1571.  
  1572.                 case KEYS_ID:
  1573.                      {
  1574.                      printf("\nIf you say so...gulp\n");
  1575.  
  1576.                      // extract keys from pocket
  1577.  
  1578.                      you.inventory[index]= EMPTY_ID;
  1579.  
  1580.                      // decrement number of objects on player
  1581.  
  1582.                      you.num_objects--;
  1583.  
  1584.                      return(1);
  1585.  
  1586.                      } break;
  1587.  
  1588.                 case SANDWICH_ID:
  1589.                      {
  1590.                      printf("\nThat was good, but it needed more mustard.\n");
  1591.  
  1592.                      // extract sanwich from pocket
  1593.  
  1594.                      you.inventory[index]= EMPTY_ID;
  1595.  
  1596.                      // decrement number of objects on player
  1597.  
  1598.                      you.num_objects--;
  1599.  
  1600.                      return(1);
  1601.  
  1602.                      } break;
  1603.  
  1604.                 } // end switch pockets
  1605.  
  1606.           } // end if this is the object
  1607.  
  1608.           } // end for index
  1609.  
  1610.       // didn't find the object
  1611.  
  1612.       printf("\nI would really like to eat that, but you don't seem to have one.\n");
  1613.  
  1614.       return(1);
  1615.  
  1616.       } // end if object is valid
  1617.    else
  1618.       {
  1619.       printf("\nI don't understand what you want me to eat?");
  1620.       return(0);
  1621.  
  1622.       } // end else invalid object
  1623.  
  1624.    } // end else
  1625.  
  1626. } // end Verb_EAT
  1627.  
  1628. ////////////////////////////////////////////////////////////////////////////////
  1629.  
  1630. int Verb_WHERE(void)
  1631. {
  1632. // the function tells the player where he is
  1633.  
  1634. // based on the tile the player is standing on in the geometry array
  1635. // indicate where he is
  1636.  
  1637. if (num_tokens==1)
  1638.     {
  1639.     // what room is player in
  1640.  
  1641.     switch(universe_geometry[you.y][you.x])
  1642.           {
  1643.  
  1644.           case 'l': //- living room
  1645.              {
  1646.              printf("\n\nYou are in the living room");
  1647.              } break;
  1648.  
  1649.           case 'b': //- bedroom
  1650.              {
  1651.              printf("\n\nYou are in the bedroom");
  1652.              } break;
  1653.  
  1654.           case 'k': //- kitchen
  1655.              {
  1656.              printf("\n\nYou are in the kitchen");
  1657.              } break;
  1658.  
  1659.           case 'w': //- washroom
  1660.              {
  1661.              printf("\n\nYou are in the washroom");
  1662.              } break;
  1663.  
  1664.           case 'h': //- hall way
  1665.              {
  1666.              printf("\n\nYou are in the hallway");
  1667.              } break;
  1668.  
  1669.           case 'r': //- restroom
  1670.              {
  1671.              printf("\n\nYou are in the master bathroom");
  1672.              } break;
  1673.  
  1674.           case 'e': //- entry way
  1675.              {
  1676.              printf("\n\nYou are in the entry way");
  1677.              } break;
  1678.  
  1679.           case 'o': //- office
  1680.              {
  1681.              printf("\n\nYou are in the computer office");
  1682.              } break;
  1683.  
  1684.           default:break;
  1685.  
  1686.           } // end switch
  1687.  
  1688.  
  1689.     // now state the direction
  1690.  
  1691.     switch(you.direction)
  1692.           {
  1693.  
  1694.           case EAST:
  1695.                {
  1696.                printf(" facing East.\n");
  1697.                } break;
  1698.  
  1699.           case WEST:
  1700.                {
  1701.                printf(" facing West.\n");
  1702.                } break;
  1703.  
  1704.           case NORTH:
  1705.                {
  1706.                printf(" facing North.\n");
  1707.                } break;
  1708.  
  1709.           case SOUTH:
  1710.                {
  1711.                printf(" facing South.\n");
  1712.                } break;
  1713.  
  1714.           default:break;
  1715.  
  1716.           } // end switch
  1717.     return(1);
  1718.     } // end if a valid sentence structure
  1719. else
  1720.    {
  1721.  
  1722.    printf("\n%\"%s\" is an invalid sentence.",global_input);
  1723.    printf("\n%s, I just don't get it?",you.name);
  1724.    return(0);
  1725.    } // end else invalid
  1726.  
  1727. } // end Verb_WHERE
  1728.  
  1729. ////////////////////////////////////////////////////////////////////////////////
  1730.  
  1731. int Verb_INVENTORY(void)
  1732. {
  1733. // this function will print out the current inventory
  1734.  
  1735. int index; // loop index
  1736.  
  1737.  
  1738. // print out the inventory and then test if the player typed too many words
  1739. // if so complain a little
  1740.  
  1741. printf("\nYou have the following items within your possesion.\n");
  1742.  
  1743. // scan thru inventory array and print out the objects that the player is
  1744. // holding
  1745.  
  1746. for (index=0; index<8; index++)
  1747.     {
  1748.  
  1749.     // test if this "pocket" has an object in it
  1750.  
  1751.     switch(you.inventory[index])
  1752.           {
  1753.  
  1754.           case LAMP_ID:
  1755.                {
  1756.                printf("\nA torch lamp.");
  1757.                } break;
  1758.  
  1759.           case KEYS_ID:
  1760.                {
  1761.                printf("\nA set of car keys.");
  1762.                } break;
  1763.  
  1764.           case SANDWICH_ID:
  1765.                {
  1766.                printf("\nA turkey sandwich.");
  1767.                } break;
  1768.  
  1769.           default:break;
  1770.  
  1771.           } // end switch
  1772.  
  1773.     } // end for index
  1774.  
  1775. // test if player has nothing on him
  1776.  
  1777. if (you.num_objects==0)
  1778.    printf("\nYour pockets are empty %s.",you.name);
  1779.  
  1780. // test if there are too many words
  1781.  
  1782. if (num_tokens>1)
  1783.    printf("\n%s, all you hade to say was \"Inventory!\"",you.name);
  1784.  
  1785. return(1);
  1786.  
  1787. } // end Verb_INVENTORY
  1788.  
  1789. ////////////////////////////////////////////////////////////////////////////////
  1790.  
  1791. int Verb_EXIT(void)
  1792. {
  1793. // this function sets the global exit and terminates the game
  1794.  
  1795. global_exit=1;
  1796.  
  1797. return(1);
  1798.  
  1799. } // end Verb_EXIT
  1800.  
  1801. ////////////////////////////////////////////////////////////////////////////////
  1802.  
  1803. int Vision_System(int depth,         // depth of scan
  1804.                   int direction,     // direction of scan N,E,S,W
  1805.                   object *stuff,     // objects seen in scan
  1806.                   int *num_objects)  // number of objects seen in scan
  1807.  
  1808. {
  1809. // this function is rather complex. It is responsible for the vision of
  1810. // the player. It works by scanning a upside down pryamid of squares in
  1811. // front of the player.  The objects within this vision window will be
  1812. // returned in the objects array along withe the number of them.
  1813. // the vision window is built up by consequtively scanning rows of blocks
  1814. // in the geometry universe along with testing the objects universe for
  1815. // instances of objects. It is sort of like ray casting, but the distance
  1816. // is irrelevant and only four directions are used.  For example if the
  1817. // player was looking north and a depth of 3 was sent for the scan then the
  1818. // scan pattern would look like:
  1819. //
  1820. //       .....
  1821. //        ...
  1822. //         P
  1823. // where 'P' is the position of player and the '.' is a scanned block
  1824. // similary a scan of depth 5 to the east would like like
  1825. //      .
  1826. //      ..
  1827. //      ...
  1828. //      ....
  1829. //      ....P
  1830. //      ....
  1831. //      ...
  1832. //      ..
  1833. //      .
  1834. // note: the field of view (FOV) will always be 90 degrees
  1835. // anyway the function is basically used for the "LOOK" verb and the "GET"
  1836. // verb and I admit that the code is redundant for each case, but to merge
  1837. // it all would make it too hard to follow!
  1838.  
  1839. int x,y,           // used to hold current universe cell location
  1840.     index,         // loop index
  1841.     scan_level;    // current level or iteration of the scan
  1842.  
  1843. *num_objects=0;
  1844.  
  1845. // which direction is vision requested in?
  1846.  
  1847. switch(direction)
  1848.       {
  1849.  
  1850.       case NORTH:
  1851.            {
  1852.            // scan like this
  1853.            //  .....
  1854.            //   ...
  1855.            //    P
  1856.  
  1857.            for (y=you.y,scan_level=0; y>=(you.y-depth); y--,scan_level++)
  1858.                {
  1859.                for (x=you.x-scan_level; x<=you.x+scan_level; x++)
  1860.                    {
  1861.                    // x,y is test point, make sure it is within the universe
  1862.                    // boundaries and within the same room
  1863.  
  1864.                    if (x>=1 && x<NUM_COLUMNS-1 &&
  1865.                        y>=1 && x<NUM_ROWS-1 &&
  1866.                        universe_geometry[y][x]==universe_geometry[you.y][you.x])
  1867.  
  1868.  
  1869.                       {
  1870.                       // test to see if square has an object in it
  1871.  
  1872.                       if (universe_objects[y][x]!=' ')
  1873.                          {
  1874.                          // insert the object into object list
  1875.  
  1876.                          stuff[*num_objects].thing = universe_objects[y][x];
  1877.                          stuff[*num_objects].x     = x;
  1878.                          stuff[*num_objects].y     = y;
  1879.  
  1880.                          // increment the number of objects
  1881.  
  1882.                          (*num_objects)++;
  1883.  
  1884.                          } // end if an object was found
  1885.  
  1886.                       } // end if in boundaries
  1887.  
  1888.                    } // end for x
  1889.  
  1890.                } // end for y
  1891.  
  1892.            // return number of objects found
  1893.  
  1894.            return(*num_objects);
  1895.  
  1896.            } break;
  1897.  
  1898.       case SOUTH:
  1899.            {
  1900.            // scan like this
  1901.            //  P
  1902.            // ...
  1903.            //.....
  1904.  
  1905.            for (y=you.y,scan_level=0; y<=(you.y+depth); y++,scan_level++)
  1906.                {
  1907.                for (x=you.x-scan_level; x<=you.x+scan_level; x++)
  1908.                    {
  1909.                    // x,y is test point, make sure it is within the universe
  1910.                    // boundaries
  1911.  
  1912.                    if (x>=1 && x<NUM_COLUMNS-1 &&
  1913.                        y>=1 && x<NUM_ROWS-1 &&
  1914.                        universe_geometry[y][x]==universe_geometry[you.y][you.x])
  1915.                       {
  1916.                       // test to see if square has an object in it
  1917.  
  1918.                       if (universe_objects[y][x]!=' ')
  1919.                          {
  1920.                          // insert the object into object list
  1921.  
  1922.                          stuff[*num_objects].thing = universe_objects[y][x];
  1923.                          stuff[*num_objects].x     = x;
  1924.                          stuff[*num_objects].y     = y;
  1925.  
  1926.                          // increment the number of objects
  1927.  
  1928.                          (*num_objects)++;
  1929.  
  1930.                          } // end if an object was found
  1931.  
  1932.                       } // end if in boundaries
  1933.  
  1934.                    } // end for x
  1935.  
  1936.                } // end for y
  1937.  
  1938.            // return number of objects found
  1939.  
  1940.            return(*num_objects);
  1941.  
  1942.            } break;
  1943.  
  1944.  
  1945.       case EAST:
  1946.            {
  1947.            // scan like this
  1948.            //   .
  1949.            //  ..
  1950.            // P..
  1951.            //  ..
  1952.            //   .
  1953.  
  1954.            for (x=you.x,scan_level=0; x<=(you.x+depth); x++,scan_level++)
  1955.                {
  1956.                for (y=you.y-scan_level; y<=you.y+scan_level; y++)
  1957.                    {
  1958.                    // x,y is test point, make sure it is within the universe
  1959.                    // boundaries
  1960.  
  1961.                    if (x>=1 && x<NUM_COLUMNS-1 &&
  1962.                        y>=1 && x<NUM_ROWS-1 &&
  1963.                        universe_geometry[y][x]==universe_geometry[you.y][you.x])
  1964.                       {
  1965.                       // test to see if square has an object in it
  1966.  
  1967.                       if (universe_objects[y][x]!=' ')
  1968.                          {
  1969.                          // insert the object into object list
  1970.  
  1971.                          stuff[*num_objects].thing = universe_objects[y][x];
  1972.                          stuff[*num_objects].x     = x;
  1973.                          stuff[*num_objects].y     = y;
  1974.  
  1975.                          // increment the number of objects
  1976.  
  1977.                          (*num_objects)++;
  1978.  
  1979.                          } // end if an object was found
  1980.  
  1981.                       } // end if in boundaries
  1982.  
  1983.                    } // end for y
  1984.  
  1985.                } // end for x
  1986.  
  1987.            // return number of objects found
  1988.  
  1989.            return(*num_objects);
  1990.  
  1991.            } break;
  1992.  
  1993.       case WEST:
  1994.            {
  1995.            // scan like this
  1996.            // .
  1997.            // ..
  1998.            // ..P
  1999.            // ..
  2000.            // .
  2001.            //
  2002.  
  2003.            for (x=you.x,scan_level=0; x>=(you.x-depth); x--,scan_level++)
  2004.                {
  2005.                for (y=you.y-scan_level; y<=you.y+scan_level; y++)
  2006.                    {
  2007.                    // x,y is test point, make sure it is within the universe
  2008.                    // boundaries
  2009.  
  2010.                    if (x>=1 && x<NUM_COLUMNS-1 &&
  2011.                        y>=1 && x<NUM_ROWS-1 &&
  2012.                        universe_geometry[y][x]==universe_geometry[you.y][you.x])
  2013.                       {
  2014.                       // test to see if square has an object in it
  2015.  
  2016.                       if (universe_objects[y][x]!=' ')
  2017.                          {
  2018.                          // insert the object into object list
  2019.  
  2020.                          stuff[*num_objects].thing = universe_objects[y][x];
  2021.                          stuff[*num_objects].x     = x;
  2022.                          stuff[*num_objects].y     = y;
  2023.  
  2024.                          // increment the number of objects
  2025.  
  2026.                          (*num_objects)++;
  2027.  
  2028.                          } // end if an object was found
  2029.  
  2030.                       } // end if in boundaries
  2031.  
  2032.                    } // end for y
  2033.  
  2034.                } // end for x
  2035.  
  2036.            // return number of objects found
  2037.  
  2038.            return(*num_objects);
  2039.  
  2040.            } break;
  2041.  
  2042.       } // end switch direction
  2043.  
  2044. } // end Vision_System
  2045.  
  2046. ////////////////////////////////////////////////////////////////////////////////
  2047.  
  2048. int Check_For_Phrase(int phrase,int index)
  2049. {
  2050. // this function is used to test for small phrases that when extracted don't
  2051. // change the measning of a sentence for example:"look to the west" and
  2052. // "loo west" and "look to west" all mean the same thing.
  2053.  
  2054. // test which phrase is to be checked
  2055.  
  2056. switch(phrase)
  2057.       {
  2058.       case PHRASE_TO: // have we found the prep. "to"
  2059.            {
  2060.  
  2061.            if (sentence[index]==PREP_TO)
  2062.               return(1);
  2063.  
  2064.            } break;
  2065.  
  2066.       case PHRASE_THE: // have we found the article "the"
  2067.            {
  2068.  
  2069.            if (sentence[index]==ART_THE)
  2070.               return(1);
  2071.  
  2072.            } break;
  2073.  
  2074.  
  2075.      case PHRASE_DOWN: // have we found the prep/adj "down"
  2076.           {
  2077.  
  2078.           if (sentence[index]==PREP_DOWN)
  2079.              return(1);
  2080.  
  2081.           } break;
  2082.  
  2083.       case PHRASE_TO_THE: // have we found the prep. phrase "to the"
  2084.            {
  2085.  
  2086.            if (sentence[index]==PREP_TO)
  2087.               {
  2088.               if (sentence[index+1]==ART_THE)
  2089.                   return(1);
  2090.               else
  2091.                   return(0);
  2092.               } // end if got "to the"
  2093.            } break;
  2094.  
  2095.       case PHRASE_DOWN_THE: // have we found the prep. phrase "down the"
  2096.            {
  2097.  
  2098.            if (sentence[index]==PREP_DOWN)
  2099.               {
  2100.               if (sentence[index+1]==ART_THE)
  2101.                   return(1);
  2102.               else
  2103.                   return(0);
  2104.               } // end if got "down the"
  2105.            } break;
  2106.  
  2107.  
  2108.       default:break; // there is a serious problem!
  2109.  
  2110.       } // end switch
  2111.  
  2112. // we have failed
  2113.  
  2114. return(0);
  2115.  
  2116. } // end Check_For_Phrase
  2117.  
  2118. ///////////////////////////////////////////////////////////////////////////////
  2119.  
  2120. void Print_Info_Strings(info_string strings[],char where)
  2121. {
  2122. // this function will print the info strings out of the sent array based
  2123. // on the the current location of the player i.e. bedroom, kitchen etc.
  2124.  
  2125. int index=0;
  2126.  
  2127. printf("\n");
  2128.  
  2129. // traverse list and print all string relating to this room
  2130.  
  2131. while(strings[index].type!='X')
  2132.      {
  2133.  
  2134.      // should this string be printed
  2135.  
  2136.      if (strings[index].type==where)
  2137.         {
  2138.  
  2139.         printf("\n%s",strings[index].string);
  2140.  
  2141.         } // end if this is a relevant string
  2142.  
  2143.      // next string
  2144.  
  2145.      index++;
  2146.  
  2147.      } // end while
  2148.  
  2149. printf("\n");
  2150.  
  2151. } // end Print_Info_Strings
  2152.  
  2153. ///////////////////////////////////////////////////////////////////////////////
  2154.  
  2155. void Introduction(void)
  2156. {
  2157.  
  2158. int index;
  2159.  
  2160. for (index=0; index<50; index++,printf("\n"));
  2161.  
  2162. // make the screen blue with white characters
  2163.  
  2164. printf("%c%c37;44m",27,91);
  2165.  
  2166. printf("\n     SSSSSSSSSS  H      H  AAAAAAAA  DDDDD     OOOOOOOO  W       W");
  2167. printf("\n     S           H      H  A      A  D    D    O      O  W       W");
  2168. printf("\n     S           H      H  A      A  D     D   O      O  W       W");
  2169. printf("\n     S           H      H  A      A  D      D  O      O  W       W");
  2170. printf("\n     S           H      H  A      A  D      D  O      O  W       W");
  2171. printf("\n     SSSSSSSSSS  HHHHHHHH  AAAAAAAA  D      D  O      O  W       W");
  2172. printf("\n              S  H      H  A      A  D      D  O      O  W       W");
  2173. printf("\n              S  H      H  A      A  D      D  O      O  W   W   W");
  2174. printf("\n              S  H      H  A      A  D      D  O      O  W   W   W");
  2175. printf("\n              S  H      H  A      A  D     D   O      O  W   W   W");
  2176. printf("\n              S  H      H  A      A  D    D    O      O  W   W   W");
  2177. printf("\n     SSSSSSSSSS  H      H  A      A  DDDDD     OOOOOOOO  WWWWWWWWW");
  2178. printf("\n                                                                  ");
  2179. printf("\n     L         AAAAAAA  NNNNNNN  DDDDDD                           ");
  2180. printf("\n     L         A     A  N     N  D     D                          ");
  2181. printf("\n     L         A     A  N     N  D      D                         ");
  2182. printf("\n     L         A     A  N     N  D      D                         ");
  2183. printf("\n     L         AAAAAAA  N     N  D      D                         ");
  2184. printf("\n     L         A     A  N     N  D      D                         ");
  2185. printf("\n     L         A     A  N     N  D     D                          ");
  2186. printf("\n     L         A     A  N     N  D    D                           ");
  2187. printf("\n     LLLLLLL   A     A  N     N  DDDDD                            ");
  2188. printf("\n                                                                  ");
  2189. printf("\n     By Andre' Lamothe                                            ");
  2190.  
  2191.  
  2192. while(!kbhit());
  2193.  
  2194. for (index=0; index<50; index++,printf("\n"));
  2195.  
  2196. } // end Introduction
  2197.  
  2198. // M A I N /////////////////////////////////////////////////////////////////////
  2199.  
  2200. void main(void)
  2201. {
  2202.  
  2203. // call up intro
  2204.  
  2205. Introduction();
  2206.  
  2207. printf("\n\nWelcome to the world of  S H A D O W  L A N D...\n\n\n");
  2208.  
  2209. // obtain users name to make game more personal
  2210.  
  2211. printf("\nWhat is your first name?");
  2212. scanf("%s",you.name);
  2213.  
  2214. // main event loop,note: it is NOT real-time
  2215.  
  2216. while(!global_exit)
  2217.      {
  2218.      // put up an input notice to user
  2219.  
  2220.      printf("\n\nWhat do you want to do?");
  2221.  
  2222.      // get the line of text
  2223.  
  2224.      Get_Line(global_input);
  2225.  
  2226.      printf("\n");
  2227.  
  2228.      // break the text down into tokens and build up a sentence
  2229.  
  2230.      Extract_Tokens(global_input);
  2231.  
  2232.      // parse the verb and execute the command
  2233.  
  2234.      Verb_Parser();
  2235.  
  2236.      } // end main event loop
  2237.  
  2238. printf("\n\nExiting the universe of S H A D O W  L A N D...see you later %s.\n",you.name);
  2239.  
  2240. // restore screen color
  2241.  
  2242. printf("%c%c37;40m",27,91);
  2243.  
  2244. } // end main
  2245.  
  2246.  
  2247.