xref: /openbsd/games/adventure/vocab.c (revision db3296cf)
1 /*	$OpenBSD: vocab.c,v 1.10 2003/06/03 03:01:37 millert Exp $	*/
2 /*	$NetBSD: vocab.c,v 1.2 1995/03/21 12:05:13 cgd Exp $	*/
3 
4 /*-
5  * Copyright (c) 1991, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * The game adventure was originally written in Fortran by Will Crowther
9  * and Don Woods.  It was later translated to C and enhanced by Jim
10  * Gillogly.  This code is derived from software contributed to Berkeley
11  * by Jim Gillogly at The Rand Corporation.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #ifndef lint
39 #if 0
40 static char sccsid[] = "@(#)vocab.c	8.1 (Berkeley) 5/31/93";
41 #else
42 static char rcsid[] = "$OpenBSD: vocab.c,v 1.10 2003/06/03 03:01:37 millert Exp $";
43 #endif
44 #endif /* not lint */
45 
46 /*	Re-coding of advent in C: data structure routines		*/
47 
48 #include <err.h>
49 #include <stdio.h>
50 #include <stdlib.h>
51 #include "hdr.h"
52 #include "extern.h"
53 
54 void
55 dstroy(object)
56 	int	object;
57 {
58 	move(object, 0);
59 }
60 
61 void
62 juggle(object)
63 	int	object;
64 {
65 	int	i, j;
66 
67 	i = place[object];
68 	j = fixed[object];
69 	move(object, i);
70 	move(object + 100, j);
71 }
72 
73 
74 void
75 move(object, where)
76 	int	object, where;
77 {
78 	int	from;
79 
80 	if (object <= 100)
81 		from = place[object];
82 	else
83 		from = fixed[object - 100];
84 	if (from > 0 && from <= 300)
85 		carry(object, from);
86 	drop(object, where);
87 }
88 
89 
90 int
91 put(object, where, pval)
92 	int	object, where, pval;
93 {
94 	move(object, where);
95 	return (-1 - pval);
96 }
97 
98 
99 void
100 carry(object, where)
101 	int	object, where;
102 {
103 	int	temp;
104 
105 	if (object <= 100) {
106 		if (place[object] == -1)
107 			return;
108 		place[object] = -1;
109 		holdng++;
110 	}
111 	if (atloc[where] == object) {
112 		atloc[where] = linkx[object];
113 		return;
114 	}
115 	for (temp = atloc[where]; linkx[temp] != object; temp = linkx[temp])
116 		;
117 	linkx[temp] = linkx[object];
118 }
119 
120 
121 void
122 drop(object, where)
123 	int	object, where;
124 {
125 	if (object > 100)
126 		fixed[object - 100] = where;
127 	else {
128 		if (place[object] == -1)
129 			holdng--;
130 		place[object] = where;
131 	}
132 	if (where <= 0)
133 		return;
134 	linkx[object] = atloc[where];
135 	atloc[where] = object;
136 }
137 
138 
139 int
140 vocab(word, type, value)	/* look up or store a word	*/
141 	const char *word;
142 	int	type;		/* -2 for store, -1 for user word, >=0 for canned lookup*/
143 	int	value;		/* used for storing only	*/
144 {
145 	int	adr;
146 	const char *s;
147 	char	*t;
148 	int	hash, i;
149 	struct hashtab *h;
150 
151 	for (hash = 0, s = word, i = 0; i < 5 && *s; i++)  /* some kind of hash */
152 		hash += *s++;		/* add all chars in the word	*/
153 	hash = (hash * 3719) & 077777;	/* pulled that one out of a hat */
154 	hash %= HTSIZE;			/* put it into range of table	*/
155 
156 	for (adr = hash; ; adr++) {	/* look for entry in table	*/
157 		if (adr == HTSIZE)
158 			adr = 0; /* wrap around			*/
159 		h = &voc[adr];		/* point at the entry		*/
160 		switch (type) {
161 		case -2:		/* fill in entry		*/
162 			if (h->val)	/* already got an entry?	*/
163 				goto exitloop2;
164 			h->val = value;
165 			if ((h->atab = malloc(length(word))) == NULL)
166 				err(1, NULL);
167 			for (s = word, t = h->atab; *s;)
168 				*t++ = *s++ ^ '=';
169 			*t = 0 ^ '=';
170 			/* encrypt slightly to thwart core reader	*/
171 		/*	printf("Stored \"%s\" (%d ch) as entry %d\n",	*/
172 		/*		word, length(word), adr);		*/
173 			return (0);	/* entry unused			*/
174 		case -1:		/* looking up user word		*/
175 			if (h->val == 0)
176 				return (-1);	/* not found	*/
177 			for (s = word, t = h->atab; *t ^ '=';)
178 				if ((*s++ ^ '=') != *t++)
179 					goto exitloop2;
180 			if ((*s ^ '=') != *t && s - word < 5)
181 				goto exitloop2;
182 			/* the word matched o.k.			*/
183 			return (h->val);
184 		default:		/* looking up known word	*/
185 			if (h->val == 0)
186 				errx(1, "Unable to find %s in vocab", word);
187 			for (s = word, t = h->atab; *t ^ '=';)
188 				if ((*s++ ^ '=') != *t++)
189 					goto exitloop2;
190 			/* the word matched o.k.			*/
191 			if (h->val / 1000 != type)
192 				continue;
193 			return (h->val%1000);
194 		}
195 
196 exitloop2:			/* hashed entry does not match	*/
197 		if (adr + 1 == hash || (adr == HTSIZE && hash == 0))
198 			errx(1, "Hash table overflow");
199 	}
200 }
201 
202 void
203 prht()					/* print hash table		*/
204 {
205 	int	i, j, l;
206 	char	*c;
207 	struct hashtab *h;
208 
209 	for (i = 0; i < HTSIZE / 10 + 1; i++) {
210 		printf("%4d", i * 10);
211 		for (j = 0; j < 10; j++) {
212 			if (i * 10 + j >= HTSIZE)
213 				break;
214 			h = &voc[i * 10 + j];
215 			putchar(' ');
216 			if (h->val == 0) {
217 				printf("-----");
218 				continue;
219 			}
220 			for (l = 0, c = h->atab; l < 5; l++)
221 				if ((*c ^ '='))
222 					putchar(*c++ ^ '=');
223 				else
224 					putchar(' ');
225 		}
226 		putchar('\n');
227 	}
228 }
229