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