⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boggle.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
字号:
#ifndef lintstatic char sccsid[] = "@(#)boggle.c	4.1 12/24/82";#endif#include <ctype.h>#include <errno.h>#include <setjmp.h>#include <sgtty.h>#include <signal.h>#include <stdio.h>/* basic parameters */#define N 4#define SSIZE 200#define MAXWORDS 1000#define CWIDTH 10#define LWIDTH 80/* parameters defined in terms of above */#define BSIZE (N*N)#define row(x) (x/N)#define col(x) (x%N)/* word being searched for */int wlength;int numsame;char wbuff [BSIZE+1];/* tty and process control */extern int errno;int status;int pipefd[2];int super = 0;int delct = 1;int zero = 0;int master = 1;int column;int *timept;int timeint[] = {60,60,50,7,1,1,1,0};long timein;extern long int time();struct sgttyb origttyb, tempttyb;int ctlecho = 0;int lctlech = LCTLECH;jmp_buf env;/* monitoring variables */int games;int logfile = -1;long logloc;char logbuff[100] = {"inst\t"};extern char *ctime(), *getlogin();extern long lseek();/* dictionary interface */char defname[] = "/usr/games/bogdict";char *dictname = &defname[0];FILE *dict;/* structures for doing matching */struct frame {	struct frame *parent;	int place;};struct frame stack [SSIZE];struct frame *level [BSIZE+1];/* the board and subsidiary structures */char present [BSIZE+1];char board [BSIZE];char olink [BSIZE];char adj [BSIZE+1][BSIZE];char occurs [26];/* the boggle cubes */char *cube [BSIZE] = {	"forixb", "moqabj", "gurilw", "setupl",	"cmpdae", "acitao", "slcrae", "romash",	"nodesw", "hefiye", "onudtk", "tevign",	"anedvz", "pinesh", "abilyt", "gkyleu"};/* storage for words found */int ubotch, ustart, wcount;char *word [MAXWORDS];char *freesp;char space[10000];endline (){	if (column != 0) {		putchar('\n');		column = 0;	}}timeout (){	if (*timept > 0) {		signal (SIGALRM, timeout);		alarm(*timept++);	}	putchar('\007');}interrupt (){	signal(SIGINT, interrupt);	if (delct++ >= 1)		longjmp(env, 1);	timept = &zero;}goodbye (stat)int stat;{	if (master != 0) {		wait(&status);		if ( ctlecho & LCTLECH ) {			ioctl( fileno(stdin), TIOCLBIS, &lctlech );		}		stty(fileno(stdin), &origttyb);	}	exit(stat);}clearscreen (){	stty (fileno(stdin), &tempttyb);	printf("\n\033\f\r");}compare (a, b)char **a, **b;{	return(wordcomp(*a, *b));}wordcomp (p, q)register char *p, *q;{	if (*p=='0' && *q!='0')		return(-1);	if (*p!='0' && *q=='0')		return(1);	while (*++p == *++q && isalpha(*p)) ;	if (!isalpha(*p))		return(-isalpha(*q));	if (!isalpha(*q))		return(1);	return(*p-*q);}printinst (){	stty (fileno(stdin), &tempttyb);	printf("instructions?");	if (getchar() == 'y') {		clearscreen();		printf("     The object of Boggle (TM  Parker  Bros.)  is  to  find,  within  3\n");		printf("minutes,  as many words as possible in a 4 by 4 grid of letters.  Words\n");		printf("may be formed from any sequence of 3 or more adjacent  letters  in  the\n");		printf("grid.   The  letters  may join horizontally, vertically, or diagonally.\n");		printf("However, no position in the grid may be used more than once within  any\n");		printf("one  word.   In  competitive  play amongst humans, each player is given\n");		printf("credit for those of his words which no other player has found.\n");		printf("     This program is intended  for  people  wishing  to  sharpen  their\n");		printf("skills  at  Boggle.   If  you  invoke the program with 4 arguments of 4\n");		printf("letters each, (e.g. \"boggle appl epie moth erhd\") the program forms the\n");		printf("obvious  Boggle grid and lists all the words from /usr/dict/words found\n");		printf("therein.  If you invoke the program without arguments, it will generate\n");		printf("a  board  for you, let you enter words for 3 minutes, and then tell you\n");		printf("how well you did relative to /usr/dict/words.\n");		printf("     In interactive play, enter your words separated by  spaces,  tabs,\n");		printf("or  newlines.   A  bell will ring when there is 2:00, 1:00, 0:10, 0:02,\n");		printf("0:01, and 0:00 time left.  You may complete any word started before the\n");		printf("expiration  of  time.   You  can surrender before time is up by hitting\n");		printf("'break'.  While entering words, your erase character is only  effective\n");		printf("within the current word and your line kill character is ignored.\n");		printf("     Advanced players may wish to invoke the program with 1 or 2 +'s as\n");		printf("the  first argument.  The first + removes the restriction that postions\n");		printf("can only be used once in each word.  The second + causes a position  to\n");		printf("be  considered  adjacent  to itself as well as its (up to) 8 neighbors.\n");		printf("Hit any key to begin.\n");		stty (fileno(stdin), &tempttyb);		getchar();	}	stty (fileno(stdin), &tempttyb);}setup (){	register int i, j;	int rd, cd, k;	for (i=0; i<BSIZE; i++) {		adj[i][i] = super>=2 ? 1 : 0;		adj[BSIZE][i] = 1;		for (j=0; j<i; j++) {			rd = row(i)-row(j);			cd = col(i)-col(j);			k = 0;			switch (rd) {			case -1:			case 1:				if (-1<=cd && cd<=1)					k = 1;				break;			case 0:				if (cd==-1 || cd==1)					k = 1;				break;			}			adj[i][j] = adj[j][i] = k;		}	}	stack[0].parent = &stack[0];	stack[0].place = BSIZE;	level[0] = &stack[0];	level[1] = &stack[1];}makelists (){	register int i, c;	for (i=0; i<26; i++)		occurs[i] = BSIZE;	for (i=0; i<BSIZE; i++) {		c = board[i];		olink[i] = occurs[c-'a'];		occurs[c-'a'] = i;	}}genboard (){	register int i, j;	for (i=0; i<BSIZE; i++)		board[i] = 0;	for (i=0; i<BSIZE; i++) {		j = rand()%BSIZE;		while (board[j] != 0)			j = (j+1)%BSIZE;		board[j] = cube[i][rand()%6];	}}printboard (){	register int i, j;	for (i=0; i<N; i++) {		printf("\t\t\t\t\b\b");		for (j=0; j<N; j++) {			putchar ((putchar(board[i*N+j]) == 'q') ? 'u' : ' ');			putchar(' ');		}		putchar('\n');	}	putchar('\n');}getdword (){	/* input:  numsame = # chars same as last word   */	/* output: numsame = # same chars for next word  */	/*        word in wbuff[0]...wbuff[wlength-1]    */	register int c;	register char *p;	if (numsame == EOF)		return (0);	p = &wbuff[numsame]+1;	while ((*p++ = c = getc(dict)) != EOF && isalpha(c)) ;	numsame = c;	wlength = p - &wbuff[2];	return (1);}getuword (){	int c;	register char *p, *q, *r;	numsame = 0;	while (*timept>0 && (isspace(c=getchar()) || c==EOF));	if (*timept == 0)		return(0);	word[wcount++] = freesp;	*freesp++ = '0';	r = &wbuff[1];	q = p = freesp;	*p++ = c;	while (!isspace(c = getchar())) {		if (c == EOF)			continue;		if (c == origttyb.sg_erase) {			if (p > q)				p--;			continue;		}		*p++ = c;	}	freesp = p;	for (p=q; p<freesp && r<&wbuff[BSIZE]; )		if (islower(c = *p++) && (*r++ = *q++ = c) == 'q' && *p == 'u')			p++;	*(freesp = q) = '0';	wlength = r-&wbuff[1];	return(1);}aputuword (ways)int ways;{	*word[wcount-1] = ways>=10 ? '*' : '0'+ways;}aputword (ways)int ways;{	/* store (wbuff, ways) in next slot in space */	register int i;	*freesp++ = ways>=10 ? '*' : '0'+ways;	for (i=1; i<= wlength; i++)		*freesp++ = wbuff[i];	word[++wcount] = freesp;}tputword (ways)int ways;{	/* print (wbuff, ways) on terminal */	wbuff[wlength+1] = '0';	wbuff[0] = ways>=10 ? '*' : '0'+ways;	outword(&wbuff[0]);}outword (p)register char *p;{	register int newcol;	register char *q;	for (q=p+1; isalpha(*q); ) {		putchar(*q);		if (*q++ == 'q') {			putchar('u');			column++;		}	}	column += q-p-1;	if (column > LWIDTH-CWIDTH) {		putchar('\n');		column = 0;		return;	}	newcol = ((column+CWIDTH)/CWIDTH)*CWIDTH;	while (((column+8)/8)*8 <= newcol) {		putchar('\t');		column = ((column+8)/8)*8;	}	while (column < newcol) {		putchar(' ');		column++;	}}printdiff (){	register int c, d, u;	char both, donly, uonly;	word[wcount] = freesp;	*freesp = '0';	both = donly = uonly = column = d = 0;	u = ustart;	while (d < ubotch) {		c = u<wcount ? wordcomp (word[d], word[u]) : -1;		if (c == 0) {			/* dict and user found same word */			if (both == 0) {				both = 1;				printf("\t\t\t   we both found:\n");			}			outword(word[d]);			word[d++] = NULL;			word[u++] = NULL;		} else if (c < 0) {			/* dict found it, user didn't */			donly = 1;			d++;		} else {			/* user found it, dict didn't */			uonly = 1;			u++;		}	}	endline();	if (donly) {		printf("\n\t\t\tI alone found these:\n");		for (d=0; d<ubotch; d++)			if (word[d] != NULL)				outword(word[d]);		endline();	}	if (uonly) {		printf("\n\t\t\tyou alone found these:\n");		for (u=ustart; u<wcount; u++)			if (word[u] != NULL)				outword(word[u]);		endline();	}	if (ubotch < ustart) {		printf("\n\t\t\t  you botched these:\n");		for (u=ubotch; u<ustart; u++)			outword(word[u]);		endline();	}}numways (leaf, last)register struct frame *leaf;struct frame *last;{	int count;	register char *p;	register struct frame *node;	if (super > 0)		return(last-leaf);	count = 0;	present[BSIZE] = 1;	while (leaf < last) {		for (p = &present[0]; p < &present[BSIZE]; *p++ = 0);		for (node = leaf; present[node->place]++ == 0; node = node->parent);		if (node == &stack[0])			count++;		leaf++;	}	return(count);}evalboard (getword, putword)int (*getword)(), (*putword)();{	register struct frame *top;	register int l, q;	int fo, found;	struct frame *parent, *lastparent;	char *padj;	numsame = found = 0;	makelists ();	while (1) {		l = numsame;		if (!(*getword) ())			break;		top = level[l+1];			while (1) {			level[l+1] = lastparent = top;			/* wbuff[1]...wbuff[l] have been matched */			/* level[0],...,level[l] of tree built */			if (l == wlength) {				if (wlength >= 3 && (q = numways(level[l], top)) != 0) {					(*putword) (q);					found++;				}				l = BSIZE+1;				break;			}			if ((fo = occurs[wbuff[++l]-'a']) == BSIZE)				break;			/* wbuff[1]...wbuff[l-1] have been matched */			/* level[0],...,level[l-1] of tree built */			for (parent=level[l-1]; parent<lastparent; parent++) {				padj = &adj[parent->place][0];				for (q=fo; q!=BSIZE; q=olink[q])					if (padj[q]) {						top->parent = parent;						top->place = q;						if (++top >= &stack[SSIZE]) {							printf("stack overflow\n");							goodbye(1);						}					}			}			/* were any nodes added? */			if (top == lastparent)				break;		}		/* advance until first l characters of next word are different */		while (numsame >= l && (*getword)()) ;	}	return(found);}main (argc, argv)int argc;char **argv;{	char *q;	register char *p;	register int i, c;	gtty (fileno(stdin), &origttyb);	setbuf(stdin, NULL);	tempttyb = origttyb;	if (setjmp(env) != 0)		goodbye(0);	signal (SIGINT, interrupt);	timein = time(0L);	if (argv[0][0] != 'a' && (logfile = open("/usr/games/boglog", 1)) >= 0) {		p = &logbuff[5];		q = getlogin();		while (*p++ = *q++);		p[-1] = '\t';		q = ctime(&timein);		while (*p++ = *q++);		logloc = lseek(logfile, 0L, 2);		write(logfile, &logbuff[0], p-&logbuff[1]);	}	if ((dict = fopen(dictname, "r")) == NULL) {		printf("can't open %s\n", dictname);		goodbye (2);	}	while ( argc > 1 && ( argv[1][0] == '+' || argv[1][0] == '-' ) ) {		if (argv[1][0]=='+') {			while(*(argv[1]++) == '+')				super++;			argc--;			argv++;		}		if ( argv[1][0] == '-' ) {			timeint[0] = 60 * ( atol( &argv[1][1] ) - 2 );			if ( timeint[0] <= 0 ) {				timeint[0] = 60;			}			argc--;			argv++;		}	}	setup ();	switch (argc) {	default:  punt:		printf("usage: boggle [+[+]] [row1 row2 row3 row4]\n");		goodbye (3);	case 5:		for (i=0; i<BSIZE; i++) {			board[i] = c = argv[row(i)+1][col(i)];			if (!islower(c)) {				printf("bad board\n");				goto punt;			}		}		printboard();		column = 0;		evalboard(getdword, tputword);		endline();		if (logfile >= 0) {			strncpy(&logbuff[0], "eval", 4);			lseek(logfile, logloc, 0);			write(logfile, &logbuff[0], 4);		}		goodbye(0);	case 1:		tempttyb.sg_flags |= CBREAK;		if ( ioctl( fileno(stdin), TIOCLGET, &ctlecho ) == 0 ) {			if ( ctlecho & LCTLECH ) {				ioctl( fileno(stdin), TIOCLBIC, &lctlech );			}		}		printinst();		srand((int) timein);		while (setjmp(env) == 0) {			errno = 0;			if (pipe(&pipefd[0]) != 0) {				printf("can't create pipe\n");				goodbye(4);			}			genboard();			delct = wcount = 0;			word[0] = freesp = &space[0];			if ((master = fork()) == 0) {				close(pipefd[0]);				clearscreen();				printboard();				signal(SIGALRM, timeout);				timept = &timeint[0];				alarm(*timept++);				evalboard(getuword, aputuword);				clearscreen();				qsort(&word[0], wcount, sizeof (int), compare);				for (i=0; i<wcount; i++)					if (i==0 || wordcomp(word[i], word[i-1])!=0) {						p = word[i];						while (isalpha(*++p)) ;						write (pipefd[1], word[i], p-word[i]);					}				close(pipefd[1]);				goodbye(0);			}			close(pipefd[1]);			rewind(dict);			getc(dict);			evalboard(getdword, aputword);			p = freesp;			while ((i = read(pipefd[0], freesp, 512)) != 0) {				if (i < 0)					if (errno != EINTR)						break;					else						i = 0;				freesp += i;			}			close(pipefd[0]);			ustart = ubotch = wcount;			while (p < freesp) {				word[wcount++] = p;				if (*p == '0')					ustart = wcount;				while (isalpha(*++p));			}			wait(&status);			if (status != 0)				goodbye (5);			delct = 1;			printdiff();			printboard();			games++;			if (logfile >= 0) {				sprintf(&logbuff[0], "%4d", games);				lseek(logfile, logloc, 0);				write(logfile, &logbuff[0], 4);			}			stty (fileno(stdin), &tempttyb);			printf("\nanother game?");			if (getchar() != 'y') {				putchar('\n');				break;			}			stty (fileno(stdin), &tempttyb);		}		goodbye(0);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -