Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Colossal Cave: https://en.wikipedia.org/wiki/Colossal_Cave_Adventure For this ex

ID: 3863515 • Letter: C

Question

Colossal Cave: https://en.wikipedia.org/wiki/Colossal_Cave_Adventure

For this exercise complete the simple Dungeon game in the Inital Dungeon code. This is a fun way to learn about using classes and objects. You’ll be learning about a new type of Ruby data structure called the Struct class(p. 139) – it’s a simple was to create a data structure that is sometime preferable to using a class.

You’ll notice that the Dungeon game is one large class with several nested classes within it: Player and Room. All of the action takes place inside of the Dungeon class.

There may be several points in putting the dungeon code together that you will have to re-factor the code. Be sure to follow instructions carefully.

Assemble the Dungeon from the code given the Inital Dungeon code into a file named dungeon.rb.

Add at least two more rooms to your dungeon.

Run your code and capture the output into a file named dungeon.txt.

Inital Dungeon code:

class Dungeon attr_accessor :player def initialize(player_name) @player = Player.new(player_name) @rooms = [] end class Player attr_accessor :name, :location def initialize(player_name) @name = player_name end end class Room attr_accessor :reference, :name, :description, :connections def initialize(reference, name, description, connections) @reference = reference @name = name @description = description @connections = connections end end end doug@theLinuxPC:lhome/doug/Dropbox/sass master n/Dropbox/sass master adventure Welcome to Adventure Would you like instructions? Somewhere nearby is Colossal Cave, where others have found fortunes in treasure and gold, though it is rumored that some who enter are never seen again. Magic is said to work in the cave I will be your eyes and hands Direct me with commands of 1 or 2 words I should warn you that I look at only the first five letters of each word, so you'll have to enter northeast" as "ne" to distinguish it from "north". (Should you get stuck, type "help" for some general hints For information on how to end your adventure etc., type "info".) This program was originally developed by Will Crowther Most of the features of the current program were added by Don Woods. Address complaints about the UNIX version to Jim Gillogly (jimorand.org). You are standing at the end of a road before a small brick building. Around you is a forest. A small stream flows out of the building and down a gully. Figure 1 Colossal Cave (1976) was a text adventure game that ran on mainframe computers. The Dungeon game we'll build is a very simple version of it

Explanation / Answer

We can write programming in C as below-


/*   program ADVENT.C                   *
*   WARNING: "advent.c" allocates GLOBAL storage space by   *
*       including "advdef.h".               *
*       All other modules use "advdec.h"       */


#include   <stdio.h>   /* drv = 1.1st file 2.def 3.A   */
#include   "advent.h"   /* #define preprocessor equates   */
#include   "advword.h"   /* definition of "word" array   */
#include   "advcave.h"   /* definition of "cave" array   */
#include   "advtext.h"   /* definition of "text" arrays   */
#include   "advdef.h"

#ifndef __QNX__
#define   strchr   index

extern   int   fclose();
extern   int   fgetc();
extern   FILE   *fopen();
extern   int   fputc();
extern   long   ftell();
extern   int   printf();
extern   int   setmem();
extern   int   scanf();
extern   int   sscanf();
extern   char   *strcat();
extern   char   *strchr();
extern   unsigned   strlen();
extern   int   tolower();
#else
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define setmem(l,s,c) memset(l,c,s)
#endif

main(argc, argv)
int   argc;
char   **argv;
{
   int   rflag;       /* user restore request option   */

   rflag = 0;
   dbugflg = 0;
   while (--argc > 0) {
       ++argv;
       if (**argv != '-')
           break;
       switch(tolower(argv[0][1])) {
       case 'r':
           ++rflag;
           continue;
       case 'd':
           ++dbugflg;
           continue;
       default:
           printf("unknown flag: %c ", argv[0][1]);
           continue;
       }               /* switch   */
   }                   /* while   */
   if (dbugflg < 2)
       dbugflg = 0;   /* must request three times   */
   opentxt();
   initplay();
   if (rflag)
       restore();
   else if (yes(65, 1, 0))
       limit = 1000;
   else
       limit = 330;
   saveflg = 0;
   srand(511);               /* seed random   */
   while(!saveflg)
       turn();
   if (saveflg)
       saveadv();
   fclose(fd1);
   fclose(fd2);
   fclose(fd3);
   fclose(fd4);
   exit(0);               /* exit = ok   */
}                       /* main       */

/* ************************************************************   */

/*
   Initialize integer arrays with sscanf
*/
scanint(pi, str)
int   *pi;
char   *str;
{

   while (*str) {
       if ((sscanf(str, "%d,", pi++)) < 1)
           bug(41);   /* failed before EOS   */
       while (*str++ != ',')   /* advance str pointer   */
           ;
   }
   return;
}

/*
   Initialization of adventure play variables
*/
initplay()
{
   turns = 0;

   /* initialize location status array */
   setmem(cond, (sizeof(int))*MAXLOC, 0);
   scanint(&cond[1], "5,1,5,5,1,1,5,17,1,1,");
   scanint(&cond[13], "32,0,0,2,0,0,64,2,");
   scanint(&cond[21], "2,2,0,6,0,2,");
   scanint(&cond[31], "2,2,0,0,0,0,0,4,0,2,");
   scanint(&cond[42], "128,128,128,128,136,136,136,128,128,");
   scanint(&cond[51], "128,128,136,128,136,0,8,0,2,");
   scanint(&cond[79], "2,128,128,136,0,0,8,136,128,0,2,2,");
   scanint(&cond[95], "4,0,0,0,0,1,");
   scanint(&cond[113], "4,0,1,1,");
   scanint(&cond[122], "8,8,8,8,8,8,8,8,8,");

   /* initialize object locations */
   setmem(place, (sizeof(int))*MAXOBJ, 0);
   scanint(&place[1], "3,3,8,10,11,0,14,13,94,96,");
   scanint(&place[11], "19,17,101,103,0,106,0,0,3,3,");
   scanint(&place[23], "109,25,23,111,35,0,97,");
   scanint(&place[31], "119,117,117,0,130,0,126,140,0,96,");
   scanint(&place[50], "18,27,28,29,30,");
   scanint(&place[56], "92,95,97,100,101,0,119,127,130,");

   /* initialize second (fixed) locations */
   setmem(fixed, (sizeof(int))*MAXOBJ, 0);
   scanint(&fixed[3], "9,0,0,0,15,0,-1,");
   scanint(&fixed[11], "-1,27,-1,0,0,0,-1,");
   scanint(&fixed[23], "-1,-1,67,-1,110,0,-1,-1,");
   scanint(&fixed[31], "121,122,122,0,-1,-1,-1,-1,0,-1,");
   scanint(&fixed[62], "121,-1,");

   /* initialize default verb messages */
   scanint(actmsg, "0,24,29,0,33,0,33,38,38,42,14,");
   scanint(&actmsg[11], "43,110,29,110,73,75,29,13,59,59,");
   scanint(&actmsg[21], "174,109,67,13,147,155,195,146,110,13,13,");

   /* initialize various flags and other variables */
   setmem(visited, (sizeof(int))*MAXLOC, 0);
   setmem(prop, (sizeof(int))*MAXOBJ, 0);
   setmem(&prop[50], (sizeof(int))*(MAXOBJ-50), 0xff);
   wzdark = closed = closing = holding = detail = 0;
   limit = 100;
   tally = 15;
   tally2 = 0;
   newloc = 3;
   loc = oldloc = oldloc2 = 1;
   knfloc = 0;
   chloc = 114;
   chloc2 = 140;
/*   dloc[DWARFMAX-1] = chloc               */
   scanint(dloc, "0,19,27,33,44,64,114,");
   scanint(odloc, "0,0,0,0,0,0,0,");
   dkill = 0;
   scanint(dseen, "0,0,0,0,0,0,0,");
   clock = 30;
   clock2 = 50;
   panic = 0;
   bonus = 0;
   numdie = 0;
   daltloc = 18;
   lmwarn = 0;
   foobar = 0;
   dflag = 0;
   gaveup = 0;
   saveflg = 0;
   return;
}

/*
   Open advent?.txt files
*/

#define ADV1 "/usr/local/lib/games/advent1.txt"
#define ADV2 "/usr/local/lib/games/advent2.txt"
#define ADV3 "/usr/local/lib/games/advent3.txt"
#define ADV4 "/usr/local/lib/games/advent4.txt"

opentxt()
{
   fd1 = fopen(ADV1, "r");
   if (!fd1) {
       printf("Sorry, I can't open advent1.txt... ");
       exit(-1);
   }
   fd2 = fopen(ADV2, "r");
   if (!fd2) {
       printf("Sorry, I can't open advent2.txt... ");
       exit(-1);
   }
   fd3 = fopen(ADV3, "r");
   if (!fd3) {
       printf("Sorry, I can't open advent3.txt... ");
       exit(-1);
   }
   fd4 = fopen(ADV4, "r");
   if (!fd4) {
       printf("Sorry, I can't open advent4.txt... ");
       exit(-1);
   }
}

/*
       save adventure game
*/
saveadv()
{
   char   *sptr;
   FILE   *savefd;
   char   username[64];

#ifndef __QNX__
   printf("What do you want to name the saved game? ");
   gets(username);
   if (sptr = strchr(username, '.'))
       *sptr = '';       /* kill extension   */
   if (strlen(username) > 8)
       username[8] = '';   /* max 8 char filename   */
   strcat(username, ".adv");
#else
   game_name(username);
#endif
   savefd = fopen(username, "wb");
   if (savefd == NULL) {
       printf("Sorry, I can't save your game... Aborting program... ");
       exit(-1);
   }
   fwrite( &turns, sizeof(int), 1, savefd);
   fwrite( &loc, sizeof(int), 1, savefd);
   fwrite( &oldloc, sizeof(int), 1, savefd);
   fwrite( &oldloc2, sizeof(int), 1, savefd);
   fwrite( &newloc, sizeof(int), 1, savefd);   /* location variables */
   fwrite( &cond[0], sizeof(int), MAXLOC, savefd);           /* location status   */
   fwrite( &place[0], sizeof(int), MAXOBJ, savefd);       /* object location   */
   fwrite( &fixed[0], sizeof(int), MAXOBJ, savefd);       /* second object loc   */
   fwrite( &visited[0], sizeof(int), MAXLOC, savefd);       /* >0 if has been here   */
   fwrite( &prop[0], sizeof(int), MAXOBJ, savefd);           /* status of object   */
   fwrite( &tally, sizeof(int), 1, savefd);
   fwrite( &tally2, sizeof(int), 1, savefd);       /* item counts       */
   fwrite( &limit, sizeof(int), 1, savefd);           /* time limit       */
   fwrite( &lmwarn, sizeof(int), 1, savefd);           /* lamp warning flag   */
   fwrite( &wzdark, sizeof(int), 1, savefd);
   fwrite( &closing, sizeof(int), 1, savefd);
   fwrite( &closed, sizeof(int), 1, savefd);   /* game state flags   */
   fwrite( &holding, sizeof(int), 1, savefd);       /* count of held items   */
   fwrite( &detail, sizeof(int), 1, savefd);           /* LOOK count       */
   fwrite( &knfloc, sizeof(int), 1, savefd);           /* knife location   */
   fwrite( &clock, sizeof(int), 1, savefd);
   fwrite( &clock2, sizeof(int), 1, savefd);
   fwrite( &panic, sizeof(int), 1, savefd);   /* timing variables   */
   fwrite( &dloc[0], sizeof(int), DWARFMAX, savefd);           /* dwarf locations   */
   fwrite( &dflag, sizeof(int), 1, savefd);           /* dwarf flag       */
   fwrite( &dseen[0], sizeof(int), DWARFMAX, savefd);       /* dwarf seen flag   */
   fwrite( &odloc[0], sizeof(int), DWARFMAX, savefd);       /* dwarf old locations   */
   fwrite( &daltloc, sizeof(int), 1, savefd);       /* alternate appearance   */
   fwrite( &dkill, sizeof(int), 1, savefd);           /* dwarves killed   */
   fwrite( &chloc, sizeof(int), 1, savefd);
   fwrite( &chloc2, sizeof(int), 1, savefd);       /* chest locations   */
   fwrite( &bonus, sizeof(int), 1, savefd);           /* to pass to end   */
   fwrite( &numdie, sizeof(int), 1, savefd);           /* number of deaths   */
   fwrite( &object1, sizeof(int), 1, savefd);       /* to help intrans.   */
   fwrite( &gaveup, sizeof(int), 1, savefd);           /* 1 if he quit early   */
   fwrite( &foobar, sizeof(int), 1, savefd);           /* fie fie foe foo...   */
   if (fclose(savefd) == -1) {
       printf("Sorry, I can't close the file...%s ",
               username);
       exit(-1);
   }
   printf("Game saved -- see you later... ");
}

/*
   restore saved game handler
*/
restore()
{
   char   username[64];
   FILE *restfd;
   int c;
   char   *sptr;

#ifndef __QNX__
   printf("What is the name of the saved game? ");
   gets(username);
   if (sptr = strchr(username, '.'))
       *sptr = '';       /* kill extension   */
   if (strlen(username) > 8)
       username[8] = '';   /* max 8 char filename   */
   strcat(username, ".adv");
#else
   game_name(username);
#endif
   restfd = fopen(username, "rb");
   if (restfd == NULL) {
       printf("Sorry, no game to load... ");
       return;
   }
   fread( &turns, sizeof(int), 1, restfd);
   fread( &loc, sizeof(int), 1, restfd);
   fread( &oldloc, sizeof(int), 1, restfd);
   fread( &oldloc2, sizeof(int), 1, restfd);
   fread( &newloc, sizeof(int), 1, restfd);   /* location variables */
   fread( &cond[0], sizeof(int), MAXLOC, restfd);           /* location status   */
   fread( &place[0], sizeof(int), MAXOBJ, restfd);       /* object location   */
   fread( &fixed[0], sizeof(int), MAXOBJ, restfd);       /* second object loc   */
   fread( &visited[0], sizeof(int), MAXLOC, restfd);       /* >0 if has been here   */
   fread( &prop[0], sizeof(int), MAXOBJ, restfd);           /* status of object   */
   fread( &tally, sizeof(int), 1, restfd);
   fread( &tally2, sizeof(int), 1, restfd);       /* item counts       */
   fread( &limit, sizeof(int), 1, restfd);           /* time limit       */
   fread( &lmwarn, sizeof(int), 1, restfd);           /* lamp warning flag   */
   fread( &wzdark, sizeof(int), 1, restfd);
   fread( &closing, sizeof(int), 1, restfd);
   fread( &closed, sizeof(int), 1, restfd);   /* game state flags   */
   fread( &holding, sizeof(int), 1, restfd);       /* count of held items   */
   fread( &detail, sizeof(int), 1, restfd);           /* LOOK count       */
   fread( &knfloc, sizeof(int), 1, restfd);           /* knife location   */
   fread( &clock, sizeof(int), 1, restfd);
   fread( &clock2, sizeof(int), 1, restfd);
   fread( &panic, sizeof(int), 1, restfd);   /* timing variables   */
   fread( &dloc[0], sizeof(int), DWARFMAX, restfd);           /* dwarf locations   */
   fread( &dflag, sizeof(int), 1, restfd);           /* dwarf flag       */
   fread( &dseen[0], sizeof(int), DWARFMAX, restfd);       /* dwarf seen flag   */
   fread( &odloc[0], sizeof(int), DWARFMAX, restfd);       /* dwarf old locations   */
   fread( &daltloc, sizeof(int), 1, restfd);       /* alternate appearance   */
   fread( &dkill, sizeof(int), 1, restfd);           /* dwarves killed   */
   fread( &chloc, sizeof(int), 1, restfd);
   fread( &chloc2, sizeof(int), 1, restfd);       /* chest locations   */
   fread( &bonus, sizeof(int), 1, restfd);           /* to pass to end   */
   fread( &numdie, sizeof(int), 1, restfd);           /* number of deaths   */
   fread( &object1, sizeof(int), 1, restfd);       /* to help intrans.   */
   fread( &gaveup, sizeof(int), 1, restfd);           /* 1 if he quit early   */
   fread( &foobar, sizeof(int), 1, restfd);           /* fie fie foe foo...   */
   if (fclose(restfd) == -1) {
       printf("Warning -- can't close save file...%s ",
               username);
   }
   printf("Game restored... ");
   describe();
}

char *game_name(filename)
char *filename;
{

   char *homedir;

   filename[0] = 0;
   if(homedir = getenv("HOME")) {
       strcat(filename, homedir);
       strcat(filename, "/");
   }
   strcat(filename, ".adventure");
   return(filename);
}


/*   program ADVENT0.C                   *
*   execution will read the four adventure text files   *
*   files; "advent1.txt", "advent2.txt", "advent3.txt" &   *
*   "advent4.txt". it will create the file "advtext.h"   *
*   which is an Index Sequential Access Method (ISAM)   *
*   header to be #included into "advent.c" before the   *
*   header "advdef.h" is #included.               */


#include   <stdio.h>   /* drv = 1.1st file 2.def 3.A   */
#include   "advent.h"

#ifndef __QNX__
extern   int   fclose();
extern   char   *fgets();
extern   FILE   *fopen();
extern   int   fprintf();
extern   int   fputs();
extern   long   ftell();
extern   int   printf();
#else
#include <stdlib.h>
#include <ctype.h>
#define Ltoa(a,b) strlen(ltoa(a,b,10))
#endif


int
main(argc, argv)
int   argc;
char   **argv;
{

   FILE   *isam, *fd1, *fd2, *fd3, *fd4;
   char   itxt[255], otxt[80], lstr[12];
   int   cnt, llen;

   isam = fopen("advtext.h", "w");
   if (!isam) {
       printf("Sorry, I can't open advtext.h... ");
       exit(-1);
   }
   fd1 = fopen("advent1.txt", "r");
   if (!fd1) {
       printf("Sorry, I can't open advent1.txt... ");
       exit(-1);
   }
   fd2 = fopen("advent2.txt", "r");
   if (!fd2) {
       printf("Sorry, I can't open advent2.txt... ");
       exit(-1);
   }
   fd3 = fopen("advent3.txt", "r");
   if (!fd3) {
       printf("Sorry, I can't open advent3.txt... ");
       exit(-1);
   }
   fd4 = fopen("advent4.txt", "r");
   if (!fd4) {
       printf("Sorry, I can't open advent4.txt... ");
       exit(-1);
   }

   fprintf(isam, " /");
   fprintf(isam, "* header: ADVTEXT.H */ ");


   cnt = -1;
   lstr[0] = '';
   fprintf(isam, "long idx1[MAXLOC] = { ");
   while (fgets(itxt, 255, fd1)) {
/*       printf("%s", itxt); */
       if (itxt[0] == '#') {
           if (lstr[0])
               fprintf(isam, "%s,", lstr);
           llen = Ltoa(ftell(fd1), lstr);
           if (!llen) {
               printf("Ltoa err in advent1.txt ");
               exit(-1);
           }           /* if (!llen)   */
           if (++cnt == 5) {
               fprintf(isam, " ");
               cnt = 0;
           }           /* if (cnt)   */
       }               /* if (itxt[0])   */
   }                   /* while fgets   */
   fprintf(isam, "%s }; ", lstr);

   cnt = -1;
   lstr[0] = '';
   fprintf(isam, "long idx2[MAXLOC] = { ");
   while (fgets(itxt, 255, fd2)) {
/*       printf("%s", itxt); */
       if (itxt[0] == '#') {
           if (lstr[0])
               fprintf(isam, "%s,", lstr);
           llen = Ltoa(ftell(fd2), lstr);
           if (!llen) {
               printf("Ltoa err in advent2.txt ");
               exit(-1);
           }           /* if (!llen)   */
           if (++cnt == 5) {
               fprintf(isam, " ");
               cnt = 0;
           }           /* if (cnt)   */
       }               /* if (itxt[0])   */
   }                   /* while fgets   */
   fprintf(isam, "%s }; ", lstr);

   cnt = -1;
   lstr[0] = '';
   fprintf(isam, "long idx3[MAXOBJ] = { ");
   while (fgets(itxt, 255, fd3)) {
/*       printf("%s", itxt); */
       if (itxt[0] == '#') {
           if (lstr[0])
               fprintf(isam, "%s,", lstr);
           llen = Ltoa(ftell(fd3), lstr);
           if (!llen) {
               printf("Ltoa err in advent3.txt ");
               exit(-1);
           }           /* if (!llen)   */
           if (++cnt == 5) {
               fprintf(isam, " ");
               cnt = 0;
           }           /* if (cnt)   */
       }               /* if (itxt[0])   */
   }                   /* while fgets   */
   fprintf(isam, "%s }; ", lstr);

   cnt = -1;
   lstr[0] = '';
   fprintf(isam, "long idx4[MAXMSG] = { ");
   while (fgets(itxt, 255, fd4)) {
/*       printf("%s", itxt); */
       if (itxt[0] == '#') {
           if (lstr[0])
               fprintf(isam, "%s,", lstr);
           llen = Ltoa(ftell(fd4), lstr);
           if (!llen) {
               printf("Ltoa err in advent4.txt ");
               exit(-1);
           }           /* if (!llen)   */
           if (++cnt == 5) {
               fprintf(isam, " ");
               cnt = 0;
           }           /* if (cnt)   */
       }               /* if (itxt[0])   */
   }                   /* while fgets   */
   fprintf(isam, "%s }; ", lstr);

   fclose(isam);
   fclose(fd1);
   fclose(fd2);
   fclose(fd3);
   fclose(fd4);
   printf("Datafile processing done!! ");
   return(0);
}                       /* main       */


/*   program DATABASE.C                   *
*   WARNING: "advent.c" allocates GLOBAL storage space by   *
*       including "advdef.h".               *
*       All other modules use "advdec.h".       */


#include   <stdio.h>   /* drv = 1.1st file 2.def 3.A   */
#include   "advent.h"
#include   "advdec.h"

#ifndef __QNX__
extern   long   atoi();
extern   int   fgetc();
extern   char   *fgets();
extern   int   fputc();
extern   long   fseek();
extern   char   *rindex();
extern   char   *strcpy();
extern   int   tolower();
#else
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define atoi atol
#define rindex strrchr
#endif


/*
   Routine to fill travel array for a given location
*/
gettrav(loc)
int   loc;
{
   int   i;
   long   t;
   char   atrav[256], *aptr;

   strcpy(atrav, cave[loc - 1]);
   while (aptr = rindex(atrav, ','))
       *aptr = '';       /* terminate substring   */
   aptr = &atrav[0];
   for (i = 0; i < MAXTRAV; ++i) {
       t = atoi(aptr);       /* convert to long int   */
       travel[i].tcond = (int) (t % 1000L);
       t /= 1000L;
       travel[i].tverb = (int) (t % 1000L);
       t /= 1000L;
       travel[i].tdest = (int) (t % 1000L);
       while (*(aptr++));       /* to next substring   */
       if (!(*aptr)) {
            travel[++i].tdest = -1;/* end of array   */
            if (dbugflg)
           for (i = 0; i < MAXTRAV; ++i)
               printf("cave[%d] = %d %d %d ",
               loc, travel[i].tdest,
               travel[i].tverb, travel[i].tcond);
            return;       /* terminate for loop   */
       }
   }
   bug(33);
}

/*
   Function to scan a file up to a specified
   point and either print or return a string.
*/
rdupto(fdi, uptoc, print, string)
FILE   *fdi;
char   uptoc, print, *string;
{
   int   c;

   while ((c = fgetc(fdi)) != uptoc) {
       if (c == EOF)
           return(0);
       if (c == ' ')
           continue;
       if (print)
           fputc(c, stdout);
       else
           *string++ = c;
   }
   if (!print)
       *string = '';
   return(1);
}

/*
   Function to read a file skipping
   a given character a specified number
   of times, with or without repositioning
   the file.
*/
rdskip(fdi, skipc, n, rewind)
FILE   *fdi;
char   skipc, rewind;
int   n;
{
   int   c;

   if (rewind)
       if (fseek(fdi, 0, 0) == -1)
           bug(31);
   while (n--)
       while ((c = fgetc(fdi)) != skipc)
           if (c == EOF)
               bug(32);
}

/*
   Routine to request a yes or no answer to a question.
*/
yes(msg1, msg2, msg3)
int   msg1, msg2, msg3;
{
   char   answer[80];

   if (msg1)
       rspeak(msg1);
   fputc('>', stdout);
   fgets(answer, 80, stdin);
   if (tolower(answer[0]) == 'n') {
       if (msg3)
           rspeak(msg3);
       return(0);
   }
   if (msg2)
       rspeak(msg2);
   return(1);
}

/*
   Print a location description from "advent4.txt"
*/
rspeak(msg)
int   msg;
{
   if (msg == 54)
       printf("ok. ");
   else {
       if (dbugflg)
            printf("Seek loc msg #%d @ %ld ", msg, idx4[msg]);
       fseek(fd4, idx4[msg - 1], 0);
       rdupto(fd4, '#', 1, 0);
   }
   return;
}

/*
   Print an item message for a given state from "advent3.txt"
*/
pspeak(item, state)
int   item, state;
{
   fseek(fd3, idx3[item - 1], 0);
   rdskip(fd3, '/', state+2, 0);
   rdupto(fd3, '/', 1, 0);
}

/*
   Print a long location description from "advent1.txt"
*/
desclg(loc)
int   loc;
{
   fseek(fd1, idx1[loc - 1], 0);
   rdupto(fd1, '#', 1, 0);
}

/*
   Print a short location description from "advent2.txt"
*/
descsh(loc)
int   loc;
{
   fseek(fd2, idx2[loc - 1], 0);
   rdupto(fd2, '#', 1, 0);
}

/*
   look-up vocabulary word in lex-ordered table. words may have
   two entries with different codes. if minimum acceptable value
   = 0, then return minimum of different codes. last word CANNOT
   have two entries(due to binary sort).
   word is the word to look up.
   val is the minimum acceptable value,
       if != 0 return %1000
*/
vocab(word, val)
char   *word;
int   val;
{
   int   v1, v2;

   if ((v1 = binary(word, wc, MAXWC)) >= 0) {
       v2 = binary(word, wc, MAXWC-1);
       if (v2 < 0)
           v2 = v1;
       if (!val)
           return(wc[v1].acode < wc[v2].acode
                   ? wc[v1].acode : wc[v2].acode);
       if (val <= wc[v1].acode)
           return(wc[v1].acode % 1000);
       else if (val <= wc[v2].acode)
           return(wc[v2].acode % 1000);
       else
           return(-1);
   }
   else
       return(-1);
}

binary(w, wctable, maxwc)
char   *w;
int   maxwc;
struct   wac   wctable[];
{
   int   lo, mid, hi, check;

   lo = 0;
   hi = maxwc - 1;
   while (lo <= hi) {
       mid = (lo + hi) / 2;
       if ((check = strcmp(w, wctable[mid].aword)) < 0)
           hi = mid - 1;
       else if (check > 0)
           lo = mid + 1;
       else
           return(mid);
   }
   return(-1);
}


/*
   Utility Routines
*/

/*
   Routine to test for darkness
*/
dark()
{
   return(!(cond[loc] & LIGHT) &&
       (!prop[LAMP] ||
       !here(LAMP)));
}

/*
   Routine to tell if an item is present.
*/
here(item)
int   item;
{
   return(place[item] == loc || toting(item));
}

/*
   Routine to tell if an item is being carried.
*/
toting(item)
int   item;
{
   return(place[item] == -1);
}

/*
   Routine to tell if a location causes
   a forced move.
*/
forced(atloc)
int   atloc;
{
   return(cond[atloc] == 2);
}

/*
   Routine true x% of the time.
*/
pct(x)
int   x;
{
   return(rand() % 100 < x);
}

/*
   Routine to tell if player is on
   either side of a two sided object.
*/
at(item)
int   item;
{
   return(place[item] == loc || fixed[item] == loc);
}

/*
   Routine to destroy an object
*/
dstroy(obj)
int   obj;
{
   move(obj, 0);
}

/*
   Routine to move an object
*/
move(obj, where)
int   obj, where;
{
   int   from;

   from = (obj<MAXOBJ) ? place[obj] : fixed[obj];
   if (from>0 && from<=300)
       carry(obj, from);
   drop(obj, where);
}

/*
   Juggle an object
   currently a no-op
*/
juggle(loc)
int   loc;
{
}

/*
   Routine to carry an object
*/
carry(obj, where)
int   obj, where;
{
   if (obj<MAXOBJ){
       if (place[obj] == -1)
           return;
       place[obj]=-1;
       ++holding;
   }
}

/*
   Routine to drop an object
*/
drop(obj, where)
int   obj, where;
{
   if (obj<MAXOBJ) {
       if (place[obj] == -1)
           --holding;
       place[obj]=where;
   }
   else
       fixed[obj-MAXOBJ]=where;
}

/*
   routine to move an object and return a
   value used to set the negated prop values
   for the repository.
*/
put(obj, where, pval)
int   obj, where, pval;
{
   move(obj, where);
   return((-1)-pval);
}
/*
   Routine to check for presence
   of dwarves..
*/
dcheck()
{
   int   i;

   for (i =1; i < (DWARFMAX-1); ++i)
       if (dloc[i] == loc)
           return(i);
   return(0);
}

/*
   Determine liquid in the bottle
*/
liq()
{
   int   i, j;
   i=prop[BOTTLE];
   j=-1-i;
   return(liq2(i>j ? i : j));
}

/*
   Determine liquid at a location
*/
liqloc(loc)
int   loc;
{
   if (cond[loc]&LIQUID)
       return(liq2(cond[loc]&WATOIL));
   else
       return(liq2(1));
}

/*
   Convert 0 to WATER
       1 to nothing
       2 to OIL
*/
liq2(pbottle)
int   pbottle;
{
   return((1-pbottle)*WATER+(pbottle>>1)*(WATER+OIL));
}

/*
   Fatal error routine
*/
bug(n)
int   n;
{
   printf("Fatal error number %d ", n);
   exit(-1);
}