Commit | Line | Data |
---|---|---|
da1ddb48 KB |
1 | /*- |
2 | * Copyright (c) 1991 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * The game adventure was original written Fortran by Will Crowther | |
6 | * and Don Woods. It was later translated to C and enhanced by | |
7 | * Jim Gillogly. | |
8 | * | |
9 | * %sccs.include.redist.c% | |
10 | */ | |
11 | ||
12 | #ifndef lint | |
13 | static char sccsid[] = "@(#)vocab.c 5.1 (Berkeley) %G%"; | |
14 | #endif /* not lint */ | |
83d38910 | 15 | |
da1ddb48 | 16 | /* Re-coding of advent in C: data structure routines */ |
83d38910 RH |
17 | |
18 | # include "hdr.h" | |
19 | ||
20 | dstroy(object) | |
21 | int object; | |
22 | { move(object,0); | |
23 | } | |
24 | ||
25 | juggle(object) | |
26 | int object; | |
27 | { register int i,j; | |
28 | i=place[object]; | |
29 | j=fixed[object]; | |
30 | move(object,i); | |
31 | move(object+100,j); | |
32 | } | |
33 | ||
34 | ||
35 | move(object,where) | |
36 | int object,where; | |
37 | { register int from; | |
38 | if (object<=100) | |
39 | from=place[object]; | |
40 | else | |
41 | from=fixed[object-100]; | |
42 | if (from>0 && from<=300) carry(object,from); | |
43 | drop(object,where); | |
44 | } | |
45 | ||
46 | ||
47 | put(object,where,pval) | |
48 | int object,where,pval; | |
49 | { move(object,where); | |
50 | return(-1-pval); | |
51 | } | |
52 | ||
53 | ||
54 | ||
55 | carry(object,where) | |
56 | int object,where; | |
57 | { register int temp; | |
58 | if (object<=100) | |
59 | { if (place[object]== -1) return; | |
60 | place[object] = -1; | |
61 | holdng++; | |
62 | } | |
63 | if (atloc[where]==object) | |
64 | { atloc[where]=link[object]; | |
65 | return; | |
66 | } | |
67 | for (temp=atloc[where]; link[temp]!=object; temp=link[temp]); | |
68 | link[temp]=link[object]; | |
69 | } | |
70 | ||
71 | ||
72 | ||
73 | ||
74 | drop(object,where) | |
75 | int object,where; | |
76 | { if (object>100) fixed[object-100]=where; | |
77 | else | |
78 | { if (place[object]== -1) holdng--; | |
79 | place[object]=where; | |
80 | } | |
81 | if (where<=0) return; | |
82 | link[object]=atloc[where]; | |
83 | atloc[where]=object; | |
84 | } | |
85 | ||
86 | ||
87 | vocab(word,type,value) /* look up or store a word */ | |
88 | char *word; | |
89 | int type; /* -2 for store, -1 for user word, >=0 for canned lookup*/ | |
90 | int value; /* used for storing only */ | |
91 | { register int adr; | |
92 | register char *s,*t; | |
93 | int hash, i; | |
94 | struct hashtab *h; | |
95 | for (hash=0,s=word,i=0; i<5 &&*s; i++) /* some kind of hash */ | |
96 | hash += *s++; /* add all chars in the word */ | |
97 | hash = (hash*3719)&077777; /* pulled that one out of a hat */ | |
98 | hash %= HTSIZE; /* put it into range of table */ | |
99 | ||
100 | for(adr=hash;; adr++) /* look for entry in table */ | |
101 | { if (adr==HTSIZE) adr=0; /* wrap around */ | |
102 | h = &voc[adr]; /* point at the entry */ | |
103 | switch(type) | |
104 | { case -2: /* fill in entry */ | |
105 | if (h->val) /* already got an entry? */ | |
106 | goto exitloop2; | |
107 | h->val=value; | |
108 | h->atab=malloc(length(word)); | |
109 | for (s=word,t=h->atab; *s;) | |
110 | *t++ = *s++ ^ '='; | |
111 | *t=0^'='; | |
112 | /* encrypt slightly to thwart core reader */ | |
113 | /* printf("Stored \"%s\" (%d ch) as entry %d\n", */ | |
114 | /* word, length(word), adr); */ | |
115 | return(0); /* entry unused */ | |
116 | case -1: /* looking up user word */ | |
117 | if (h->val==0) return(-1); /* not found */ | |
118 | for (s=word, t=h->atab;*t ^ '=';) | |
119 | if ((*s++ ^ '=') != *t++) | |
120 | goto exitloop2; | |
121 | if ((*s ^ '=') != *t && s-word<5) goto exitloop2; | |
122 | /* the word matched o.k. */ | |
123 | return(h->val); | |
124 | default: /* looking up known word */ | |
125 | if (h->val==0) | |
126 | { printf("Unable to find %s in vocab\n",word); | |
127 | exit(0); | |
128 | } | |
129 | for (s=word, t=h->atab;*t ^ '=';) | |
130 | if ((*s++ ^ '=') != *t++) goto exitloop2; | |
131 | /* the word matched o.k. */ | |
132 | if (h->val/1000 != type) continue; | |
133 | return(h->val%1000); | |
134 | } | |
135 | ||
136 | exitloop2: /* hashed entry does not match */ | |
137 | if (adr+1==hash || (adr==HTSIZE && hash==0)) | |
138 | { printf("Hash table overflow\n"); | |
139 | exit(0); | |
140 | } | |
141 | } | |
142 | } | |
143 | ||
144 | ||
145 | copystr(w1,w2) /* copy one string to another */ | |
146 | char *w1,*w2; | |
147 | { register char *s,*t; | |
148 | for (s=w1,t=w2; *s;) | |
149 | *t++ = *s++; | |
150 | *t=0; | |
151 | } | |
152 | ||
153 | weq(w1,w2) /* compare words */ | |
154 | char *w1,*w2; /* w1 is user, w2 is system */ | |
155 | { register char *s,*t; | |
156 | register int i; | |
157 | s=w1; | |
158 | t=w2; | |
159 | for (i=0; i<5; i++) /* compare at most 5 chars */ | |
160 | { if (*t==0 && *s==0) | |
161 | return(TRUE); | |
162 | if (*s++ != *t++) return(FALSE); | |
163 | } | |
164 | return(TRUE); | |
165 | } | |
166 | ||
167 | ||
168 | length(str) /* includes 0 at end */ | |
169 | char *str; | |
170 | { register char *s; | |
171 | register int n; | |
172 | for (n=0,s=str; *s++;) n++; | |
173 | return(n+1); | |
174 | } | |
175 | ||
176 | prht() /* print hash table */ | |
177 | { register int i,j,l; | |
178 | char *c; | |
179 | struct hashtab *h; | |
180 | for (i=0; i<HTSIZE/10+1; i++) | |
181 | { printf("%4d",i*10); | |
182 | for (j=0; j<10; j++) | |
183 | { if (i*10+j>=HTSIZE) break; | |
184 | h= &voc[i*10+j]; | |
185 | putchar(' '); | |
186 | if (h->val==0) | |
187 | { printf("-----"); | |
188 | continue; | |
189 | } | |
190 | for (l=0, c=h->atab; l<5; l++) | |
191 | if ((*c ^ '=')) putchar(*c++ ^ '='); | |
192 | else putchar(' '); | |
193 | } | |
194 | putchar('\n'); | |
195 | } | |
196 | } | |
197 |