DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T y

⟦5339d79c2⟧ TextFile

    Length: 12059 (0x2f1b)
    Types: TextFile
    Names: »yid-slots.c«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/YidSlots/yid-slots.c« 

TextFile

/* Yid Slots
 * (c) 1987 by Bob Glickstein
 *
 * See the README file for information regarding the legal status of
 * this software.
 *
 * Program simulates a slot machine in which the first of three windows
 * contains typical Jewish first names; the second window
 * conatins typical Jewish last-name-prefixes; and the third window
 * contains typical Jewish last-name-suffixes.  A file is read in
 * to determine the set of name-parts.  The file contains payoffs for
 * certain combinations.  In the default file, the biggest
 * payoff is for the combination "Bob Glick stein".
 */

/* FORMAT OF DATA FILE CONTAINING NAMES PARTS AND PAYOFFS:
 * <list-of-first-names-each-separated-by-white-space>
 * <nl>*<nl>       (That is, an asterisk alone on a line)
 * <list-of-last-name-prefixes-each-separated-by-white-space>
 * <nl>*<nl>
 * <list-of-last-name-suffixes-each-separated-by-white-space>
 * <nl>*<nl>
 * <a-first-name> <a-prefix> <a-suffix> <a-payoff-number><nl>
 * (this last line can be repeated as many times as you like, for as
 * many payoffs as you'd like to have.  The payoff-number is the number
 * of credits to return for every credit that was bet.  A "?" in any of the
 * first name, prefix, or suffix positions matches anything.
 *
 * RESTRICTIONS: No single string in the data file may be >= 20 chars
 * in length.
 */




#include  <stdio.h>
#include  <curses.h>
#include  "yid-slots.h"


struct namenode *names[3];     /* names[0] points to a linked list of first
                                * names; names[1] to a linked list of
                                * prefixes; names[2] to suffixes */

struct namenode *curnode[3];   /* These pointers hold our current position
                                * within the lists pointed to by names. (By
                                * current position, I mean the nodes
                                * appearing in the CENTER of the window.
                                * These pointers trail behind the printnode
                                * pointers.) */

struct namenode *printnode[3]; /* Points to the nodes being printed in the
                                * windows.  When the wheels stop spinning,
                                * these pointers point to nodes in the
                                * BOTTOMS of the windows.  Curnode points to
                                * nodes in the CENTERS of the windows (these
                                * are the nodes that win). */

struct payoff  *payoffs;       /* A linked list of payoffs */

WINDOW         *betwin, *textwin, *namewins[3];        /* betwin displays
current
                                                * money & current bet;
                                                * textwin is a dialogue
                                                * window; namewins are the
                                                * three slot machine windows */
WINDOW         *boxwin;                /* boxwin displays a box around name
windows */

int             bankroll;      /* Amount of money player has */

main(argc, argv)
int             argc;
char           *argv[];

{
    char           *fname;

    if (argc == 2)
       fname = argv[1];
    else {
       if (argc == 1)
           fname = FDEFAULT;
       else {
           fprintf(stderr, "Usage: %s [yidnamefile]\n", argv[0]);
           exit(1);
       }
    }

    initglobals();

    if (readnamefile(fname)) { /* if file successfully read */
       initdisplay();
       signon();
       play();
       signoff();
       cleanup();
    }
    else {
       cleanup();
       fprintf(stderr, "%s: error reading file %s\n", argv[0], fname);
       exit(1);
    }
}


/* advance - given an index into names[], and a pointer to the current
 * position, advance returns the next position in the linked list
 * names[i], wrapping around to the head of the list at the end
 */

struct namenode *advance(i, ptr)
int             i;
struct namenode *ptr;
{
    return ((ptr->next) ? ptr->next : names[i]);
}


/* My own random-number generator, generates a random number between 0 and
 * n-1 (the argument).  Call this fn. with an arg. of 0 to seed the generator
 * randomly (will return 0).
 */

long            bgrandom(n)
long            n;
{
    long            time(), random();

    if (!n)
       srandom((int) (time(NULL) & 0377));
    else
       return (random() % n);
}


initglobals()
{
    bgrandom((long) 0);

    names[0] = names[1] = names[2] = NULL;
    payoffs = NULL;
    curnode[0] = curnode[1] = curnode[2] = NULL;
    printnode[0] = printnode[1] = printnode[2] = NULL;

    initscr();

    namewins[0] = newwin(WINDOWHEIGHT, WINDOWWIDTH,
                        WINDOW_Y_START, 1);
    namewins[1] = newwin(WINDOWHEIGHT, WINDOWWIDTH,
                        WINDOW_Y_START, 3 + WINDOWWIDTH);
    namewins[2] = newwin(WINDOWHEIGHT, WINDOWWIDTH,
                        WINDOW_Y_START, 5 + 2 * WINDOWWIDTH);

    boxwin = newwin(WINDOWHEIGHT + 2, 7 + 3 * WINDOWWIDTH,
                   WINDOW_Y_START - 1, 0);

    textwin = newwin(AUX_WINHEIGHT, TEXTWIDTH,
                    WINDOWHEIGHT + WINDOW_Y_START + 2, 0);
    betwin = newwin(AUX_WINHEIGHT, BETWIDTH,
                   WINDOWHEIGHT + WINDOW_Y_START + 2, TEXTWIDTH + 2);

    scrollok(namewins[0], TRUE);
    scrollok(namewins[1], TRUE);
    scrollok(namewins[2], TRUE);
    scrollok(textwin, TRUE);

    bankroll = INIT_BANKROLL;
}


/* initdisplay() does things like erase the windows, draw the boxes,
 * fill in non-changing text (like the templates "Amount in wallet:"
 * and "Amount of bet:" in the betwindow
 * MOST IMPORTANTLY, this routine fills up the three windows with the first
 * few name parts and sets all of the pointers correctly (curnode,
 * printnode).
 */

/* WARNING: contains lots of hardwired numbers
 */

initdisplay()
{
    int             i, j;

    werase(textwin);
    werase(betwin);
    wprintw(betwin, "You have:\n %d\nAmt. of bet:\n %d", bankroll, 0);
    wrefresh(textwin);
    wrefresh(betwin);

    werase(boxwin);
    box(boxwin, '.', '.');
    for (j = 1; j <= 5; ++j) {
       wmove(boxwin, j, 23);
       waddstr(boxwin, "..");
       wmove(boxwin, j, 47);
       waddstr(boxwin, "..");
    }

    wmove(boxwin, 3, 0);
    waddch(boxwin, '-');
    wmove(boxwin, 3, 23);
    waddstr(boxwin, "--");
    wmove(boxwin, 3, 47);
    waddstr(boxwin, "--");
    wmove(boxwin, 3, 72);
    waddch(boxwin, '-');
    wrefresh(boxwin);

    for (i = 0; i < 3; ++i) {
       werase(namewins[i]);
       printnode[i] = names[i];
       wprintw(namewins[i], "%s", printnode[i]->name);
    }
    for (i = 0; i < 3; ++i) {
       printnode[i] = advance(i, printnode[i]);
       wprintw(namewins[i], "\n%s", printnode[i]->name);
    }
    for (i = 0; i < 3; ++i) {
       curnode[i] = printnode[i] = advance(i, printnode[i]);
       wprintw(namewins[i], "\n%s", printnode[i]->name);
    }
    for (j = 1; j <= 2; ++j)
       for (i = 0; i < 3; ++i) {
           printnode[i] = advance(i, printnode[i]);
           wprintw(namewins[i], "\n%s", printnode[i]->name);
       }
    for (i = 0; i < 3; ++i) {
       overwrite(namewins[i], boxwin);
       wrefresh(namewins[i]);
    }
}


cleanup()
{
    endwin();
}


int             readnamefile(fname)    /* Attempts to load names in from a
                                        * hopefully correct-format namefile */
char           *fname;
{
    FILE           *fp;
    int             i, tpay;
    char            buffer[3][BUFLEN], *malloc();
    struct namenode *tnode;
    struct payoff  *tpayoff;

    if (!(fp = fopen(fname, "r")))
       return (FALSE);         /* No Good */

    for (i = 0; i < 3; ++i) {
       do {
           fscanf(fp, "%s", buffer[0]);
           if (buffer[0][0] != DELIM) {
               tnode = (struct namenode *) malloc(sizeof(struct namenode));
               tnode->name = malloc(1 + strlen(buffer[0]));

               /*
                * WARNING: These malloc's are not checked for failure
                */
               strcpy(tnode->name, buffer[0]);
               tnode->next = names[i];
               names[i] = tnode;       /* Links it into the list */
           }
       } while (buffer[0][0] != DELIM);
    }
    while (fscanf(fp, "%s %s %s %d", buffer[0], buffer[1], buffer[2], &tpay)
== 4) {
       tpayoff = (struct payoff *) malloc(sizeof(struct payoff));
       for (i = 0; i < 3; ++i) {
           tpayoff->parts[i] = malloc(1 + strlen(buffer[i]));
           strcpy(tpayoff->parts[i], buffer[i]);
       }
       tpayoff->pay = tpay;
       tpayoff->next = payoffs;
       payoffs = tpayoff;      /* Links it into the list */
    }
    return (TRUE);
}


signon()
{
    wprintw(textwin,
           "Welcome to Yid Slots\n(c) 1987 by Bob Glickstein\n");
    wrefresh(textwin);
}


signoff()
{
    wprintw(textwin, "Thank you for playing Yid Slots\n");
    wrefresh(textwin);
}


/* Main loop of program */
play()
{
    int             bet;

    while (bankroll > 0) {
       if (!(bet = placebet()))
           return;             /* A bet of zero ends the game */

       spin();
       bankroll += settle(bet);/* settle() returns -bet if no winning
                                * combinations came up; otherwise, it
                                * returns the number of credits by which to
                                * augment bankroll */
       wmove(betwin, 1, 1);
       wprintw(betwin, "%d", bankroll);
       wclrtoeol(betwin);
       wrefresh(betwin);
    }
}


/* Dialogue & input of bet amount */

int             placebet()
{
    int             again = TRUE, bet;

    wprintw(textwin, "Place your bet (0 ends the game)\n  ");
    wrefresh(textwin);
    while (again) {
       wscanw(textwin, "%d", &bet);
       wrefresh(textwin);
       if ((bet < 0) || (bet > bankroll)) {
           wprintw(textwin, "Bet must be non-negative and affordable\n");
           wrefresh(textwin);
           again = TRUE;
       }
       else
           again = FALSE;
    }
    wmove(betwin, 3, 1);
    wprintw(betwin, "%d", bet);
    wclrtoeol(betwin);
    wrefresh(betwin);
    return (bet);
}


/* Set the wheels a-spin, stopping them one at a time after
 * a random interval (maximum MAXSPIN ticks per wheel)
 */

spin()
{
    int             counter;
    long            r;

    for (counter = 0; counter < 3; ++counter)
       for (r = MAXSPIN; r && bgrandom(r); --r)
           spinwheels(counter);
}


/* Advance wheels counter through 2 one tick each */

spinwheels(counter)
int             counter;
{
    int             i;

    for (i = counter; i < 3; ++i) {
       printnode[i] = advance(i, printnode[i]);
       curnode[i] = advance(i, curnode[i]);
       wprintw(namewins[i], "\n%s", printnode[i]->name);
       wrefresh(namewins[i]);
    }
}


/* Examine what came up on the wheels.  Compare against
 * winning combinations in the payoffs linked list.  If there
 * is a match, return the payoff times the bet placed.  If
 * not, return -bet
 */

int             settle(bet)
int             bet;
{
    struct payoff  *ptr;

    wmove(betwin, 3, 1);
    wprintw(betwin, "%d", 0);
    wclrtoeol(betwin);
    wrefresh(betwin);

    for (ptr = payoffs; ptr && !match(ptr); ptr = ptr->next);

    wprintw(textwin, "%s %s%s - ", curnode[0]->name,
           curnode[1]->name, curnode[2]->name);

    if (ptr) {
       wprintw(textwin, "pays %d:1!\n", ptr->pay);
       wrefresh(textwin);
       return (bet * ptr->pay);
    }
    else {
       wprintw(textwin, "does not pay\n");
       wrefresh(textwin);
       return (-bet);
    }
}


/* Predicate: do all three curnode[] pointers match the given
 * payoff pointer?
 */

int             match(ptr)
struct payoff  *ptr;
{
    int             i, matched = TRUE;

    for (i = 0; (i < 3) && matched; ++i)
       matched = matched &&
           ((!strcmp(ptr->parts[i], MATCHANY)) ||
            (!strcmp(ptr->parts[i], curnode[i]->name)));
    return (matched);
}


#ifdef  DEBUG
report(str)
char           *str;
{
    fprintf(stderr, "* %s\n", str);
}

#endif