[comp.sources.games] v11i065: ac_bj - Atlantic City blackjack, Part01/01

billr@saab.CNA.TEK.COM (Bill Randle) (11/20/90)

Submitted-by: charles spell <cs00chs@unccvax.uncc.edu>
Posting-number: Volume 11, Issue 65
Archive-name: ac_bj/Part01
Environment: Sys V curses


#! /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 archive 1 (of 1)."
# Contents:  README ac_bj.6 ac_bj.c
# Wrapped by billr@saab on Mon Nov 19 12:48:34 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(625 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XHere is an Atlantic city blackjack game I hacked together one weekend before
Xgoing to Atlantic City. To compile (requires System V curses):
X
X     cc ac_bj.c -o ac_bj -lcurses
X
XA small contribution will be appreciated...I will send out fixes/enhancements
Xif there is enough monetary interest...
X
XIf you enjoy or find the program (in part or whole) useful, please send
Xa contribution to:
X   John J. Ribera, Jr.
X   9505-J University Terrace Dr.
X   Charlotte, NC 28262
X   Voice: (704) 549-5571
XPlease send suggestions, comments, complaints, ideas, etc... to the author
Xat the address above or e-mail : uunet!mcnc!unccvax!cs00chs
END_OF_FILE
if test 625 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'ac_bj.6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ac_bj.6'\"
else
echo shar: Extracting \"'ac_bj.6'\" \(2184 characters\)
sed "s/^X//" >'ac_bj.6' <<'END_OF_FILE'
X.TH ac_bj 6
X.SH NAME
Xac_bj - a blackjack program
X.SH SYNOPSIS
X.B ac_bj
X.SH DESCRIPTION
XThis is an eight-deck Atlantic City blackjack game for system V. Splits and
Xdouble downs are supported. No insurance. Use the Spacebar to Hit and CR to
Xstand if desired. A redeal will occur when half of the all decks are used.
Xbj uses terminfo GRAPHICS capablities - iff they are activated.
X
X.SH NOTE
XThe program looks much nicer if you have the smacs=, rmacs= and acsc=
Xcapabilities in your terminfo database...but it will still work
Xwithout them...
X
XHow to add graphics capabilities for vt100, vt101 and vt102 emulators:
XType the following commands (re-start here if anything goes wrong):
X.nf
X.na
Xcsh> setenv TERM vt100      # vt100 is an example-use TERM name youre that
Xcsh> mkdir ~/term           #   emulates a vt10[012] (in terminfo database)
Xcsh> infocmp > ~/term/info  # this will create a terminfo source file.
Xcsh> setenv TERMINFO ~/term # Tell curses to use the database in ~/term
Xcsh> tic ~/term/info        # Ignore warnings (if any)...
XEdit the ~/term/info file and add the following line to the proper entry:
X -go to the entry that emulates vt100 (eg. vt100,vt101, vt102)
X -add the following line to it...
X smacs=\E(0\E)0, rmacs=\E(B\E)B, acsc=jjkkllmmnnqqssttuuvvww++\,\,,
X -save it and type the following command:
Xcsh> tic ~/term/info
X.ad
X.fi
X.LP
XFor non vt100 emulators you must read your terminal reference manual and
Xterminfo(5) to set it up properly. Some old terminals do not have a text
Xgraphics mode - i.e. you cannot see the pretty graphics.
X.SH BUGS
XThere are a few bugs. These will be fixed on the next version iff there is
Xenough mmonetary interest. The dealer continues to deal to himself even
Xafter the outcome of a score is certain. No insurance. After the first
Xshuffle, the WIN-LOSE is not displayed properly.
X.SH AUTHOR
X(E-mail: uunet!mcnc!unccvax!cs00chs)
XJohn J. Ribera, Jr.
X9505-J University Terrace Dr.
XCharlotte, NC 28262
XVoice: (704) 549-5571
X.LP
XIf you find this program or any part of it useful please send a
Xcontribution to the above address. This will allow you to receive
Xthe most recent fixes and versions. Make checks payable to
XJohn J. Ribera, Jr.
END_OF_FILE
if test 2184 -ne `wc -c <'ac_bj.6'`; then
    echo shar: \"'ac_bj.6'\" unpacked with wrong size!
fi
# end of 'ac_bj.6'
fi
if test -f 'ac_bj.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ac_bj.c'\"
else
echo shar: Extracting \"'ac_bj.c'\" \(19633 characters\)
sed "s/^X//" >'ac_bj.c' <<'END_OF_FILE'
X#include <curses.h>
X#include <ctype.h>
X#include <signal.h>
X/*****************************************************************************
X* You may freely distribute this file as long as the contents of this file
X* have not been altered in any way or form. If you decide that you would like
X* to re-distribute a change, please send to me for testing first - this keeps
X* one current and tested version out there...
X*
X* Please send suggestions, comments, complaints, ideas, etc...to the author
X* at e-mail address: uunet!mcnc!unccvax!cs00chs (cs00chs@unccvax.uncc.edu)
X* A small contribution will be appreciated and will ensure future updates
X* and hints. Remember, if you practice card counting and basic strategy,
X* you have a mathematical advantage over the house (in real life too).
X*/
X
X/*****************************************************************************
X* NAME                                                                  Aug 89
X*   bj - a blackjack program (version 1.0)
X*
X* SYNOPSIS
X*   bj 
X*
X* DESCRIPTION
X*  This is an eight-deck Atlantic City blackjack game for system V. Splits and
X*  double downs are supported. No insurance. Use the Spacebar to Hit and CR to
X*  stand if desired. A redeal will occur when half of the all decks are used.
X*  bj uses terminfo GRAPHICS capablities - iff they are activated.
X*
X*  Card-counting: Starting with the beginning of each deck, keep a running
X*                 count (initially 0):
X*                 ACE,KING,QUEEN,JACK,10 == -1
X*                 9, 8, 7                ==  0  (ignore)
X*                 6,5,4,3,2              == +1
X*                 When count is high (positive) bet high, if low bet minimum.
X*  Basic Strategy:    Dealer Showing      Insurance should never be taken
X*           Player -2-3-4-5-6-7-8-9-X-A-  unless counting is being used!
X*           2-8            H i t
X*           09      H D D D D H H H H H
X*           10      D D D D D D D D H H
X*           11      D D D D D D D D D H
X*           12      H H S S S H H H H H
X*           13-16   S S S S S H H H H H
X*           17            S t a n d
X*           A,2|3   H H H D D H H H H H
X*           A,4|5   H H D D D H H H H H
X*           A,6     H D D D D H H H H H
X*           A,7     S D D D D S S H H H
X*           A,8|9|X      S t a n d
X*
X* NOTE
X*  The program looks much nicer if you have the smacs=, rmacs= and acsc=
X*  capabilities in your terminfo database...but it will still work
X*  without them...
X*
X*  How to add graphics capabilities for vt100, vt101 and vt102 emulators:
X*  Type the following commands (re-start here if anything goes wrong):
X*  csh> setenv TERM vt100      # vt100 is an example-use TERM name youre that
X*  csh> mkdir ~/term           #   emulates a vt10[012] (in terminfo database)
X*  csh> infocmp > ~/term/info  # this will create a terminfo source file.
X*  csh> setenv TERMINFO ~/term # Tell curses to use the database in ~/term
X*  csh> tic ~/term/info        # Ignore warnings (if any)...
X*  Edit the ~/term/info file and add the following line to the proper entry:
X*    -go to the entry that emulates vt100 (eg. vt100,vt101, vt102)
X*    -add the following line to it...
X*    smacs=\E(0\E)0, rmacs=\E(B\E)B, acsc=jjkkllmmnnqqssttuuvvww++\,\,,
X*    -save it and type the following command:
X*  csh> tic ~/term/info
X*
X*  For non vt100 emulators you must read your terminal reference manual and
X*  terminfo(5) to set it up properly. Some old terminals do not have a text
X*  graphics mode - i.e. you cannot see the pretty graphics.
X*
X* BUGS
X*  There are a few bugs. These will be fixed on the next version iff there is
X*  enough interest. The dealer continues to deal to himself even after the
X*  outcome of a score is certain. No insurance. After the first shuffle, the
X*  WIN-LOSE is not displayed properly.
X*
X* AUTHOR
X*   clt2!jjr   (can be reached via: uunet!mcnc!unccvax!cs00chs)
X*   John J. Ribera, Jr.
X*   9505-J University Terrace Drive
X*   Charlotte, NC 28262
X*
X*   A small contribution will be appreciated and will ensure bug fixes and
X*   hints. Copyright (C) 1990.
X*/
X
X/* flags for get_str() and get_chr()... */
X#define CLR_FLD     0x0001
X#define INIT_ONKEY  0x0010
X#define MAP_UPPER   0x0002
X#define MAP_LOWER   0x0004
X#define AUTO_RET    0x0008
X#define NOPAD       0x0020
X#define NOECHO      0x0040
X#define BEEP        0x0080
X
X/* keystroke defines for readablity.... */
X#define ESC         0x1b
X#define CR          '\r'
X#define NL          '\n'
X#define BS          '\b'
X
X#define MAX_HANDS   3
X#define DECKS       8
X#define DEALER      0
X#define DOWN        0
X#define UP          1
X#define WIN         0x0001
X#define LOSE        0x0002
X#define PUSH        0x0004
X#define BJ          0x0008
X#define GETCNT(i)   (short) abs((int) (getcnt(i)))
Xtypedef struct
X    {
X    short   amt;
X    short   bet;
X    short   cnt;
X    short   cards[13];
X    char    name[9+1];
X    WINDOW  *win;
X    } HAND;
X
XHAND    Hand[MAX_HANDS];
Xshort   Hands = 2;
Xshort   *Cards;
Xshort   Cur_card;
Xshort   get_str(), get_chr(), nextcard();
Xvoid    getcard(), dispbet(), dispcard();
Xvoid    inithand(), disphand();
Xvoid    promptfor();
Xmain()
X{
X    short   i, n, pcnt, dcnt;
X    short   decks, cmp;
X    short   *shuffle();
X    short   getcnt(), bj(), getbet();
X    char    *cardtype();
X    char    *ptr;
X    void    done();
X
Xsignal(SIGINT, done);
Xinitscr();
Xnoecho();
Xcrmode();
X
Xfor (n = 0; n < MAX_HANDS; n++)
X    inithand(n);
X
Xsrand(time((long *) 0));
Xwhile (TRUE)
X    {
X    clearok(stdscr, TRUE);
X    refresh();
X    for (i = 0; i < Hands; i++)
X        disphand(i);
X    wstandout(Hand[DEALER].win);
X    mvwprintw(Hand[DEALER].win, 0, 1, " B L A C K J A C K ");
X    wstandend(Hand[DEALER].win);
X    wprintw(Hand[DEALER].win, " by clt2!jjr... (press DEL to quit)");
X    mvwprintw(Hand[DEALER].win, 5, 1, "Shuffle...");
X    wrefresh(Hand[DEALER].win);
X    sleep(2);
X    Cards = shuffle((decks = DECKS));
X    Cur_card = 0;
X    while (Cur_card < decks * 52 / 2)
X        {
X        for (i = 1;Hands > 2; Hands--, i++)
X            werase(Hand[i+1].win), wrefresh(Hand[i+1].win);
X        Hands = 2;
X        for (n = 1; n < Hands; n++)
X            {
X            if (!getbet(n))
X                done();
X            Hand[n].cnt = 0;
X            disphand(n);
X            }
X        Hand[DEALER].cnt = 0;
X        disphand(DEALER);
X        getcard(1); getcard(DEALER);
X        getcard(1); getcard(DEALER);
X        getcard(1);
X        if (Hands > 2)
X            {
X            getcard(2);
X            getcard(2);
X            }
X        getcard(DEALER);
X        for (dcnt = GETCNT(DEALER), i = 1;  i < Hands; i++)
X            {
X            if ((pcnt = GETCNT(i)) > 21 || dcnt > 21)
X                cmp = (pcnt > 21) ? LOSE : WIN;
X            else if (pcnt == dcnt)
X                cmp = (bj(i)) ? BJ : PUSH;
X            else
X                cmp = (pcnt > dcnt) ? (bj(i) ? BJ : WIN) : LOSE;
X            switch (cmp)
X                {
X            case WIN:
X                Hand[i].amt += Hand[i].bet;
X                Hand[DEALER].amt -= Hand[i].bet;
X                ptr = " WIN ";
X                break;
X            case BJ:
X                Hand[i].amt += Hand[i].bet + (Hand[i].bet / 2);
X                Hand[DEALER].amt -= (Hand[i].bet + Hand[i].bet / 2);
X                ptr = " WIN ";
X                break;
X            case PUSH:
X                ptr = " PUSH ";
X                break;
X            case LOSE:
X                Hand[DEALER].amt += Hand[i].bet;
X                Hand[i].amt -= Hand[i].bet;
X                ptr = " LOSE ";
X                break;
X                }
X            dispbet(i);
X            dispbet(DEALER);
X            wrefresh(Hand[i].win); wrefresh(Hand[0].win);
X            wstandout(Hand[i].win); mvwprintw(Hand[i].win, 2, 20, ptr);
X            wstandend(Hand[i].win); wrefresh(Hand[i].win);
X            }
X        }
X    promptfor("New deck...press return to continue...", ptr, 1, "", CLR_FLD);
X    }
X}
Xvoid
Xinithand(n)
Xshort   n;
X{
X
XHand[n].win = newwin((n == DEALER) ? 7 : 5,0,(n == DEALER) ? 0 : n * 5 + 2, 0);
XHand[n].amt = (DEALER == n ) ? 0 : 1000;
XHand[n].bet = 0L;
XHand[n].cnt = 0;
Xstrcpy(Hand[n].name, getlogin());
Xstrcpy(Hand[DEALER].name, "Dealer");
X}
X/*******************************************************************************
X* shuffle will return a static pointer to an array of random shorts with a range
X* of 0 to 52 * 'decks'. If 'decks' is > 10, then 10 decks will be returned.
X* If 'decks' is < 1 then one shuffled deck will be returned.
X*/
Xshort   *
Xshuffle(decks)
Xshort   decks;
X{
Xstatic  short   deck[52 * 10 + 1];
X        short   mark[52 * 10 + 1];
X        short   card;
X        short   cnt = 0;
X
Xmemset(mark, '\0', sizeof(mark));
Xmemset(deck, '\0', sizeof(deck));
X
Xdecks = (decks < 1) ? 1 : ((decks > 10) ? 10 : decks);
Xwhile (cnt < 52 * decks)
X    if ((card = (short) rand() % (52 * decks)) >= 0 && !mark[card])
X        deck[cnt++] = card, mark[card] = 1;
Xdeck[cnt] = -1;
Xreturn(deck);
X}
X/******************************************************************************
X* cardtype will return a 3 character string that specifies which card 'card'
X* represents. Character [1] of the returned string specifies the cardinality
X* of 'card' and character [2] specifies the suit of 'card'.
X*/
Xchar *
Xcardtype(card)
Xshort   card;
X{
Xstatic  char    value[27] = " A 2 3 4 5 6 7 8 910 J Q K";
Xstatic  char    suit[5] = "SHCD";
Xstatic  char    type[4];
X
Xstrncpy(type, &value[((card % 52) / 4) << 1], 2);
Xtype[2] = suit[card & 3];
Xtype[3] = 0;
Xreturn(type);
X}
X
Xint
Xboxit(win, rows, cols, brow, bcol)
XWINDOW  *win;
Xshort   rows;
Xshort   cols;
Xshort   brow;
Xshort   bcol;
X{
X    short   i;
X
Xwrefresh(win);
Xwattron(win, A_ALTCHARSET);
Xmvwaddch(win, brow, bcol, ACS_ULCORNER);
Xmvwaddch(win, brow+rows-1, bcol, ACS_LLCORNER);
Xfor (i=bcol+1; i < bcol+cols-1; i++)
X    {
X    mvwaddch(win, brow, i, ACS_HLINE);
X    mvwaddch(win, brow+rows-1, i, ACS_HLINE);
X    }
Xmvwaddch(win, brow, i, ACS_URCORNER);
Xmvwaddch(win, brow+rows-1, i, ACS_LRCORNER);
Xfor (i=brow+1; i < rows-1; i++)
X    {
X    mvwaddch(win, i, bcol, ACS_VLINE);
X    mvwprintw(win, i, bcol+1, "%*.*s", cols-2, cols-2, "");
X    mvwaddch(win, i, bcol+cols-1, ACS_VLINE);
X    }
Xwrefresh(win);
Xwattroff(win, A_ALTCHARSET);
X}
X
Xvoid
Xgetcard(hand)
Xshort   hand;
X{
X    char    c, getact();
X    char    *sel, *cardtype();
X    char    ctype1[5], ctype2[5];
X
Xif (Hand[hand].cnt < 2)
X    {
X    Hand[hand].cards[Hand[hand].cnt++] = nextcard();
X    dispcard(hand, Hand[hand].cnt-1, (hand==DEALER&&Hand[0].cnt==2)?DOWN:UP);
X    return;
X    }
Xif (hand == DEALER)
X    {
X    dispcard(DEALER, 1, UP);
X    while (GETCNT(DEALER) < 17 || getcnt(DEALER) < 0 && GETCNT(DEALER) == 17)
X        {
X        Hand[DEALER].cards[Hand[DEALER].cnt++] = nextcard();
X        dispcard(DEALER, Hand[DEALER].cnt-1, UP);
X        }
X    return;
X    }
Xif (GETCNT(hand) == 21)
X    return;
Xstrcpy(ctype1, cardtype(Hand[hand].cards[0]));
Xstrcpy(ctype2, cardtype(Hand[hand].cards[1]));
Xsel = (Hands < MAX_HANDS && ctype1[1]==ctype2[1]) ? "HSDP0123 " : "HSD123 ";
Xif ((c = getact(hand, sel)) == 'S')
X    return;
Xif (c == 'P')
X    {
X    Hands++;
X    Hand[hand].cnt--;
X    Hand[hand+1].bet = Hand[hand].bet;
X    Hand[hand+1].cards[0] = Hand[hand].cards[1];
X    Hand[hand+1].cnt = 1;
X    Hand[hand+1].bet = Hand[hand].bet;
X    Hand[hand+1].amt = 0L;
X    dispbet(hand);
X    disphand(hand + 1);
X    dispcard(hand + 1, 0, UP);
X    }
XHand[hand].cards[Hand[hand].cnt++] = nextcard();
Xdispcard(hand, Hand[hand].cnt-1, UP);
X/*
Xif (GETCNT(hand) >= 21)
X    return;
X*/
Xif (c == 'P')
X    {
X    if (getact(hand, "^HSD123 ") == 'S')
X        return;
X    Hand[hand].cards[Hand[hand].cnt++] = nextcard();
X    dispcard(hand, Hand[hand].cnt-1, UP);
X    }
Xif (c == 'D')
X    {
X    Hand[hand].bet *= 2;
X    dispbet(hand);
X    dispbet(DEALER);
X    return;
X    }
X
Xwhile (GETCNT(hand) < 21)
X    {
X    if ((c=getact(hand, "^HS12 ")) == 'S')
X        return;
X    Hand[hand].cards[Hand[hand].cnt++] = nextcard();
X    dispcard(hand, Hand[hand].cnt-1, UP);
X    }
Xreturn;
X}
X
Xshort
Xgetcnt(hand)
Xshort   hand;
X{
X    char    *type;
X    char    *strchr();
X    short   cnt, acecnt;
X    short   i;
X
Xfor (i = 0, cnt = acecnt = 0; i < Hand[hand].cnt; i++)
X    {
X    type = cardtype(Hand[hand].cards[i]);
X    if (strchr("KQJ0", type[1]))
X        cnt += 10;
X    else if (strchr("23456789", type[1]))
X        cnt += type[1] - '0';
X    else
X        cnt += 11, acecnt++;
X    }
Xwhile (acecnt--)
X    if (cnt > 21)
X        cnt -= 10;
Xreturn(acecnt>0 ? -cnt : cnt);
X}
X
Xchar
Xgetact(hand, valact)
Xshort   hand;
Xchar    *valact;
X{
X    char    prompt[80];
X    char    choice[2];
X    char    sel[5];
X
Xstrcpy(sel, "PHSD");
Xsprintf(prompt, "Enter choice %s (Hit, Stand", Hand[hand].name);
Xif (strchr(valact, 'D'))
X    strcat(prompt, ", Double");
Xif (strchr(valact, 'P'))
X    strcat(prompt, ", sPlit");
Xstrcat(prompt, "): ");
Xstrcpy(choice, "S");
Xpromptfor(prompt, choice, 1, valact, MAP_UPPER|AUTO_RET);
Xif (strchr("0123", choice[0]))
X    choice[0] = sel[choice[0] - '0'];
Xreturn(choice[0]);
X}
X
Xshort
Xgetbet(hand)
Xshort   hand;
X{
X    char    prompt[80];
X    char    bet[9];
X    int     atoi();
X
Xif (Hand[hand].bet > 500)
X    Hand[hand].bet = 500;
Xsprintf(prompt, "Enter bet %s: ($2 - $500, 0 to quit) ", Hand[hand].name);
Xdo
X    {
X    sprintf(bet, "%hd", Hand[hand].bet);
X    promptfor(prompt, bet, 5, "0123456789", INIT_ONKEY);
X    Hand[hand].bet = (long)atoi(bet);
X    if (!Hand[hand].bet)
X        return((short) 0);
X    } while (Hand[hand].bet % 2 || Hand[hand].bet > 500);
Xdispbet(hand);
Xreturn(Hand[hand].bet);
X}
X
Xvoid
Xdispbet(hand)
Xshort   hand;
X{
X    short   i;
X
Xif (hand == DEALER)
X    for (i = 1, Hand[DEALER].bet = 0; i < Hands; i++)
X        Hand[DEALER].bet += Hand[i].bet;
X
Xmvwprintw(Hand[hand].win,2,1,"stakes    : %5hd", Hand[hand].bet);
Xmvwprintw(Hand[hand].win,3,1,"credit    : %+5hd", Hand[hand].amt);
Xwrefresh(Hand[hand].win);
X}
X
Xvoid
Xdispcard(hand, card, up)
Xshort   hand;
Xshort   card;
Xshort   up;
X{
X    short   bcol;
X    short   bj();
X    char    c,type[5];
X
Xbcol = 40 + (card - 2) * 3;
Xwstandout(Hand[hand].win);
Xboxit(Hand[hand].win, (short) 5, (short) 5, (short) 0, (short) bcol);
Xif (up)
X    {
X    strcpy(type, cardtype(Hand[hand].cards[card]));
X    c = type[2]; type[2] = 0;
X    mvwprintw(Hand[hand].win, 1, bcol+1, &type[(type[0] == ' ') ? 1 : 0]);
X    mvwprintw(Hand[hand].win, 2, bcol+2, "%c", c);
X    mvwprintw(Hand[hand].win, 3, bcol+2, type);
X    wrefresh(Hand[hand].win);
X    wstandend(Hand[hand].win);
X    wrefresh(Hand[hand].win);
X    mvwprintw(Hand[hand].win, 1, 13, "%5hd", GETCNT(hand));
X    if (GETCNT(hand) > 21)
X        mvwprintw(Hand[hand].win, 1, 21, "BUST ");
X    if (bj(hand))
X        mvwprintw(Hand[hand].win, 1, 21, "BLACKJACK! ");
X    }
Xwstandend(Hand[hand].win);
X
Xwrefresh(Hand[hand].win);
X}
X
Xvoid
Xdisphand(hand)
Xshort   hand;
X{
X    short   i;
Xfor (i = 0; i < 5; i++)
X    wmove(Hand[hand].win, i, 1), wclrtoeol(Hand[hand].win);
Xmvwprintw(Hand[hand].win, 1, 1, "%-10.10s: ", Hand[hand].name);
Xif (hand < 2)
X    dispbet(hand);
Xwrefresh(Hand[hand].win);
X}
X
Xvoid
Xpromptfor(prompt, input, max, vchrs, flags)
Xchar    *prompt;
Xchar    *input;
Xshort   max;
Xlong    flags;
X{
X    char    *strchr();
Xwmove(Hand[DEALER].win, 5, 1);
Xwhile (*prompt)
X    if (strchr(vchrs, *prompt) && *prompt != ' ')
X        {
X        wstandout(Hand[DEALER].win);
X        waddch(Hand[DEALER].win, *prompt++);
X        wstandend(Hand[DEALER].win);
X        }
X    else
X        waddch(Hand[DEALER].win, *prompt++);
Xwaddch(Hand[DEALER].win, ' ');
X
Xget_str(Hand[DEALER].win, input, max, vchrs, flags);
Xwmove(Hand[DEALER].win, 5, 1); wclrtoeol(Hand[DEALER].win);
Xwrefresh(Hand[DEALER].win);
X}
X
Xshort
Xnextcard()
X{
Xreturn(Cards[Cur_card++]);
X}
X
Xshort
Xbj(hand)
Xshort   hand;
X{
Xif (GETCNT(hand) != 21)
X    return((short)0);
Xif (Hand[hand].cnt == 2)
X    return((short)1);
Xreturn((short)0);
X}
X/******************************************************************************
X* get a string through curses...how many times has this been re-written?
X* Returns:      key that caused get_str to return.
X* Side Effects: _str_ holds a space padded array of characters entered by user.
X*               _win_ will be changed by the contents of string
X* Note: wattron before call to get_str for pretty display of input box...
X*       noecho() should be enabled...
X*/
Xshort
Xget_str(win, str, max, vchrs, flags)
XWINDOW  *win;           /* input window */
Xchar    *str;           /* changed by side effect   */
Xshort   max;            /* stop when this is reached    */
Xchar    *vchrs;         /* valid keystrokes...  */
Xshort   flags;          /* all kinds of options...  */
X{
X
X    short   sr, sc;     /* save row save column -restored on ret*/
X    short   ofs =0;     /* current offset from beginning of str */
X    short   ret =0;     /* return status != when return desired */
X    short   c;          /* each input char is put into this var */
X    short   first=TRUE; /* first time through the main loop?    */
X    char    save[256];  /* max better be less than 256 chars    */
X
Xwrefresh(win);                          /* dump any changes */
Xgetyx(win, sr, sc);                     /* get logical cursor location*/
Xif (flags & CLR_FLD)                    /* initialize field from beginning? */
X    sprintf(str, "%*.*s", max, max, "");
Xstrcpy(save, str);                      /* save in case of an ESC...    */
Xsprintf(str, "%-*.*s", max, max, save); /* left justified...pad for now...  */
Xif (~flags & NOECHO)                    /* if we want to echo string... */
X    waddstr(win, str);
Xwmove(win, sr, sc+ofs);
Xwhile (!ret)
X    {
X    if (isprint((c = get_chr(win, vchrs, flags))))
X        {                               /* clear the input string on first  */
X        if (ofs == max)                 /* dont write over the terminating  */
X            ofs--;                      /* null character...                */
X        if (first && flags & INIT_ONKEY)/* clear on first printable char... */
X            sprintf(str, "%*.*s", max, max, "");
X        str[ofs++] = (char) c;
X        if (ofs == max)                 /* if at end of string already...   */
X            if (flags & AUTO_RET)       /*   and AUTO_RET flag ON then...   */
X                ret = CR;               /*     pretend CR was pressed...    */
X        }
X    else
X        switch (c)
X            {
X        case CR:
X        case NL:
X        case KEY_UP:
X        case KEY_DOWN:
X            ret = c;
X            break;
X        case ESC:
X            strcpy(str, save);
X            ret = c;
X            break;
X        case KEY_RIGHT:
X            if (ofs < max)
X                str[ofs++] = ' ';
X            break;
X        case KEY_LEFT:
X        case BS:
X            if (ofs)
X                ofs--;
X            break;
X        default:
X            ret = c;
X            }
X    if (~flags & NOECHO)                /* if NOECHO is OFF then disp str...*/
X        mvwaddstr(win, sr, sc, str);    /* (display after each character)   */
X    wmove(win, sr, sc+ofs);
X    wrefresh(win);
X    first = FALSE;                      /* we have been around the loop...  */
X    }
Xif (flags & NOPAD)
X    for (ofs = 0; ofs < max; ofs++)
X        if (str[ofs] == ' ')
X            c = ofs;
Xreturn(ret);
X}
X
Xshort
Xget_chr(win, vchrs, flags)
XWINDOW  *win;
Xchar    *vchrs;
Xshort   flags;
X{
X    short   c;
Xwrefresh(win);
Xwhile ((c = wgetch(win)) == ERR)
X    if (isprint(c) && strchr(vchrs, c))
X        break;
X    else if (flags & BEEP)
X        beep();
Xif (flags & MAP_UPPER)
X    if (c >= 'a' && c <= 'z')
X        c = toupper(c);
Xif (flags & MAP_LOWER)
X    if (c >= 'A' && c <= 'A')
X        c = tolower(c);
Xreturn(c);
X
X}
X
Xvoid
Xdone()
X{
Xmvprintw(19, 20, "Quit with %hd dollars",  Hand[1].amt);
Xmvprintw(20, 20, "Press any key to exit...");
Xrefresh();
Xgetch();
X
Xendwin();
Xexit(0);
X}
X
X
END_OF_FILE
if test 19633 -ne `wc -c <'ac_bj.c'`; then
    echo shar: \"'ac_bj.c'\" unpacked with wrong size!
fi
# end of 'ac_bj.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have the archive.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0