games@tekred.TEK.COM (09/15/88)
Submitted by: Robert Steven Glickstein <bobg+@andrew.cmu.edu> Comp.sources.games: Volume 5, Issue 63 Archive-name: yid-slots #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: Makefile README yid-names yid-slots.c yid-slots.h # Wrapped by billr@saab on Wed Sep 14 13:17:43 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(363 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X XGAMEFILE=/usr/games/yid-slots XNAMEFILE=/usr/games/yid-names X XCC=cc XCFLAGS=-O X Xinstall: install-names install-slots X Xinstall-names: yid-names X -cp yid-names ${NAMEFILE} X Xinstall-slots: yid-slots X -cp yid-slots ${GAMEFILE} X Xyid-slots: yid-slots.o X ${CC} ${CFLAGS} yid-slots.o -o yid-slots -lcurses -ltermcap X Xyid-slots.o: yid-slots.c yid-slots.h END_OF_FILE if test 363 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1471 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' X XYID-SLOTS - The Jewish Name Slot Machine (c) 1987 by Bob Glickstein X X XPermission is hereby granted to freely distribute and modify this Xsoftware, provided that X 1) The above copyright notice appears on all files and X in the introduction to the program, and X 2) A notice is appended to the copyright identifying any X modifications to the original XThe author waives all responsibility for everything. X XYid-slots is a slot-machine-like game in which the windows display not Xapples, oranges and cherries, but portions of Jewish names. There are Xthree windows; first names, last-name prefixes and last-name suffixes. XCertain combinations pay off according to the file yid-names. For example, X X Bob Glick stein X Xpays a very great deal indeed. X XThe game is invoked simply as "yid-slots"; a single optional Xargument names an alternative file to yid-names. X XModify the Makefile to have proper destinations for the GAMEFILE X(the executable) and the NAMEFILE (the data file). Modify the file Xyid-slots.h to contain a definition for the macro FDEFAULT; it should Xbe the same as the Makefile's NAMEFILE macro. X XA bug in this program may require you to use a LineFeed (^J) frather Xthan a NewLine (^M) when entering lines of data into the program X(namely, your bets). The rest of the program should be self-explanatory. X XHave loads-o-fun. X X XBob Glickstein XInformation Technology Center XCarnegie Mellon University X Xbobg@andrew.cmu.edu END_OF_FILE if test 1471 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'yid-names' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'yid-names'\" else echo shar: Extracting \"'yid-names'\" \(521 characters\) sed "s/^X//" >'yid-names' <<'END_OF_FILE' XBob XNathaniel XHeshy XBarry XMurray XSolly XMorty XSylvia XMyron XBernie XMarty XYossel XSadie XIrwin XZelda XRuth XHarvey XAlbert X* XGlick XBoren XStein XSpiel XLefko XBlum XFeld XRosen XStern XSilver XEisen XGuilden XRoth XFeir XGold XSaper XFein X* Xstein Xberg Xbloom Xbaum Xman Xfeld Xgold Xstone Xbach Xblatt Xcrantz Xstern Xwitz X* XNathaniel ? ? 5 X? ? blatt 5 XBob ? ? 10 X? Glick ? 20 X? Guilden stern 50 X? Rosen crantz 50 X? Boren stein 100 X? Spiel berg 100 X? Glick stein 200 XMarty Feld man 300 XSteven Spiel berg 500 XNathaniel Boren stein 500 XBob Glick stein 1000 END_OF_FILE if test 521 -ne `wc -c <'yid-names'`; then echo shar: \"'yid-names'\" unpacked with wrong size! fi # end of 'yid-names' fi if test -f 'yid-slots.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'yid-slots.c'\" else echo shar: Extracting \"'yid-slots.c'\" \(12059 characters\) sed "s/^X//" >'yid-slots.c' <<'END_OF_FILE' X/* Yid Slots X * (c) 1987 by Bob Glickstein X * X * See the README file for information regarding the legal status of X * this software. X * X * Program simulates a slot machine in which the first of three windows X * contains typical Jewish first names; the second window X * conatins typical Jewish last-name-prefixes; and the third window X * contains typical Jewish last-name-suffixes. A file is read in X * to determine the set of name-parts. The file contains payoffs for X * certain combinations. In the default file, the biggest X * payoff is for the combination "Bob Glick stein". X */ X X/* FORMAT OF DATA FILE CONTAINING NAMES PARTS AND PAYOFFS: X * <list-of-first-names-each-separated-by-white-space> X * <nl>*<nl> (That is, an asterisk alone on a line) X * <list-of-last-name-prefixes-each-separated-by-white-space> X * <nl>*<nl> X * <list-of-last-name-suffixes-each-separated-by-white-space> X * <nl>*<nl> X * <a-first-name> <a-prefix> <a-suffix> <a-payoff-number><nl> X * (this last line can be repeated as many times as you like, for as X * many payoffs as you'd like to have. The payoff-number is the number X * of credits to return for every credit that was bet. A "?" in any of the X * first name, prefix, or suffix positions matches anything. X * X * RESTRICTIONS: No single string in the data file may be >= 20 chars X * in length. X */ X X X X X#include <stdio.h> X#include <curses.h> X#include "yid-slots.h" X X Xstruct namenode *names[3]; /* names[0] points to a linked list of first X * names; names[1] to a linked list of X * prefixes; names[2] to suffixes */ X Xstruct namenode *curnode[3]; /* These pointers hold our current position X * within the lists pointed to by names. (By X * current position, I mean the nodes X * appearing in the CENTER of the window. X * These pointers trail behind the printnode X * pointers.) */ X Xstruct namenode *printnode[3]; /* Points to the nodes being printed in the X * windows. When the wheels stop spinning, X * these pointers point to nodes in the X * BOTTOMS of the windows. Curnode points to X * nodes in the CENTERS of the windows (these X * are the nodes that win). */ X Xstruct payoff *payoffs; /* A linked list of payoffs */ X XWINDOW *betwin, *textwin, *namewins[3]; /* betwin displays Xcurrent X * money & current bet; X * textwin is a dialogue X * window; namewins are the X * three slot machine windows */ XWINDOW *boxwin; /* boxwin displays a box around name Xwindows */ X Xint bankroll; /* Amount of money player has */ X Xmain(argc, argv) Xint argc; Xchar *argv[]; X X{ X char *fname; X X if (argc == 2) X fname = argv[1]; X else { X if (argc == 1) X fname = FDEFAULT; X else { X fprintf(stderr, "Usage: %s [yidnamefile]\n", argv[0]); X exit(1); X } X } X X initglobals(); X X if (readnamefile(fname)) { /* if file successfully read */ X initdisplay(); X signon(); X play(); X signoff(); X cleanup(); X } X else { X cleanup(); X fprintf(stderr, "%s: error reading file %s\n", argv[0], fname); X exit(1); X } X} X X X/* advance - given an index into names[], and a pointer to the current X * position, advance returns the next position in the linked list X * names[i], wrapping around to the head of the list at the end X */ X Xstruct namenode *advance(i, ptr) Xint i; Xstruct namenode *ptr; X{ X return ((ptr->next) ? ptr->next : names[i]); X} X X X/* My own random-number generator, generates a random number between 0 and X * n-1 (the argument). Call this fn. with an arg. of 0 to seed the generator X * randomly (will return 0). X */ X Xlong bgrandom(n) Xlong n; X{ X long time(), random(); X X if (!n) X srandom((int) (time(NULL) & 0377)); X else X return (random() % n); X} X X Xinitglobals() X{ X bgrandom((long) 0); X X names[0] = names[1] = names[2] = NULL; X payoffs = NULL; X curnode[0] = curnode[1] = curnode[2] = NULL; X printnode[0] = printnode[1] = printnode[2] = NULL; X X initscr(); X X namewins[0] = newwin(WINDOWHEIGHT, WINDOWWIDTH, X WINDOW_Y_START, 1); X namewins[1] = newwin(WINDOWHEIGHT, WINDOWWIDTH, X WINDOW_Y_START, 3 + WINDOWWIDTH); X namewins[2] = newwin(WINDOWHEIGHT, WINDOWWIDTH, X WINDOW_Y_START, 5 + 2 * WINDOWWIDTH); X X boxwin = newwin(WINDOWHEIGHT + 2, 7 + 3 * WINDOWWIDTH, X WINDOW_Y_START - 1, 0); X X textwin = newwin(AUX_WINHEIGHT, TEXTWIDTH, X WINDOWHEIGHT + WINDOW_Y_START + 2, 0); X betwin = newwin(AUX_WINHEIGHT, BETWIDTH, X WINDOWHEIGHT + WINDOW_Y_START + 2, TEXTWIDTH + 2); X X scrollok(namewins[0], TRUE); X scrollok(namewins[1], TRUE); X scrollok(namewins[2], TRUE); X scrollok(textwin, TRUE); X X bankroll = INIT_BANKROLL; X} X X X/* initdisplay() does things like erase the windows, draw the boxes, X * fill in non-changing text (like the templates "Amount in wallet:" X * and "Amount of bet:" in the betwindow X * MOST IMPORTANTLY, this routine fills up the three windows with the first X * few name parts and sets all of the pointers correctly (curnode, X * printnode). X */ X X/* WARNING: contains lots of hardwired numbers X */ X Xinitdisplay() X{ X int i, j; X X werase(textwin); X werase(betwin); X wprintw(betwin, "You have:\n %d\nAmt. of bet:\n %d", bankroll, 0); X wrefresh(textwin); X wrefresh(betwin); X X werase(boxwin); X box(boxwin, '.', '.'); X for (j = 1; j <= 5; ++j) { X wmove(boxwin, j, 23); X waddstr(boxwin, ".."); X wmove(boxwin, j, 47); X waddstr(boxwin, ".."); X } X X wmove(boxwin, 3, 0); X waddch(boxwin, '-'); X wmove(boxwin, 3, 23); X waddstr(boxwin, "--"); X wmove(boxwin, 3, 47); X waddstr(boxwin, "--"); X wmove(boxwin, 3, 72); X waddch(boxwin, '-'); X wrefresh(boxwin); X X for (i = 0; i < 3; ++i) { X werase(namewins[i]); X printnode[i] = names[i]; X wprintw(namewins[i], "%s", printnode[i]->name); X } X for (i = 0; i < 3; ++i) { X printnode[i] = advance(i, printnode[i]); X wprintw(namewins[i], "\n%s", printnode[i]->name); X } X for (i = 0; i < 3; ++i) { X curnode[i] = printnode[i] = advance(i, printnode[i]); X wprintw(namewins[i], "\n%s", printnode[i]->name); X } X for (j = 1; j <= 2; ++j) X for (i = 0; i < 3; ++i) { X printnode[i] = advance(i, printnode[i]); X wprintw(namewins[i], "\n%s", printnode[i]->name); X } X for (i = 0; i < 3; ++i) { X overwrite(namewins[i], boxwin); X wrefresh(namewins[i]); X } X} X X Xcleanup() X{ X endwin(); X} X X Xint readnamefile(fname) /* Attempts to load names in from a X * hopefully correct-format namefile */ Xchar *fname; X{ X FILE *fp; X int i, tpay; X char buffer[3][BUFLEN], *malloc(); X struct namenode *tnode; X struct payoff *tpayoff; X X if (!(fp = fopen(fname, "r"))) X return (FALSE); /* No Good */ X X for (i = 0; i < 3; ++i) { X do { X fscanf(fp, "%s", buffer[0]); X if (buffer[0][0] != DELIM) { X tnode = (struct namenode *) malloc(sizeof(struct namenode)); X tnode->name = malloc(1 + strlen(buffer[0])); X X /* X * WARNING: These malloc's are not checked for failure X */ X strcpy(tnode->name, buffer[0]); X tnode->next = names[i]; X names[i] = tnode; /* Links it into the list */ X } X } while (buffer[0][0] != DELIM); X } X while (fscanf(fp, "%s %s %s %d", buffer[0], buffer[1], buffer[2], &tpay) X== 4) { X tpayoff = (struct payoff *) malloc(sizeof(struct payoff)); X for (i = 0; i < 3; ++i) { X tpayoff->parts[i] = malloc(1 + strlen(buffer[i])); X strcpy(tpayoff->parts[i], buffer[i]); X } X tpayoff->pay = tpay; X tpayoff->next = payoffs; X payoffs = tpayoff; /* Links it into the list */ X } X return (TRUE); X} X X Xsignon() X{ X wprintw(textwin, X "Welcome to Yid Slots\n(c) 1987 by Bob Glickstein\n"); X wrefresh(textwin); X} X X Xsignoff() X{ X wprintw(textwin, "Thank you for playing Yid Slots\n"); X wrefresh(textwin); X} X X X/* Main loop of program */ Xplay() X{ X int bet; X X while (bankroll > 0) { X if (!(bet = placebet())) X return; /* A bet of zero ends the game */ X X spin(); X bankroll += settle(bet);/* settle() returns -bet if no winning X * combinations came up; otherwise, it X * returns the number of credits by which to X * augment bankroll */ X wmove(betwin, 1, 1); X wprintw(betwin, "%d", bankroll); X wclrtoeol(betwin); X wrefresh(betwin); X } X} X X X/* Dialogue & input of bet amount */ X Xint placebet() X{ X int again = TRUE, bet; X X wprintw(textwin, "Place your bet (0 ends the game)\n "); X wrefresh(textwin); X while (again) { X wscanw(textwin, "%d", &bet); X wrefresh(textwin); X if ((bet < 0) || (bet > bankroll)) { X wprintw(textwin, "Bet must be non-negative and affordable\n"); X wrefresh(textwin); X again = TRUE; X } X else X again = FALSE; X } X wmove(betwin, 3, 1); X wprintw(betwin, "%d", bet); X wclrtoeol(betwin); X wrefresh(betwin); X return (bet); X} X X X/* Set the wheels a-spin, stopping them one at a time after X * a random interval (maximum MAXSPIN ticks per wheel) X */ X Xspin() X{ X int counter; X long r; X X for (counter = 0; counter < 3; ++counter) X for (r = MAXSPIN; r && bgrandom(r); --r) X spinwheels(counter); X} X X X/* Advance wheels counter through 2 one tick each */ X Xspinwheels(counter) Xint counter; X{ X int i; X X for (i = counter; i < 3; ++i) { X printnode[i] = advance(i, printnode[i]); X curnode[i] = advance(i, curnode[i]); X wprintw(namewins[i], "\n%s", printnode[i]->name); X wrefresh(namewins[i]); X } X} X X X/* Examine what came up on the wheels. Compare against X * winning combinations in the payoffs linked list. If there X * is a match, return the payoff times the bet placed. If X * not, return -bet X */ X Xint settle(bet) Xint bet; X{ X struct payoff *ptr; X X wmove(betwin, 3, 1); X wprintw(betwin, "%d", 0); X wclrtoeol(betwin); X wrefresh(betwin); X X for (ptr = payoffs; ptr && !match(ptr); ptr = ptr->next); X X wprintw(textwin, "%s %s%s - ", curnode[0]->name, X curnode[1]->name, curnode[2]->name); X X if (ptr) { X wprintw(textwin, "pays %d:1!\n", ptr->pay); X wrefresh(textwin); X return (bet * ptr->pay); X } X else { X wprintw(textwin, "does not pay\n"); X wrefresh(textwin); X return (-bet); X } X} X X X/* Predicate: do all three curnode[] pointers match the given X * payoff pointer? X */ X Xint match(ptr) Xstruct payoff *ptr; X{ X int i, matched = TRUE; X X for (i = 0; (i < 3) && matched; ++i) X matched = matched && X ((!strcmp(ptr->parts[i], MATCHANY)) || X (!strcmp(ptr->parts[i], curnode[i]->name))); X return (matched); X} X X X#ifdef DEBUG Xreport(str) Xchar *str; X{ X fprintf(stderr, "* %s\n", str); X} X X#endif END_OF_FILE if test 12059 -ne `wc -c <'yid-slots.c'`; then echo shar: \"'yid-slots.c'\" unpacked with wrong size! fi # end of 'yid-slots.c' fi if test -f 'yid-slots.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'yid-slots.h'\" else echo shar: Extracting \"'yid-slots.h'\" \(1150 characters\) sed "s/^X//" >'yid-slots.h' <<'END_OF_FILE' X/* Header file for yid-slots.c X * (c) 1987 by Bob Glickstein X * See the file README for information regarding the legal status of this X * software. X */ X X#ifndef TRUE X# define TRUE 1 X# define FALSE 0 X#endif X X#ifdef DEBUG X# define D(x) x X#else X# define D(x) X#endif X X#define BUFLEN 20 X#define DELIM ('*') X X#ifndef FDEFAULT X#define FDEFAULT ("/usr/games/yid-names") X#endif X X#define MATCHANY ("?") /* Wildcard character */ X#define MAXSPIN (60) X#define INIT_BANKROLL (100) X#define WINDOWHEIGHT (5) /* Five names show in a spinning window at X * any one time */ X#define WINDOWWIDTH (22) X#define WINDOW_Y_START (2) /* top y-coord of name windows */ X#define AUX_WINHEIGHT (5) X#define TEXTWIDTH (60) X#define BETWIDTH (15) X Xstruct namenode { X char *name; X struct namenode *next; X}; X Xstruct payoff { X char *parts[3]; /* One string to match each of three parts of X * an outcome */ X int pay; /* How much to pay if it comes up */ X struct payoff *next; X}; END_OF_FILE if test 1150 -ne `wc -c <'yid-slots.h'`; then echo shar: \"'yid-slots.h'\" unpacked with wrong size! fi # end of 'yid-slots.h' fi echo shar: End of shell archive. exit 0