[net.sources.games] Looking for curses version of hangman

guy@rlgvax.UUCP (Guy Harris) (04/02/85)

> Does anyone have a version of /usr/games/hangman that draws the hangman on
> the screen?  Could this be called hang-o-matic?  If so, please post it to
> net.sources.games.

Yup, Berkeley does.  4.1BSD has the program, but no source; 4.2BSD has the
source.  I also did one once, which would be free of any Berkeley licensing
requirements but, alas, it was based on the Bell "hangman" so it's not free
of AT&T licensing requirements.

	Guy Harris
	sun!guy

arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (04/11/85)

#!/bin/sh
#
# In article <601@rlgvax.UUCP> guy@rlgvax.UUCP (Guy Harris) writes:
# >> Does anyone have a version of /usr/games/hangman that draws the hangman on
# >> the screen?  Could this be called hang-o-matic?  If so, please post it to
# >> net.sources.games.
# >Yup, Berkeley does.  4.1BSD has the program, but no source; 4.2BSD has the
# >source.  I also did one once, which would be free of any Berkeley licensing
# >requirements but, alas, it was based on the Bell "hangman" so it's not free
# >of AT&T licensing requirements.
# >	Guy Harris
#
# The version distributed with Berkeley was not based on Bell's, so it
# doesn't have any licensing requirements besides Berkeley's.  I wrote it,
# so I'm sure.
#
# (If I had the energy, I would get offended by the suggestion that I
# would need to look at someone else's code to figure out how to write
# a measly \hangman/ program.)
#
# In fact, here is the source, so that non-Berkeley sites
# can have it.  That is why there are comment chars at the beginning of
# these lines, because...
#
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	Makefile
#	endgame.c
#	extern.c
#	getguess.c
#	getword.c
#	hangman.h
#	main.c
#	playgame.c
#	prdata.c
#	prman.c
#	prword.c
#	setup.c
#	hangman.6
# This archive created: Thu Apr 11 12:03:33 1985
export PATH; PATH=/bin:$PATH
echo shar: extracting "'Makefile'" '(493 characters)'
if test -f 'Makefile'
then
	echo shar: over-writing existing file "'Makefile'"
fi
sed 's/^X//' << \SHAR_EOF > 'Makefile'
XOBJS=		endgame.o extern.o getguess.o getword.o main.o playgame.o \
X		prdata.o prman.o prword.o setup.o
XCFILES=		endgame.c extern.c getguess.c getword.c main.c playgame.c \
X		prdata.c prman.c prword.c setup.c
XHDRS=		hangman.h
XCFLAGS=		-O
XLDFLAGS=	-g
X
Xall: hangman
X
Xtags: $(HDRS) $(CFILES)
X	ctags $(HDRS) $(CFILES)
X
Xinstall: hangman
X	install -s hangman $(DESTDIR)/usr/games/hangman
X	
Xhangman: $(OBJS)
X	$(CC) $(LDFLAGS) -o hangman $(OBJS) -lcurses -ltermlib
X
Xclean:
X	rm -f $(OBJS) hangman ? core
SHAR_EOF
if test 493 -ne "`wc -c 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 493 characters)'
fi
echo shar: extracting "'endgame.c'" '(623 characters)'
if test -f 'endgame.c'
then
	echo shar: over-writing existing file "'endgame.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'endgame.c'
X# include	"hangman.h"
X
X/*
X * endgame:
X *	Do what's necessary at the end of the game
X */
Xendgame()
X{
X	register char	ch;
X
X	prman();
X	if (Errors >= MAXERRS)
X		Errors = MAXERRS + 2;
X	prword();
X	prdata();
X	move(MESGY, MESGX);
X	if (Errors > MAXERRS)
X		printw("Sorry, the word was \"%s\"\n", Word);
X	else
X		printw("You got it!\n");
X
X	for (;;) {
X		mvaddstr(MESGY + 1, MESGX, "Another word? ");
X		leaveok(stdscr, FALSE);
X		refresh();
X		if ((ch = readch()) == 'n')
X			die();
X		else if (ch == 'y')
X			break;
X		mvaddstr(MESGY + 2, MESGX, "Please type 'y' or 'n'");
X	}
X
X	leaveok(stdscr, TRUE);
X	move(MESGY, MESGX);
X	addstr("\n\n\n");
X}
SHAR_EOF
if test 623 -ne "`wc -c 'endgame.c'`"
then
	echo shar: error transmitting "'endgame.c'" '(should have been 623 characters)'
fi
echo shar: extracting "'extern.c'" '(494 characters)'
if test -f 'extern.c'
then
	echo shar: over-writing existing file "'extern.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'extern.c'
X# include	"hangman.h"
X
Xbool	Guessed[26];
X
Xchar	Word[BUFSIZ],
X	Known[BUFSIZ],
X	*Noose_pict[] = {
X		"     ______",
X		"     |    |",
X		"     |",
X		"     |",
X		"     |",
X		"     |",
X		"   __|_____",
X		"   |      |___",
X		"   |_________|",
X		NULL
X	};
X
Xint	Errors,
X	Wordnum = 0;
X
Xdouble	Average = 0.0;
X
XERR_POS	Err_pos[MAXERRS] = {
X	{  2, 10, 'O' },
X	{  3, 10, '|' },
X	{  4, 10, '|' },
X	{  5,  9, '/' },
X	{  3,  9, '/' },
X	{  3, 11, '\\' },
X	{  5, 11, '\\' }
X};
X
XFILE	*Dict = NULL;
X
Xoff_t	Dict_size;
SHAR_EOF
if test 494 -ne "`wc -c 'extern.c'`"
then
	echo shar: error transmitting "'extern.c'" '(should have been 494 characters)'
fi
echo shar: extracting "'getguess.c'" '(1090 characters)'
if test -f 'getguess.c'
then
	echo shar: over-writing existing file "'getguess.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'getguess.c'
X# include	"hangman.h"
X
X/*
X * getguess:
X *	Get another guess
X */
Xgetguess()
X{
X	register int	i;
X	register int	ch;
X	register bool	correct;
X
X	leaveok(stdscr, FALSE);
X	for (;;) {
X		move(PROMPTY, PROMPTX + sizeof "Guess: ");
X		refresh();
X		ch = readch();
X		if (isalpha(ch)) {
X			if (isupper(ch))
X				ch = tolower(ch);
X			if (Guessed[ch - 'a'])
X				mvprintw(MESGY, MESGX, "Already guessed '%c'", ch);
X			else
X				break;
X		}
X		else if (ch == CTRL(D))
X			die();
X		else
X			mvprintw(MESGY, MESGX, "Not a valid guess: '%s'",
X				unctrl(ch));
X	}
X	leaveok(stdscr, TRUE);
X	move(MESGY, MESGX);
X	clrtoeol();
X
X	Guessed[ch - 'a'] = TRUE;
X	correct = FALSE;
X	for (i = 0; Word[i] != '\0'; i++)
X		if (Word[i] == ch) {
X			Known[i] = ch;
X			correct = TRUE;
X		}
X	if (!correct)
X		Errors++;
X}
X
X/*
X * readch;
X *	Read a character from the input
X */
Xreadch()
X{
X	register int	cnt, r;
X	auto char	ch;
X
X	cnt = 0;
X	for (;;) {
X		if (read(0, &ch, sizeof ch) <= 0)
X		{
X			if (++cnt > 100)
X				die();
X		}
X		else if (ch == CTRL(L)) {
X			wrefresh(curscr);
X			mvcur(0, 0, curscr->_cury, curscr->_curx);
X		}
X		else
X			return ch;
X	}
X}
SHAR_EOF
if test 1090 -ne "`wc -c 'getguess.c'`"
then
	echo shar: error transmitting "'getguess.c'" '(should have been 1090 characters)'
fi
echo shar: extracting "'getword.c'" '(806 characters)'
if test -f 'getword.c'
then
	echo shar: over-writing existing file "'getword.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'getword.c'
X# include	"hangman.h"
X
X# if pdp11
X#	define	RN	(((off_t) rand() << 16) | (off_t) rand())
X# else
X#	define	RN	rand()
X# endif
X
X/*
X * getword:
X *	Get a valid word out of the dictionary file
X */
Xgetword()
X{
X	register FILE		*inf;
X	register char		*wp, *gp;
X
X	inf = Dict;
X	for (;;) {
X		fseek(inf, abs(RN % Dict_size), 0);
X		if (fgets(Word, BUFSIZ, inf) == NULL)
X			continue;
X		if (fgets(Word, BUFSIZ, inf) == NULL)
X			continue;
X		Word[strlen(Word) - 1] = '\0';
X		if (strlen(Word) < MINLEN)
X			continue;
X		for (wp = Word; *wp; wp++)
X			if (!islower(*wp))
X				goto cont;
X		break;
Xcont:		;
X	}
X	gp = Known;
X	wp = Word;
X	while (*wp) {
X		*gp++ = '-';
X		wp++;
X	}
X	*gp = '\0';
X}
X
X/*
X * abs:
X *	Return the absolute value of an integer
X */
Xoff_t
Xabs(i)
Xoff_t	i;
X{
X	if (i < 0)
X		return -(off_t) i;
X	else
X		return (off_t) i;
X}
SHAR_EOF
if test 806 -ne "`wc -c 'getword.c'`"
then
	echo shar: error transmitting "'getword.c'" '(should have been 806 characters)'
fi
echo shar: extracting "'hangman.h'" '(712 characters)'
if test -f 'hangman.h'
then
	echo shar: over-writing existing file "'hangman.h'"
fi
sed 's/^X//' << \SHAR_EOF > 'hangman.h'
X# include	<curses.h>
X# include	<sys/types.h>
X# include	<sys/stat.h>
X# include	<ctype.h>
X# include	<signal.h>
X
X# define	MINLEN	6
X# define	MAXERRS	7
X# define	DICT	"/usr/dict/words"
X
X# define	MESGY	12
X# define	MESGX	0
X# define	PROMPTY	11
X# define	PROMPTX	0
X# define	KNOWNY	10
X# define	KNOWNX	1
X# define	NUMBERY	4
X# define	NUMBERX	(COLS - 1 - 26)
X# define	AVGY	5
X# define	AVGX	(COLS - 1 - 26)
X# define	GUESSY	2
X# define	GUESSX	(COLS - 1 - 26)
X
X
Xtypedef struct {
X	short	y, x;
X	char	ch;
X} ERR_POS;
X
Xextern bool	Guessed[];
X
Xextern char	Word[], Known[], *Noose_pict[];
X
Xextern int	Errors, Wordnum;
X
Xextern double	Average;
X
Xextern ERR_POS	Err_pos[];
X
Xextern FILE	*Dict;
X
Xextern off_t	Dict_size;
X
Xint	die();
X
Xoff_t	abs();
SHAR_EOF
if test 712 -ne "`wc -c 'hangman.h'`"
then
	echo shar: error transmitting "'hangman.h'" '(should have been 712 characters)'
fi
echo shar: extracting "'main.c'" '(354 characters)'
if test -f 'main.c'
then
	echo shar: over-writing existing file "'main.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'main.c'
X# include	"hangman.h"
X
X/*
X * This game written by Ken Arnold.
X */
Xmain()
X{
X	initscr();
X	signal(SIGINT, die);
X	setup();
X	for (;;) {
X		Wordnum++;
X		playgame();
X		Average = (Average * (Wordnum - 1) + Errors) / Wordnum;
X	}
X	/* NOTREACHED */
X}
X
X/*
X * die:
X *	Die properly.
X */
Xdie()
X{
X	mvcur(0, COLS - 1, LINES - 1, 0);
X	endwin();
X	putchar('\n');
X	exit(0);
X}
SHAR_EOF
if test 354 -ne "`wc -c 'main.c'`"
then
	echo shar: error transmitting "'main.c'" '(should have been 354 characters)'
fi
echo shar: extracting "'playgame.c'" '(299 characters)'
if test -f 'playgame.c'
then
	echo shar: over-writing existing file "'playgame.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'playgame.c'
X# include	"hangman.h"
X
X/*
X * playgame:
X *	play a game
X */
Xplaygame()
X{
X	register bool	*bp;
X
X	getword();
X	Errors = 0;
X	bp = Guessed;
X	while (bp < &Guessed[26])
X		*bp++ = FALSE;
X	while (Errors < MAXERRS && index(Known, '-') != NULL) {
X		prword();
X		prdata();
X		prman();
X		getguess();
X	}
X	endgame();
X}
SHAR_EOF
if test 299 -ne "`wc -c 'playgame.c'`"
then
	echo shar: error transmitting "'playgame.c'" '(should have been 299 characters)'
fi
echo shar: extracting "'prdata.c'" '(520 characters)'
if test -f 'prdata.c'
then
	echo shar: over-writing existing file "'prdata.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'prdata.c'
X# include	"hangman.h"
X
X/*
X * prdata:
X *	Print out the current guesses
X */
Xprdata()
X{
X	register bool	*bp;
X
X	move(GUESSY, GUESSX + sizeof "Guessed: ");
X	bp = Guessed;
X	while (bp < &Guessed[26])
X		if (*bp++)
X			addch((bp - Guessed) + 'a' - 1);
X	clrtoeol();
X	mvprintw(NUMBERY, NUMBERX + sizeof "Word #:          ", "%d", Wordnum);
X	mvprintw(AVGY, AVGX + sizeof       "Current Average: ", "%.3f",
X				(Average * (Wordnum - 1) + Errors) / Wordnum);
X	mvprintw(AVGY + 1, AVGX + sizeof   "Overall Average: ", "%.3f", Average);
X}
SHAR_EOF
if test 520 -ne "`wc -c 'prdata.c'`"
then
	echo shar: error transmitting "'prdata.c'" '(should have been 520 characters)'
fi
echo shar: extracting "'prman.c'" '(311 characters)'
if test -f 'prman.c'
then
	echo shar: over-writing existing file "'prman.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'prman.c'
X# include	"hangman.h"
X
X/*
X * prman:
X *	Print out the man appropriately for the give number
X *	of incorrect guesses.
X */
Xprman()
X{
X	register int	i;
X
X	for (i = 0; i < Errors; i++)
X		mvaddch(Err_pos[i].y, Err_pos[i].x, Err_pos[i].ch);
X	while (i < MAXERRS) {
X		mvaddch(Err_pos[i].y, Err_pos[i].x, ' ');
X		i++;
X	}
X}
SHAR_EOF
if test 311 -ne "`wc -c 'prman.c'`"
then
	echo shar: error transmitting "'prman.c'" '(should have been 311 characters)'
fi
echo shar: extracting "'prword.c'" '(167 characters)'
if test -f 'prword.c'
then
	echo shar: over-writing existing file "'prword.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'prword.c'
X# include	"hangman.h"
X
X/*
X * prword:
X *	Print out the current state of the word
X */
Xprword()
X{
X	move(KNOWNY, KNOWNX + sizeof "Word: ");
X	addstr(Known);
X	clrtoeol();
X}
SHAR_EOF
if test 167 -ne "`wc -c 'prword.c'`"
then
	echo shar: error transmitting "'prword.c'" '(should have been 167 characters)'
fi
echo shar: extracting "'setup.c'" '(669 characters)'
if test -f 'setup.c'
then
	echo shar: over-writing existing file "'setup.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'setup.c'
X# include	"hangman.h"
X
X/*
X * setup:
X *	Set up the strings on the screen.
X */
Xsetup()
X{
X	register char		**sp;
X	static struct stat	sbuf;
X
X	noecho();
X	crmode();
X
X	mvaddstr(PROMPTY, PROMPTX, "Guess:");
X	mvaddstr(GUESSY, GUESSX, "Guessed:");
X	mvaddstr(NUMBERY, NUMBERX, "Word #:");
X	mvaddstr(AVGY, AVGX, "Current Average:");
X	mvaddstr(AVGY + 1, AVGX, "Overall Average:");
X	mvaddstr(KNOWNY, KNOWNX, "Word: ");
X
X	for (sp = Noose_pict; *sp != NULL; sp++) {
X		move(sp - Noose_pict, 0);
X		addstr(*sp);
X	}
X
X	srand(time(NULL) + getpid());
X	if ((Dict = fopen(DICT, "r")) == NULL) {
X		perror(DICT);
X		endwin();
X		exit(1);
X	}
X	fstat(fileno(Dict), &sbuf);
X	Dict_size = sbuf.st_size;
X}
SHAR_EOF
if test 669 -ne "`wc -c 'setup.c'`"
then
	echo shar: error transmitting "'setup.c'" '(should have been 669 characters)'
fi
echo shar: extracting "'hangman.6'" '(451 characters)'
if test -f 'hangman.6'
then
	echo shar: over-writing existing file "'hangman.6'"
fi
sed 's/^X//' << \SHAR_EOF > 'hangman.6'
X.TH HANGMAN 6 "1 February 1983"
X.UC 4
X.SH NAME
Xhangman \- Computer version of the game hangman
X.SH SYNOPSIS
X.B /usr/games/hangman
X.SH DESCRIPTION
XIn
X.I hangman,
Xthe computer picks a word from the on-line word list
Xand you must try to guess it.
XThe computer keeps track of which letters have been guessed
Xand how many wrong guesses you have made on the screen in a graphic fashion.
X.SH FILES
X/usr/dict/words     On-line word list
X.SH AUTHOR
XKen Arnold
SHAR_EOF
if test 451 -ne "`wc -c 'hangman.6'`"
then
	echo shar: error transmitting "'hangman.6'" '(should have been 451 characters)'
fi
#	End of shell archive
exit 0