[comp.sources.games] v05i063: yid-slots - a Jewish Name slot machine

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