amator@homxb.ATT.COM (T.NECEDA) (02/04/89)
if you have curses, rand48(), SYS5, and an ascii word list you can probably run this game....if not it probably will take about 3 minutes to port to whatever you do have. --------cut here--------cut here----------cut here---------cut here--------- #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # README # Makefile # main.c # dogame.c # if test -f README; then echo "File README exists"; else echo "x - extracting README (Text)" sed 's/^X//' << 'SHAR_EOF' > README && XHere is a quick 'hangperson' program based on the ever-so-popular Xhangman game we used to relish playing as kids. I have forgotten Xsome of the rules (in particular - how many wrong guesses you are allowed) Xso I just guessed on a couple of things. X XThis was written on a system running SYSVR3. I make no guarantees that Xit will run correctly anywhere. I do humbly apologize for some Xof the poor code, incoherent comments, and lack of a help screen but, Xwhat the hell, it was quick, easy, and now it's free. Please feel free Xto hack it to death if you want. X XWhat you will have to do: X 1. Unshar this file (which you may have done already) X 2. edit main.c and change the define of WORDLIST to the path X of your ascii word list ( /usr/dict/words may be a good one ), X and change the define of NO_OF_WORDS to the total amount of X words in WORDLIST (`wc -l' might help there). X 3. type make X Xenjoy! XThomas W. Neceda Xatt!homxb!amator X SHAR_EOF chmod 0600 README || echo "restore of README fails" fi if test -f Makefile; then echo "File Makefile exists"; else echo "x - extracting Makefile (Text)" sed 's/^X//' << 'SHAR_EOF' > Makefile && X X# Makefile for 'hangperson'. Edit BIN if you want to install in some other X# place than /usr/games. X# X# Make sure you edit the main.c file first and redefine WORDLIST and X# NO_OF_WORDS X XBIN= /usr/games XLDLIBS= -lcurses -ltermcap XFINAL= hangperson X XCFLAGS= -O X XOBJECTS = main.o dogame.o X X$(FINAL): $(OBJECTS) X $(CC) -o $(FINAL) $(OBJECTS) $(LDLIBS) X Xinstall: $(FINAL) X cp $(FINAL) $(BIN) X strip $(BIN)/$(FINAL) X Xcleanup: X rm -f $(OBJECTS) $(FINAL) X SHAR_EOF chmod 0600 Makefile || echo "restore of Makefile fails" fi if test -f main.c; then echo "File main.c exists"; else echo "x - extracting main.c (Text)" sed 's/^X//' << 'SHAR_EOF' > main.c && X/***************************************************************************** X a hangperson program written with curses. X X 1/30/89 by Thomas W. Neceda X please send any comments/fixes/flames/money to X att!homxb!amator X This is public domain - You can do absolutely whatever you want with X this, but if someone is foolish enough to give you money for this I'd X appreciate it if you would buy me a beer sometime. X******************************************************************************/ X X/***************************************************************************** X You will most probably have to redefine these next two. I understand X that /usr/dict/words is a popular spot to find an ascii word list. X NO_OF_WORDS is the result of `wc -l /usr/dict/words` or where ever the X dictionary happens to be. X******************************************************************************/ X X#define WORDLIST "/usr/src/cmd/spell/list" /*location of dictionary*/ X#define NO_OF_WORDS 23739 /*number of words in dict.*/ X X#include <ctype.h> X#include <stdio.h> X#include <time.h> X Xchar word[30]; X Xmain() X{ X char *c, *getaword() ; X static int i ; X X do { X i = getint(); /* get an integer that will correspond to a line */ X c = getaword(i); /* get the word on the line from above integer */ X } while( c == NULL ); X X do_game(c); /* do the game */ X endgame(); /* should never get here */ X} X X/* get a random number that falls between 1 and the total number or words in X the dictionary file. This number will be used as a line number to get X the word on that line. (this whole procedure probably would be more X efficient if using fstat()/fseek() ) X*/ Xgetint() X{ X long int i, time(); X int j = 1 ; X X srand48( (int)time((long int *)0) ); /* seed with current time */ X i = lrand48(); /* get a random long */ X X j = i % 10 ; /* get a number to divide by */ X X /* someone once told me you can't divide by zero...1 is not cool here X either.....33 was just picked out of the hat */ X X j = ( j > 1) ? j : 33 ; X X while( i > NO_OF_WORDS ) X i = i / j ; X X return(i); X} X X/* get a word from the dictionary....the number passed to this function X should correspond to a line number in the dictionary file X*/ Xchar * Xgetaword(i) Xint i; X{ X static char c ; X extern char word[]; X FILE *fp ; X X if((fp=fopen(WORDLIST, "r")) == NULL ){ X printf("Can't open file\n"); X exit(2); X } X X for( ; i > 0 ; i-- ) X fgets(word, 29, fp); X X c = word[0] ; X X if( isupper(c) || isdigit(c) ){ /* we don't want any words that */ X fclose(fp); /* begin with capitals or numbers */ X return((char *)NULL); X } X else{ X fclose(fp); X return((char *)word); /* got a word? well...return * ! */ X } X} SHAR_EOF chmod 0600 main.c || echo "restore of main.c fails" fi if test -f dogame.c; then echo "File dogame.c exists"; else echo "x - extracting dogame.c (Text)" sed 's/^X//' << 'SHAR_EOF' > dogame.c && X/***************************************************************************** X a hangperson program written with curses. X X 1/30/89 by Thomas W. Neceda X please send any comments/fixes/flames/money to X att!homxb!amator X This is public domain - You can do absolutely whatever you want with X this, but if someone is foolish enough to give you money for this I'd X appreciate it if you would buy me a beer. X******************************************************************************/ X X#include <ctype.h> X#include <curses.h> X#include <signal.h> X Xdo_game(word) Xchar word[]; X{ X static char *poorsoul[] = { X " O`\\ ", X " /|_| ", X " ' ||` ", X " || ", X " '` ", X " " }; X static char *snap[] = { X " O ", X " /-`\\/`", X " \\ /` ", X " ' | \\ ", X " / \\", X " ' , " }; X X static char *bottom[] = {"---------------------------"}; X static char *yardarm[] = {"------------"}; X static char *side[] = { "|","|","|","|", "|", "|","|","|", "|", "|", "|"}; X static char *post[] = {"|", "|", "|", "|", "|", "|", "|", "|"}; X static char *rope[] = {"|", "|"}; X static char *alpha[] = {"a", "b","c","d","e","f","g","h","i","j","k","l", X "m","n","o","p","q","r","s","t","u","v","w","x","y","z"}; X X static char guessed[40]; /* letters already guessed,right or wrong*/ X static int j = 0; /* index for guessed[] */ X static char cur_guess ; /* the current guess */ X static int i ; /* your basic index'er */ X static int dupe; /* if cur_guess in guessed[] */ X static int total ; /* amount of characters in word[] */ X static int toomany ; /* how many wrong guesses */ X static int hit; /* if cur_guess is a good guess */ X static int miss; /* if cur_guess is a bad guess */ X X extern int endgame(); /* normal end of game */ X extern int quickend(); /* abnormal end of game */ X X signal(SIGINT, quickend); /* some basic signal handling here */ X signal(SIGHUP, quickend); X signal(SIGQUIT, quickend); X X initscr(); X clear(); X X for( i=0 ; word[i] != '\n' ; i++ ) /* put underscores to indicate */ X mvaddch(LINES / 2 , i, '_' ); /* the word's letters */ X X total = i ; X X mvaddstr(1, 0, "Unused Letters:"); /* make a list of unused letters */ X for(i = 0 ; i < 26 ; i++) /* (each letter will be deleted as */ X mvprintw(2, i, "%c", *alpha[i]); /* guessed) */ X X mvprintw(LINES-3, 0, "There are %d letters in the word", total ); X mvprintw(LINES-2, 0, "Please enter a letter"); X refresh(); X X while( total > 0 ){ /* haven't guessed all the characters */ X while( miss != 1 ){ /* do until guess is a character */ X move(LINES-1, 0); X clrtoeol(); X refresh(); X cur_guess = tolower(getch()); /* make sure its lower case */ X if( cur_guess == '\014' ){ /* refresh screen with ^L */ X clearok(stdscr, TRUE); X refresh(); X miss = 0 ; X } X else if(isalpha(cur_guess) != 0 ) /*check to see if a letter */ X miss = 1 ; X else{ /* if not a letter, beep */ X miss = 0 ; X beep(); X move(LINES-1, 0); X clrtoeol(); X refresh(); X } X } X miss = 0 ; /* reset miss for next guess */ X X for( i=0 ; i <= j ; i++ ){ /* go through all guesses to see if */ X if(guessed[i] == cur_guess) /* previously guessed */ X dupe = 1 ; X } X if(dupe == 1 ){ /* if previously guessed then say so */ X move(LINES-2, 0 ); X clrtoeol(); X printw("Don't be silly!"); X refresh(); X beep(); X dupe = 0; X } X else{ /* otherwise put the */ X for( i=0 ; word[i] != '\n' ; i++ ){ /* letter in its proper */ X if(cur_guess == word[i]){ /* place */ X move(LINES-2, 0 ); X clrtoeol(); X printw("HIT"); X mvprintw(LINES/2, i, "%c", cur_guess ); X hit = 1 ; X total-- ; X if(total == 0){ /* all guessed correctly? */ X mvprintw(LINES-2, 0, "We have a WINNER!->%s", word); X refresh(); X endgame(); X } X } X } X if( hit == 1 ) /* if letter was a good one reset hit for */ X hit = 0 ; /* next loop */ X else{ X move(LINES-2, 0 ); /* otherwise increment toomany and print */ X clrtoeol(); /* the appropriate part of the gallows */ X printw("Sorry"); X toomany++ ; X refresh(); X switch(toomany) X { X case 1 : X hanger(bottom, 1, 20, COLS/2 ); X break ; X case 2 : X hanger(side, 10, 10, COLS/2 ); X break ; X case 3 : X hanger(side, 10, 10, COLS/2 + 26 ); X break ; X case 4 : X hanger(bottom, 1, 9, COLS/2 ); X break ; X case 5 : X hanger(post, 6, 3, COLS/2 + 5 ); X break ; X case 6 : X hanger(yardarm, 1, 2, COLS/2 + 5 ); X break ; X case 7 : X hanger(rope, 2, 3, COLS/2 + 17 ); X break ; X case 8 : X mvprintw(1, COLS/2, "HEY! No more wrong guesses OK????"); X hanger(poorsoul, 5, 5, COLS/2 + 14 ); X beep(); X break ; X case 9 : X move(1,0); /* player is dead meat here */ X clrtoeol(); X mvprintw(1, 0, "AAAAAAARRRRRGGGGHHHHHHHHHHHH"); X mvprintw(LINES-2,0," too many wrong guesses! word was: %s", X word); X refresh(); X beep(); X for( i = 5 ; i <= 13 ; i++ ){ X hanger(poorsoul, 5, i, COLS/2 + 14 ); X mvprintw( i , COLS/2 + 16, " | " ); X } X hanger(snap, 6, i, COLS/2 +14); X hanger(snap, 6, i, COLS/2 +14); X hanger(poorsoul, 6, i, COLS/2 +14); X endgame(); X break ; X default : X endgame(); X } X } X for(i = 0 ; i < 26 ; i++){ /* delete the letter from */ X if( cur_guess == *alpha[i] ) /* list of unused letters */ X mvaddch(2, i, ' '); X } X guessed[j++] = cur_guess ; /* add the guess to list of */ X /* previously guessed letters*/ X refresh(); X } X } X refresh(); X endgame(); X} X X /* draw a part of the gallows */ Xhanger(pic, length, y, x) Xchar *pic[]; Xint length, y, x; X{ X int i; X for ( i=0 ; i < length ; i++ ) X mvprintw(i+y, x, pic[i]); X refresh(); X} X X /* normal end of game */ Xendgame() X{ X endwin(); X exit(); X} X X /* abnormal end of game....just clears the screen too */ Xquickend() X{ X clear(); X refresh(); X endwin(); X exit(); X} SHAR_EOF chmod 0600 dogame.c || echo "restore of dogame.c fails" fi exit 0 -- # Thomas W. Neceda (201) 949-3215 # AT&T - Bell Laboratories # att!{homxb, hopat}!amator