DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T d

⟦7a1d1d58b⟧ TextFile

    Length: 6642 (0x19f2)
    Types: TextFile
    Names: »dict.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Scrabble/dict.c« 

TextFile


/* RCS Info: $Revision: 1.2 $ on $Date: 89/03/15 11:16:27 $
 *           $Source: /yew3/faustus/src/scrabble/RCS/dict.c,v $
 * Copyright (c) 1989 Wayne A. Christopher, U. C. Berkeley CS Dept
 *	 faustus@renoir.berkeley.edu, ucbvax!faustus
 * Permission is granted to modify and re-distribute this code in any manner
 * as long as this notice is preserved.  All standard disclaimers apply.
 *
 */

#ifdef MSDOS
typedef char bool;
#endif
#include "scrabble.h"

#ifdef _STDC_
static int dicthash(char *word, int tabsize);
static void getem(word_t **wordp, char *lbuf, int place, char *opt,
		int numopt, int len);
#else
static int dicthash();
static void getem();
#endif

#ifdef MSDOS
static dict_t far *dictionary;
#else
static dict_t *dictionary;
#endif

#ifdef _STDC_
void
readdict(char *file)
#else
void
readdict(file)
char *file;
#endif
{
	FILE *fp;
	char buf[BSIZE], *e;
	word_t *ww;
	int i, j, k, n, t;

	if (!(fp = fopen(file, "r"))) {
		perror(file);
		exit(0);
	}
	fprintf(stderr, "Reading \"%s\" ", file);
	fflush(stderr);

#ifdef MSDOS
	dictionary = (dict_t far *) util_farmalloc(sizeof (dict_t));
#else	
	dictionary = (dict_t *) util_malloc(sizeof (dict_t));
#endif	
	for (i = 0; i < MAX_LENGTH; i++)
		for (j = 0; j < HASH_SIZE; j++)
			dictionary->buckets[i][j] = NULL;
	dictionary->size = 0;

	while (fgets(buf, BSIZE, fp)) {
		if (isupper(buf[0]) || !buf[2])
			continue;

		for (e = buf; *e; e++)
			;
		*--e = '\0';
		addword(buf);

#ifdef notdef
		/* Add the plural... */
		s = e - 1;
		if (index("sxz", *s)) {
			*++s = 'e';
			*++s = 's';
			*++s = '\0';
		} else {
			*++s = 's';
			*++s = '\0';
		}
		addword(buf);
		*e = '\0';
#endif
	}

	fprintf(stderr, " %d words.\n", dictionary->size);

	if (debug) {
		fprintf(stderr, "Stats:\n");
		for (i = 0; i < MAX_LENGTH; i++) {
			fprintf(stderr, "\t%d:", i + 1);
			n = t = 0;
			for (j = 0; j < HASH_SIZE; j++) {
				for (ww = dictionary->buckets[i][j], k = 0; ww;
						ww = ww->next)
					k++;
				/* fprintf(stderr, " %d", k); */
				if (k)
					n++;
				t += k;
			}
			fprintf(stderr, " %d / %d full, %d total\n",
					n, HASH_SIZE, t);
		}
	}

	fclose(fp);

	return;
}

#ifdef _STDC_
void
writedict(char *file)
#else
void
writedict(file)
char *file;
#endif
{
	int i, j, k = 0;
	word_t *word;
	FILE *fp;
	char buf[BSIZE];

	if (!(fp = fopen(file, "w"))) {
		perror(file);
		return;
	}

	for (i = 0; i < MAX_LENGTH; i++)
		for (j = 0; j < HASH_SIZE; j++)
			for (word = dictionary->buckets[i][j]; word;
					word = word->next) {
				fprintf(fp, "%s\n", word->word);
				k++;
			}

	fclose(fp);

	sprintf(buf, "Wrote %d words to %s.", k, file);
	user_message(buf);

	return;
}

#ifdef _STDC_
void
addword(char *word)
#else
void
addword(word)
char *word;
#endif
{
	int key = dicthash(word, HASH_SIZE);
	int len = strlen(word);
	word_t *ww;

	if ((key == -1) || (len > SIZE))
		return;

	ww = (word_t *) util_malloc(sizeof (word_t));

	ww->word = strsav(word);
	ww->length = len;
	ww->next = dictionary->buckets[len - 1][key];
	dictionary->buckets[len - 1][key] = ww;

	dictionary->size++;

	if (dictionary->size % 1000 == 0) {
		fprintf(stderr, ".");
		fflush(stderr);
	}

	return;
}

#ifdef _STDC_
void
remword(char *word)
#else
void
remword(word)
char *word;
#endif
{
	int key = dicthash(word, HASH_SIZE);
	int len = strlen(word);
	word_t *ww, *lw = NULL;

	for (ww = dictionary->buckets[len - 1][key]; ww; ww = ww->next) {
		if (eq(ww->word, word))
			break;
		lw = ww;
	}

	assert(ww);

	if (lw)
		lw->next = ww->next;
	else
		dictionary->buckets[len - 1][key] = ww->next;

	dictionary->size--;

	return;
}

#ifdef _STDC_
bool
isaword(char *poss)
#else
bool
isaword(poss)
char *poss;
#endif
{
	word_t *word;
	int len = strlen(poss);
	int key = dicthash(poss, HASH_SIZE);

	if (key == -1)
		return (false);

	for (word = dictionary->buckets[len - 1][key]; word; word = word->next)
		if (eq(word->word, poss))
			return (true);
	
	return (false);
}

/* Return a list of the buckets containing all the words we could make with
 * the given letters and are of the given length.  Look at all the combinations 
 * that include all the required ones and enough optional ones to make
 * up the length.
 */

#ifdef _STDC_
word_t *
getpossibles(char *opt, int numopt, char *req, int numreq, int len)
#else
word_t *
getpossibles(opt, numopt, req, numreq, len)
char *opt;
int numopt;
char *req;
int numreq;
int len;
#endif
{
	char lbuf[SIZE];
	int i;
	word_t *word = NULL;
	int wc1 = -1, wc2 = -1;

	for (i = 0; i < numreq; i++)
		lbuf[i] = req[i];

	if (numreq + numopt < len)
		return (NULL);
	
	for (i = 0; i < numopt; i++)
		if (opt[i] == WILD) {
			if (wc1 == -1)
				wc1 = i;
			else
				wc2 = i;
		}

	if (wc1 > -1) {
		for (opt[wc1] = 'a'; opt[wc1] <= 'z'; opt[wc1]++) {
			if (wc2 > -1) {
				for (opt[wc2] = 'a'; opt[wc2] <= 'z';
						opt[wc2]++)
					getem(&word, lbuf, numreq, opt, numopt,
							len);
				opt[wc2] = WILD;
			} else
				getem(&word, lbuf, numreq, opt, numopt, len);
		}
		opt[wc1] = WILD;
	} else
		getem(&word, lbuf, numreq, opt, numopt, len);

	return (word);
}

#ifdef _STDC_
static void
getem(word_t **wordp, char *lbuf, int place, char *opt, int numopt, int len)
#else
static void
getem(wordp, lbuf, place, opt, numopt, len)
word_t **wordp;
char *lbuf;
int place;
char *opt;
int numopt;
int len;
#endif
{
	int key;
	word_t *set, *ww;

assert(numopt >= 0);

	if ((numopt == len - place) || (place == len)) {
		while (place < len)
			lbuf[place++] = *opt++;
		lbuf[len] = '\0';
		key = dicthash(lbuf, HASH_SIZE);
		set = dictionary->buckets[len - 1][key];
		if (set) {
			for (ww = *wordp; ww; ww = ww->next_set)
				if (ww == set)
					break;
			if (ww)
				return;

			set->next_set = *wordp;
			*wordp = set;
#ifdef notdef
			if (debug) {
				fprintf(stderr, "\t\t");
				for (ww = set; ww; ww = ww->next)
					fprintf(stderr, " %s", ww->word);
				fprintf(stderr, "\n");
			}
#endif
		}
	} else {
		lbuf[place] = *opt;
		getem(wordp, lbuf, place + 1, opt + 1, numopt - 1, len);
		getem(wordp, lbuf, place, opt + 1, numopt - 1, len);
	}

	return;
}

#define NLETTERS	28	/* So it's a multiple of 4. */

/* A return value of -1 denotes that this is a bad word. */

#ifdef _STDC_
static int
dicthash(char *word, int tabsize)
#else
static int
dicthash(word, tabsize)
char *word;
int tabsize;
#endif
{
	int i;
	unsigned long result = 0;
	unsigned long letters[NLETTERS];
	char *s;

	for (i = 0; i < NLETTERS; i++)
		letters[i] = 0;

	for (s = word; *s; s++) {
		if (!isalpha(*s))
			return (-1);
		letters[isupper(*s) ? (*s - 'A') : (*s - 'a')]++;
	}

	for (i = 0; i < NLETTERS; i++)
		result ^= letters[i] << i;
	
	return (result % tabsize);
}