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