[net.sources.games] Cheery Hangman game...

dat@hpcnof.UUCP (12/31/85)

	Attached is a set of files that implement a rather macabre
version of hangman (all you sickie netters should like it :-) including
my own cursor control library.  If anyone gets really motivated, I 
imagine that translating it into Berkeley Curses (which I didn't have)
and reposting it would be quite appreciated.

	DON'T CHEAT AND LOOK AT THE .hang-words FILE TO SEE WHAT THE
WORDS ARE!!!

	Have fun with this, and all messages from the ACLU or whomever
else complains about violent computer games should be routed to /dev/null!

					-- Dave Taylor
					Hewlett-Packard (CNO)

					ihnp4!hpfcla!d_taylor

------- cut here and so on --------

# Shar file generated Tuesday, December 31st 1985 at 9:37 am by dat
# Extract with either sh or csh
#
# Contents of shar file:
#   README hangman.c hangman.6 curses.c curses.h addword.6 addword.c .hang-words
#
# --------------  File README ---------------
echo extracting file README
cat << 'END_OF_FILE' > README

	To create the hangman game and use it you need merely to unpack
all the files (presumably you've already done this!) then

$ cc -c -O curses.c
$ cc -O addword.c -o addword
$ cc -O hangman.c curses.o -o hangman -ltermcap

then install it with:

$ cp addword /usr/games/addword
$ chown games /usr/games/addword
$ chmod 4755 /usr/games/addword

$ cp .hang-words /usr/games/lib/.hang-words
$ chown games /usr/games/lib/.hang-words
$ chmod 744 /usr/games/lib/.hang-words

$ cp hangman /usr/games/hangman
$ chown games /usr/games/hangman

$ cp hangman.6 /usr/man/man6
$ cp addword.6 /usr/man/man6

and you should be ready to roll!!! (or hang, as the case may be)

**** Any problems encountered, bugs fixed, or great words added should
     be reported to the author (please) at either of the addresses:

	ihnp4!hpfcla!d_taylor
	hpcnof!dat@HPLABS
	hplabs!hpcnof!dat

     Thanks and good luck!

					-- Dave Taylor

END_OF_FILE
# --------------  File hangman.c ---------------
echo extracting file hangman.c
cat << 'END_OF_FILE' > hangman.c
/**             hangman.c               **/

/**  Plays the game of hangman!         **/

/** (C) 1985 Dave Taylor: ihnp4!hpfcla!d_taylor -or- hplabs!hpcnof!dat **/

#include <stdio.h>
#include <signal.h>
#include "curses.h"

#define word_file       "/usr/games/lib/.hang-words"
#define MAX_CHARS       25
#define MAX_GUESSES     10

#define GUESSED_IT      0
#define TRIED_GUESS     1
#define GOOD_GUESS      2
#define BAD_GUESS       3

#define delay(n)	{register int i; for (i=0;i<n;i++); }

char  word[MAX_CHARS];
char  guessed[26], part_word[MAX_CHARS];
int   bad_guesses, words_gotten = 0, words_tried = 0;
int   debug = 0;

main(argc)
int argc;
{
        char ch;
        int  leave();

	debug = (argc>1);

        switch(InitScreen()) {
          case -1 : exit(printf("Unknown terminal\n"));
          case -2 : exit(printf("Not Cursor Addressable\n"));
          default : break;
        }
        
	if (debug) printf("initscreen succeeded\n");

        signal(SIGINT, leave);
        signal(SIGQUIT,leave);
        
        do {
          initialize(word);
        
          ClearScreen();
          build_gallows();
          show_word(part_word);
          show_guessed();
          if (words_tried)
            PutLine(9,50,"Success: %2d%%",
            (int) ((float) 100*((float) words_gotten/(float) words_tried)));
  
          while (bad_guesses < MAX_GUESSES && not_guessed()) {
            switch (guess(&ch)) {
              case BAD_GUESS  : show_gallows(++bad_guesses);
                                add_to_guessed(ch);
                                show_guessed();
                                break;
              case GOOD_GUESS : add_to_guessed(ch);
                                show_guessed();
                                fill_in(ch);
                                show_word(part_word);
                                break;
              case GUESSED_IT : show_word(word);
                                strcpy(part_word,word);
                                break;
              case TRIED_GUESS: break;    /** no penalty **/
              default         : PutLine(22,0,"Huh?");
            }
          }

        if (bad_guesses < MAX_GUESSES) 
          words_gotten++;
        else 
          PutLine(19,0,"The word you were trying to guess was '%s'",word);
 
        words_tried++;

        PutLine(17,0,"Would you like to try another word? (y/n) ");
      } while (tolower(ReadACh()) != 'n');

      PutLine(19,0,"Your final success rate was %d%%",
      (int) ((float) 100*((float) words_gotten/(float) words_tried)));
      CleartoEOLN();
      
      leave();
}

int
ReadACh()
{
	char ch;

	Raw(ON);
	ch = ReadCh();
	Raw(OFF);
	return(ch);
}

initialize(word)
char *word;
{
        /** pick word, and initialize all variables! **/

        int max_words, get_word;
        register int i;
        FILE *wordfile;

	if (debug) printf("initialize()\n");
        srand(time(0));
        if ((wordfile = fopen(word_file, "r")) == NULL)
          leave(printf("Cannot open wordfile %s!\n", word_file));

        fgets(word,MAX_CHARS, wordfile);
        sscanf(word, "%d", &max_words);

        get_word = rand() % max_words + 1;

        while (get_word-- > 0)
          fgets(word,MAX_CHARS, wordfile);
        
        word[strlen(word)-1] = '\0';    /** remove the '\n' **/

        fclose(wordfile);

        for (i= 0; i < 26; i++)
          guessed[i] = 0;

        bad_guesses = 0;

        for (i = 0; i < strlen(word); i++)
          part_word[i] = '_';
        part_word[i] = '\0';

}

int
not_guessed()
{
        /** returns non-zero iff there are any underlines in the
            variable part_word (ie the word isn't fully guessed yet!) **/

        register int i;

        while (i < strlen(part_word) && part_word[i] != '_')
            i++;

        return(i != strlen(part_word));
}

int
guess(ch)
char *ch;
{
        /**     Guess a letter.  If RETURN is keyed in, try to
                guess the entire word.  There is NO penalty for
                attempting to guess the word.   Returns either
                GOOD_GUESS, BAD_GUESS, GUESSED_IT or TRIED_GUESS **/

        char guessed_word[MAX_CHARS];
        register int i;

	if (debug) printf("guess()\n");
        MoveCursor(21,0); CleartoEOLN();

        PutLine(17,0,"Guess a character: ");
        CleartoEOLN();
        *ch = tolower(ReadACh());
        MoveCursor(19,0); CleartoEOLN();
        switch (*ch) {
          case 127 :  leave();          /** hit DELETE! **/
          case 13  :  PutLine(19,0,"You think the word is: ");  /** <ret> **/
                      gets(guessed_word,MAX_CHARS);
                      if (strcmp(guessed_word, word) == 0) {
                        PutLine(19,0,"You Got It!");
                        CleartoEOLN();
                        return(GUESSED_IT);
                      }
                      else {
                        PutLine(19,0,"Nope.");
                        CleartoEOLN();
                        return(TRIED_GUESS);
                      }
          default  :  if (*ch < (char) 30) 
                        leave();
		      else if (*ch > 'z' || *ch < 'a') {
                        PutLine(19,0,"Guess must be 'A' thru 'Z'");
                        return(TRIED_GUESS);
                       }
                      if (guessed[*ch - 'a']) {
                        PutLine(19,0,"You already guessed that letter!");
                        return(TRIED_GUESS);
                      }
                      for (i = 0; i < strlen(word); i++)
                        if (word[i] == *ch)
                          return(GOOD_GUESS);
                      return(BAD_GUESS);
        }
}

add_to_guessed(ch)
char ch;
{
        /** add ch to guessed.  Keep guessed in alphabetical order! **/

	if (debug) printf("add_to_guessed(%c)\n",ch);
        guessed[ch - 'a']++;
}

show_guessed()
{
        /** show what characters have been guessed so far **/
        register int i;

	if (debug) printf("show_guessed()\n");
        PutLine(3,50, "Guessed: ");
        for (i = 0; i < 26; i++)
          if (guessed[i])
            putchar((char) i + 'a');
        fflush(stdout);
}

fill_in(ch)
char ch;
{
        /** fill in all occurances of 'ch' in word **/
        register int i;

	if (debug) printf("fill_in(%c)\n", ch);
        for (i=0; i < strlen(word); i++)
          if (word[i] == ch)
            part_word[i] = ch;
}       
        
show_word(word)
char *word;
{
        PutLine(6,50,"Word: %s", word);
        CleartoEOLN();
}

leave()
{
        MoveCursor(23,0);       
        exit(0);
}

/******* and now the cheery part: the hanging graphics routines! ********/

/**
                        
                        0                       @
     man to be hung -> (|)      the hangman -> /|\
                       / \                     / \

**/

char hangee[3][3];

#define put_man(who,l,c)        PutLine(l-2,c,"%3.3s",who[0]); \
                                PutLine(l-1,c,"%3.3s",who[1]); \
                                PutLine(l,c,"%3.3s", who[2]);
#define clear_man(l,c)          PutLine(l-2,c,"   "); \
                                PutLine(l-1,c,"   "); \
                                PutLine(l,c,"   ");
show_gallows(n)
int n;
{
        /** draw gallows...as n increases, draw the parts of the
            man to be hung... **/

        int line, column;

	if (debug) printf("show_gallows(%d)\n", n);
        if (n == 1) { /** place hangee! **/
          strcpy(hangee[0]," 0 "); 
          strcpy(hangee[1],"(|)");
          strcpy(hangee[2],"/ \\");
          place_man(1, &line, &column);
          put_man(hangee,line, column);
        }
        else if (n < 10) { 
          place_man(n-1, &line, &column); /* remove old hangee  */
          clear_man(line, column);
          place_man(n, &line, &column);	  /* put him at new loc */
          put_man(hangee,line, column);
	  fix_gallows(n-1);               /* and patch it up    */
        }
        else { /** too late: this is the big death scene! **/
          place_man(n-1, &line, &column);
          clear_man(line, column);
          place_man(n, &line, &column);
          put_man(hangee,line, column);
	  delay(300);
          PutLine(4,24,"|");
          PutLine(5,24,"|");
          PutLine(6,24,"#"); 
          PutLine(7,27,"- Augh!");
        }
}

place_man(n, line, col)
int n, *line, *col;
{
        switch(n) {
          case 1 : *line = 12;  *col = 1;       break;
          case 2 : *line = 10;  *col = 4;       break;
          case 3 : *line = 9;   *col = 7;       break;
          case 4 : *line = 8;   *col = 10;      break;
          case 5 : *line = 8;   *col = 16;      break;
          case 6 : *line = 8;   *col = 17;      break;
          case 7 : *line = 8;   *col = 18;      break;
          case 8 : *line = 8;   *col = 20;      break;
          case 9 : *line = 7;   *col = 23;      break;
          case 10: *line = 9;   *col = 23;      break;
        }
        
}

fix_gallows(n)
int n;
{
        /** fix the pieces being eaten by the little characters as
            the execution progresses! **/

        register int line, col, fix;

        switch(n) {
          case 0 :      return;
          case 1 : line = 12;   col = 1;  fix = 3;  break;
          case 2 : line = 10;   col = 4;  fix = 3;  break;
          case 3 : line = 9;    col = 7;  fix = 3;  break;
          case 4 : line = 8;    col = 10; fix = 3;  break;
          case 5 : line = 8;    col = 16; fix = 1;  break;
          case 6 : line = 8;    col = 17; fix = 1;  break;
          case 7 : line = 8;    col = 18; fix = 2;  break;
          case 8 : line = 8;    col = 20; fix = 3;  break;
        }

	switch(fix) {
	  case 3: PutLine(line, col, "___"); 	break;
	  case 2: PutLine(line, col, "__"); 	break;
	  case 1: PutLine(line, col, "_");	break;
	}
}

        
build_gallows()
{
        /** this is a macabre gallows...  **/
	PutLine(0,36,"- Hangman -");

	MoveCursor(2,0);
        printf("              ===========\n");
        printf("              |/        |\n");
        printf("              ||        #\n");
        printf("              ||        O\n");
        printf("              ||\n");
        printf("              ||\n");
        printf("          ____||_______TTT_________\n");
        printf("       ___|  |  |            |  |\n");
        printf("    ___|     |  |            |  |\n");
        printf("    |        |  |            |  |\n");
        printf("____|________|__|____________|__|_____\n");
	fflush(stdout);
}
END_OF_FILE
# --------------  File hangman.6 ---------------
echo extracting file hangman.6
cat << 'END_OF_FILE' > hangman.6
.TH HAHGMAN 6
.ad b
.SH NAME
hangman - play the computer in hangman
.SH SYNOPSIS
.B hangman
.SH HP-UX COMPATIBILITY
.TP 10
Level:
HP-UX/STANDARD
.TP
Origin:
Hewlett Packard
.SH DESCRIPTION
.I Hangman
is a macabre rewrite of the classic game of the same
name and is simple to play.
.SH AUTHOR
Dave Taylor, Hewlett Packard Colorado Network Operation
.SH SEE\ ALSO
addword(6)
.SH BUGS
It should be noted that some installations of this
program have databases containing extremely difficult
words to guess!
END_OF_FILE
# --------------  File curses.c ---------------
echo extracting file curses.c
cat << 'END_OF_FILE' > curses.c
/** 			curses.c		**/

/**  This library gives programs the ability to easily access the
     termcap information and write screen oriented and raw input
     programs.  The routines can be called as needed, except that
     to use the cursor / screen routines there must be a call to
     InitScreen() first.  The 'Raw' input routine can be used
     independently, however.

     Dave Taylor, HP Colorado Networks
**/

#include <stdio.h>

#ifdef RAWMODE
# include <termio.h>
#endif

#include <ctype.h>
#include "curses.h"

#ifdef RAWMODE
# define TTYIN	0
#endif

extern int debug;

#ifdef RAWMODE
  struct termio _raw_tty, 
              _original_tty;

  static int _inraw = 0;                  /* are we IN rawmode?    */
#endif

static int _intransmit;			/* are we transmitting keys? */

static
char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
     *_setbold, *_clearbold, *_setunderline, *_clearunderline, 
     *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
     *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off;
static
int
     _lines, _columns;

static char _terminal[1024];              /* Storage for terminal entry */
static char _capabilities[256];           /* String for cursor motion */

static char *ptr = _capabilities;	/* for buffering         */

int    outchar();			/* char output for tputs */

InitScreen()
{
   /* Set up all this fun stuff: returns zero if all okay, or;
        -1 indicating no terminal name associated with this shell,
        -2..-n  No termcap for this terminal type known
   */

   int  tgetent(),      /* get termcap entry */
        error;
   char *tgetstr(),     /* Get termcap capability */
        termname[40];

   if (strcpy(termname, getenv("TERM")) == NULL)
     return(-1);

   if ((error = tgetent(_terminal, termname)) != 1)
     return(error-2);

   /* load in all those pesky values */
   _clearscreen       = tgetstr("cl", &ptr);
   _moveto            = tgetstr("cm", &ptr);
   _up                = tgetstr("up", &ptr);
   _down              = tgetstr("do", &ptr);
   _right             = tgetstr("nd", &ptr);
   _left              = tgetstr("bs", &ptr); 
   _setbold           = tgetstr("so", &ptr);
   _clearbold         = tgetstr("se", &ptr);
   _setunderline      = tgetstr("us", &ptr);
   _clearunderline    = tgetstr("ue", &ptr);
   _setinverse        = tgetstr("so", &ptr);
   _clearinverse      = tgetstr("se", &ptr);
   _sethalfbright     = tgetstr("hs", &ptr);
   _clearhalfbright   = tgetstr("he", &ptr);
   _cleartoeoln       = tgetstr("ce", &ptr);
   _cleartoeos        = tgetstr("cd", &ptr);
   _lines	      = tgetnum("li");
   _columns	      = tgetnum("co");
   _transmit_on	      = tgetstr("ks", &ptr);
   _transmit_off      = tgetstr("ke", &ptr);


   if (!_left) {
      _left = ptr;
      *ptr++ = '\b';
      *ptr++ = '\0';
   }
   return(0);
}

char *return_value_of(termcap_label)
char *termcap_label;
{
	/** this will return the string kept by termcap for the 
	    specified capability **/

   	char *tgetstr();     		/* Get termcap capability */

	return( (char *) tgetstr(termcap_label, &ptr));
}

transmit_functions(newstate)
int newstate;
{
	/** turn function key transmission to ON | OFF **/
	
	if (newstate != _intransmit) {
	  _intransmit = ! _intransmit;
	  if (newstate == ON)
   	    tputs(_transmit_on, 1, outchar);
	  else 
   	    tputs(_transmit_off, 1, outchar);

   	  fflush(stdout);      /* clear the output buffer */
	}
}

/****** now into the 'meat' of the routines...the cursor stuff ******/

ScreenSize(lines, columns)
int *lines, *columns;
{
	/** returns the number of lines and columns on the display. **/

	*lines = _lines - 1;		/* assume index from zero */
	*columns = _columns;
}

ClearScreen()
{
        /* clear the screen: returns -1 if not capable */

   if (!_clearscreen) 
     return(-1);

   tputs(_clearscreen, 1, outchar);
   fflush(stdout);      /* clear the output buffer */
   return(0);
}

MoveCursor(row, col)
int row, col;
{
        /** move cursor to the specified row column on the screen.
            0,0 is the top left! **/

           char *tgoto();
	   char *stuff;

           if (!_moveto) 
             return(-1);

           stuff = (char *) tgoto(_moveto, col, row);
	   tputs(stuff, 1, outchar);
           fflush(stdout);
           return(0);
}


CursorUp()
{
        /** move the cursor up one line **/

        if (!_up)
           return(-1);

   	tputs(_up, 1, outchar);
	fflush(stdout);
        return(0);
}


CursorDown()
{
        /** move the cursor down one line **/

       if (!_down) 
          return(-1);

       tputs(_down, 1, outchar);
       fflush(stdout);
       return(0);
}


CursorLeft()
{
        /** move the cursor one character to the left **/

       if (!_left) 
          return(-1);

       tputs(_left, 1, outchar);
       fflush(stdout);
       return(0);
}


CursorRight()
{
        /** move the cursor one character to the right (nondestructive) **/

       if (!_right) 
          return(-1);

       tputs(_right, 1, outchar);
       fflush(stdout);
       return(0);
}


StartBold()
{
        /** start boldface/standout mode **/

       if (!_setbold) 
         return(-1);

       tputs(_setbold, 1, outchar);
       fflush(stdout);
       return(0);
}


EndBold()
{
        /** compliment of startbold **/

        if (!_clearbold) 
           return(-1);

       tputs(_clearbold, 1, outchar);
       fflush(stdout);
       return(0);
}


StartUnderline()
{
        /** start underline mode **/

       if (!_setunderline) 
          return(-1);

       tputs(_setunderline, 1, outchar);
       fflush(stdout);
       return(0);
}


EndUnderline()
{
        /** the compliment of start underline mode **/

       if (!_clearunderline) 
          return(-1);

       tputs(_clearunderline, 1, outchar);
       fflush(stdout);
       return(0);
}


StartHalfbright()
{
        /** start half intensity mode **/

       if (!_sethalfbright) 
         return(-1);

       tputs(_sethalfbright, 1, outchar);
       fflush(stdout);
       return(0);
}

EndHalfbright()
{
        /** compliment of starthalfbright **/

       if (!_clearhalfbright) 
          return(-1);

       tputs(_clearhalfbright, 1, outchar);
       fflush(stdout);
       return(0);
}

StartInverse()
{
        /** set inverse video mode **/

       if (!_setinverse) 
         return(-1);

       tputs(_setinverse, 1, outchar);
       fflush(stdout);
       return(0);
}


EndInverse()
{
        /** compliment of startinverse **/

       if (!_clearinverse) 
         return(-1);

       tputs(_clearinverse, 1, outchar);
       fflush(stdout);
       return(0);
}

PutLine(x, y, line, args)
int x,y;
char *line; 
int  args;
{
        /** write line, with 'args', at location x,y **/

        MoveCursor(x,y);
        _doprnt(line, &args, stdout);
        fflush(stdout);    /* ensure it actually gets out! */
}

CleartoEOLN()
{
        /** clear to end of line **/

       if (!_cleartoeoln) 
         return(-1);

       tputs(_cleartoeoln, 1, outchar);
       fflush(stdout);  /* clear the output buffer */
       return(0);
}

CleartoEOS()
{
        /** clear to end of screen **/

       if (!_cleartoeos) 
         return(-1);

       tputs(_cleartoeos, 1, outchar);
       fflush(stdout);  /* clear the output buffer */
       return(0);
}

#ifdef RAWMODE

Raw(state)
int state;
{
	/** state is either ON or OFF, as indicated by call **/

        if (state == OFF && _inraw) {
	  (void) ioctl(TTYIN, TCSETAW, &_original_tty);
          _inraw = 0;
	}
        else if (state == ON && ! _inraw) {
	  (void) ioctl(TTYIN, TCGETA, &_original_tty);	/** current setting **/
	  	
	  (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
	  _raw_tty.c_iflag &= ~(INLCR | ICRNL |BRKINT);
	  _raw_tty.c_iflag |= IXON;
	  _raw_tty.c_oflag |= OPOST;
	  _raw_tty.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
	  _raw_tty.c_lflag &= ~(ICANON | ECHO);
	  _raw_tty.c_cc[VMIN] = '\01';
	  _raw_tty.c_cc[VTIME] = '\0';
	  (void) ioctl(TTYIN, TCSETAW, &_raw_tty);

          _inraw = 1;
        }
}

int
ReadCh()
{
        /** read a character with Raw mode set! **/

        register int result;
        char ch;

        result = read(0, &ch, 1);
	
	return(result == 0? EOF : ch);
}

#endif

outchar(c)
char c;
{
	/** output the given character.  From tputs... **/
	/** Note: this CANNOT be a macro!              **/

	putc(c, stdout);
}
END_OF_FILE
# --------------  File curses.h ---------------
echo extracting file curses.h
cat << 'END_OF_FILE' > curses.h
/*** 			curses.h			***/

     /*** Include file for seperate compilation.  ***/

#define OFF		0
#define ON 		1

int  InitScreen(),      /* This must be called before anything else!! */

     ClearScreen(), 	 CleartoEOLN(),

     MoveCursor(),       PutLine(),
     CursorUp(),         CursorDown(), 
     CursorLeft(),       CursorRight(), 

     StartBold(),        EndBold(), 
     StartUnderline(),   EndUnderline(), 
     StartHalfbright(),  EndHalfbright(),
     StartInverse(),     EndInverse(),
	
     transmit_functions(),

     Raw(),              ReadCh();

char *return_value_of();
END_OF_FILE
# --------------  File addword.6 ---------------
echo extracting file addword.6
cat << 'END_OF_FILE' > addword.6
.TH ADDWORD 6
.ad b
.SH NAME
addword - add a word to the hangman database
.SH SYNOPSIS
.B addword
word
.SH HP-UX COMPATIBILITY
.TP 10
Level:
HP-UX/STANDARD
.TP
Origin:
Hewlett Packard
.SH DESCRIPTION
.I Addword
adds a new word to the hangman database.
.SH AUTHOR
Dave Taylor, Hewlett Packard Colorado Network Operation
.SH BUGS
.I Addword
doesn't check to ensure that the word isn't already
in the database, so it is possible to duplicate. 
END_OF_FILE
# --------------  File addword.c ---------------
echo extracting file addword.c
cat << 'END_OF_FILE' > addword.c
/***			addword.c		***/

/**  Add a word to the hangman word file.  Note this must be setuid games. **/

/** (C) 1985 Dave Taylor:  ihnp4!hpfcla!d_taylor -or-  hplabs!hpcnof!dat **/

#include <stdio.h>

#define WLEN		40
#define word_file	"/usr/games/lib/.hang-words"
#define temp_file	"/tmp/hang"
#define mode		300	/* -rw------ */

main(argc, argv)
int argc;
char *argv[];
{
	int words;
	char theword[WLEN], filename[40];
	FILE *w, *temp;
	
	if (argc != 2)
	  exit(printf("Usage: %s <word>\n", argv[0]));

	if ((w = fopen(word_file,"r")) == NULL)
	  exit(printf("Couldn't open word file!\n"));

	sprintf(filename,"%s.%d", temp_file, getpid());
	if ((temp = fopen(filename,"w")) == NULL)
	  exit(printf("Couldn't open temp file!\n"));

	fgets(theword, WLEN, w);

	sscanf(theword, "%d", &words);

	printf("Adding this word makes %d words!\n", ++words);

	fprintf(temp, "%d\n", words);

	while (fgets(theword, WLEN, w) != NULL)
	  fputs(theword, temp);

	fprintf(temp, "%s\n", argv[1]);
	fclose(temp);
	fclose(w);
	unlink(word_file);
	link(filename,word_file);
	unlink(filename);
	chmod(word_file, mode);
}
END_OF_FILE
# --------------  File .hang-words ---------------
echo extracting file .hang-words
cat << 'END_OF_FILE' > .hang-words
301
transcontinental
supermarket
prairie
trashcan
mysterious
interior
ulterior
xylophone
pizza
quietest
foray
confusion
kaleidoscope
lecherous
opiate
pious
proprietary
salacious
semaphore
suspicion
vertigo
psychotic
surrogate
typhoon
upholstery
vociferous
warranty
guarantee
wrath
aerospace
affirmation
apprehension
appease
articulate
arrogant
backhand
batten
bastinado
benediction
fight
braggadocio
brassiere
inquisition
caprice
chimney
clique
concessionaire
corsage
destructive
castrate
strength
mythological
animation
hangman
recursion
transformation
fornicate
glockenspiel
tongue
dictatorship
utilitarianism
establishment
homogeneous
horticulture
agriculture
hymnal
hydrometer
hyena
grandiose
hypothesize
ballistic
iconography
ideological
illegitimate
impediment
immune
culpable
lunar
subroutine
iterative
jigsaw
jurisdiction
kilogram
hashish
cocaine
marijuana
kimono
kyack
laminate
latitudinal
longtitudinal
cunning
tricky
presidential
contradictory
obnoxious
gardener
nuisance
reboot
numskull
muzzle
fodder
fascination
transliteration
compute
computer
network
notice
telephone
androgynous
homophobe
terminal
device
gamey
fascination
profile
ambiance
ambulatory
whore
contradiction
fatality
chiropractic
chicanery
buzzard
cache
xerox
internal
belch
laboratory
lightning
zodiac
victim
vignette
genre
rendezvous
vineyard
traffic
vibrating
jostle
vampire
jamboree
juggle
oblong
coffin
noose
plaza
collegiate
seaboard
empire
script
generation
submarine
linear
parallel
serial
duplicate
coaxial
triaxial
quadrangle
ogre
howitzer
machete
cathode
camouflage
combat
hybrid
shellac
neophyte
anthropomorphic
worthless
jabberwocky
wrong
kamikaze
yawning
coiffeur
suicide
squawk
kazoo
krypton
larynx
pyromania
prologue
appendix
communist
eunuch
pervert
masquerade
louse
magnetic
majestic
lumberjack
jocularity
jeopardy
luxuriate
prophylactic
malediction
hydroponic
manganese
horrify
masseuse
hazard
messiah
pariah
guzzle
crucifixion
guillotine
gallows
esoteric
pendulum
tourniquet
thumbscrew
enema
catheter
totalitarianism
transducer
transcend
nirvana
organize
chaos
spectre
ghoul
asthetic
timpani
plague
twitter
pneumonia
giggle
abdomen
bodacious
hilarious
adjourn
peculiar
android
vestibule
zombie
popcorn
anesthetic
cyborg
zipper
wretched
wrench
slime
wriggle
ridicule
quoth
usher
rowboat
house
valve
automobile
helicopter
vertex
vortex
virgin
violent
macabre
vomit
voodoo
voyeur
vulture
sparrow
gondola
polychrome
monochrome
plunder
intestine
whetstone
plight
reprieve
vulgarity
vulcanize
cannibalize
alcohol
vivisection
voguish
rogue
dastardly
queer
cocatrice
nymph
nuzzle
transmogrification
slaughter
grotesque
transvestite
transmutate
mutant
tsunami
cockroach
beetle
cemetery
caustic
twinkle
villify
centrifuge
definition
uglify
dictionary
ubiquitous
coercion
END_OF_FILE
echo done with shar extraction

dat@hpcnof.UUCP (01/10/86)

Ooops!  I made a slight error in the original posting of my hangman
game ...

If you're on a Bell system, you'll need to compile the current
(or the attached) curses.c module with:

	cc -O -D RAWMODE -c curses.c

(need to define RAWMODE)

If you're on a Berkeley system things get much more complex...you
need to use the new curses.c file (attached) and compile it with
the command:

	cc -O -D RAWMODE -D BSD -c curses.c

DISCLAIMER:  I don't have access to a machine running BSD software, so
if it turns out that the newly mangled curses program doesn't work, 
Please help me fix it!!

					--- Dave Taylor

------ attachment: curses.c

/** 			curses.c		**/

/**  This library gives programs the ability to easily access the
     termcap information and write screen oriented and raw input
     programs.  The routines can be called as needed, except that
     to use the cursor / screen routines there must be a call to
     InitScreen() first.  The 'Raw' input routine can be used
     independently, however.

     Dave Taylor, HP Colorado Networks
**/

#include <stdio.h>

#ifdef RAWMODE
#  ifdef BSD
#    include <sgtty.h>
#  else
#    include <termio.h>
#  endif
#endif

#include <ctype.h>
#include "curses.h"

#ifdef BSD

/** need to define this routine since BSD ctype.h doesn't include it! **/

#  define tolower(c)	(isupper(c)? c - 'A' + 'a' : c)

/** also need to map the System V ioctl stuff... **/

#define TCGETA 		TIOCGETP
#define TCSETAW		TIOCSETN

#endif

#ifdef RAWMODE
# define TTYIN	0
#endif

extern int debug;

#ifdef RAWMODE
#  ifdef BSD
  struct sgtty  _raw_tty,
		_original_tty;
#  else
  struct termio _raw_tty, 
              _original_tty;
#  endif

  static int _inraw = 0;                  /* are we IN rawmode?    */
#endif

static int _intransmit;			/* are we transmitting keys? */

static
char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
     *_setbold, *_clearbold, *_setunderline, *_clearunderline, 
     *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
     *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off;
static
int
     _lines, _columns;

static char _terminal[1024];              /* Storage for terminal entry */
static char _capabilities[256];           /* String for cursor motion */

static char *ptr = _capabilities;	/* for buffering         */

int    outchar();			/* char output for tputs */

InitScreen()
{
   /* Set up all this fun stuff: returns zero if all okay, or;
        -1 indicating no terminal name associated with this shell,
        -2..-n  No termcap for this terminal type known
   */

   int  tgetent(),      /* get termcap entry */
        error;
   char *tgetstr(),     /* Get termcap capability */
        termname[40];

   if (strcpy(termname, getenv("TERM")) == NULL)
     return(-1);

   if ((error = tgetent(_terminal, termname)) != 1)
     return(error-2);

   /* load in all those pesky values */
   _clearscreen       = tgetstr("cl", &ptr);
   _moveto            = tgetstr("cm", &ptr);
   _up                = tgetstr("up", &ptr);
   _down              = tgetstr("do", &ptr);
   _right             = tgetstr("nd", &ptr);
   _left              = tgetstr("bs", &ptr); 
   _setbold           = tgetstr("so", &ptr);
   _clearbold         = tgetstr("se", &ptr);
   _setunderline      = tgetstr("us", &ptr);
   _clearunderline    = tgetstr("ue", &ptr);
   _setinverse        = tgetstr("so", &ptr);
   _clearinverse      = tgetstr("se", &ptr);
   _sethalfbright     = tgetstr("hs", &ptr);
   _clearhalfbright   = tgetstr("he", &ptr);
   _cleartoeoln       = tgetstr("ce", &ptr);
   _cleartoeos        = tgetstr("cd", &ptr);
   _lines	      = tgetnum("li");
   _columns	      = tgetnum("co");
   _transmit_on	      = tgetstr("ks", &ptr);
   _transmit_off      = tgetstr("ke", &ptr);


   if (!_left) {
      _left = ptr;
      *ptr++ = '\b';
      *ptr++ = '\0';
   }
   return(0);
}

char *return_value_of(termcap_label)
char *termcap_label;
{
	/** this will return the string kept by termcap for the 
	    specified capability **/

   	char *tgetstr();     		/* Get termcap capability */

	return( (char *) tgetstr(termcap_label, &ptr));
}

transmit_functions(newstate)
int newstate;
{
	/** turn function key transmission to ON | OFF **/
	
	if (newstate != _intransmit) {
	  _intransmit = ! _intransmit;
	  if (newstate == ON)
   	    tputs(_transmit_on, 1, outchar);
	  else 
   	    tputs(_transmit_off, 1, outchar);

   	  fflush(stdout);      /* clear the output buffer */
	}
}

/****** now into the 'meat' of the routines...the cursor stuff ******/

ScreenSize(lines, columns)
int *lines, *columns;
{
	/** returns the number of lines and columns on the display. **/

	*lines = _lines - 1;		/* assume index from zero */
	*columns = _columns;
}

ClearScreen()
{
        /* clear the screen: returns -1 if not capable */

   if (!_clearscreen) 
     return(-1);

   tputs(_clearscreen, 1, outchar);
   fflush(stdout);      /* clear the output buffer */
   return(0);
}

MoveCursor(row, col)
int row, col;
{
        /** move cursor to the specified row column on the screen.
            0,0 is the top left! **/

           char *tgoto();
	   char *stuff;

           if (!_moveto) 
             return(-1);

           stuff = (char *) tgoto(_moveto, col, row);
	   tputs(stuff, 1, outchar);
           fflush(stdout);
           return(0);
}


CursorUp()
{
        /** move the cursor up one line **/

        if (!_up)
           return(-1);

   	tputs(_up, 1, outchar);
	fflush(stdout);
        return(0);
}


CursorDown()
{
        /** move the cursor down one line **/

       if (!_down) 
          return(-1);

       tputs(_down, 1, outchar);
       fflush(stdout);
       return(0);
}


CursorLeft()
{
        /** move the cursor one character to the left **/

       if (!_left) 
          return(-1);

       tputs(_left, 1, outchar);
       fflush(stdout);
       return(0);
}


CursorRight()
{
        /** move the cursor one character to the right (nondestructive) **/

       if (!_right) 
          return(-1);

       tputs(_right, 1, outchar);
       fflush(stdout);
       return(0);
}


StartBold()
{
        /** start boldface/standout mode **/

       if (!_setbold) 
         return(-1);

       tputs(_setbold, 1, outchar);
       fflush(stdout);
       return(0);
}


EndBold()
{
        /** compliment of startbold **/

        if (!_clearbold) 
           return(-1);

       tputs(_clearbold, 1, outchar);
       fflush(stdout);
       return(0);
}


StartUnderline()
{
        /** start underline mode **/

       if (!_setunderline) 
          return(-1);

       tputs(_setunderline, 1, outchar);
       fflush(stdout);
       return(0);
}


EndUnderline()
{
        /** the compliment of start underline mode **/

       if (!_clearunderline) 
          return(-1);

       tputs(_clearunderline, 1, outchar);
       fflush(stdout);
       return(0);
}


StartHalfbright()
{
        /** start half intensity mode **/

       if (!_sethalfbright) 
         return(-1);

       tputs(_sethalfbright, 1, outchar);
       fflush(stdout);
       return(0);
}

EndHalfbright()
{
        /** compliment of starthalfbright **/

       if (!_clearhalfbright) 
          return(-1);

       tputs(_clearhalfbright, 1, outchar);
       fflush(stdout);
       return(0);
}

StartInverse()
{
        /** set inverse video mode **/

       if (!_setinverse) 
         return(-1);

       tputs(_setinverse, 1, outchar);
       fflush(stdout);
       return(0);
}


EndInverse()
{
        /** compliment of startinverse **/

       if (!_clearinverse) 
         return(-1);

       tputs(_clearinverse, 1, outchar);
       fflush(stdout);
       return(0);
}

PutLine(x, y, line, args)
int x,y;
char *line; 
int  args;
{
        /** write line, with 'args', at location x,y **/

        MoveCursor(x,y);
        _doprnt(line, &args, stdout);
        fflush(stdout);    /* ensure it actually gets out! */
}

CleartoEOLN()
{
        /** clear to end of line **/

       if (!_cleartoeoln) 
         return(-1);

       tputs(_cleartoeoln, 1, outchar);
       fflush(stdout);  /* clear the output buffer */
       return(0);
}

CleartoEOS()
{
        /** clear to end of screen **/

       if (!_cleartoeos) 
         return(-1);

       tputs(_cleartoeos, 1, outchar);
       fflush(stdout);  /* clear the output buffer */
       return(0);
}

#ifdef RAWMODE

Raw(state)
int state;
{
	/** state is either ON or OFF, as indicated by call **/

        if (state == OFF && _inraw) {
	  (void) ioctl(TTYIN, TCSETAW, &_original_tty);
          _inraw = 0;
	}
        else if (state == ON && ! _inraw) {
	  (void) ioctl(TTYIN, TCGETA, &_original_tty);	/** current setting **/
	  	
	  (void) ioctl(TTYIN, TCGETA, &_raw_tty);    /** again! **/
#ifdef BSD
	  _raw_tty.sg_flags &= ~(CRMOD | ECHO)
	  _raw_tty.sg_flags &=  (RAW);
#else
	  _raw_tty.c_iflag &= ~(INLCR | ICRNL | BRKINT);
	  _raw_tty.c_iflag |= IXON;
	  _raw_tty.c_oflag |= OPOST;
	  _raw_tty.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
	  _raw_tty.c_lflag &= ~(ICANON | ECHO);
	  _raw_tty.c_cc[VMIN] = '\01';
	  _raw_tty.c_cc[VTIME] = '\0';
#endif
	  (void) ioctl(TTYIN, TCSETAW, &_raw_tty);

          _inraw = 1;
        }
}

int
ReadCh()
{
        /** read a character with Raw mode set! **/

        register int result;
        char ch;

        result = read(0, &ch, 1);
	
	return(result == 0? EOF : ch);
}

#endif

outchar(c)
char c;
{
	/** output the given character.  From tputs... **/
	/** Note: this CANNOT be a macro!              **/

	putc(c, stdout);
}