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 b

⟦ee4f9eab9⟧ TextFile

    Length: 10827 (0x2a4b)
    Types: TextFile
    Names: »bj.c«

Derivation

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

TextFile

/* bj.c */
/*
			B.J. - Las Vegas Blackjack, Version 1.0
			by Nathan Glasser
			nathan@brokaw.lcs.mit.edu (internet)
			nathan@mit-eddie.uucp (usenet)

			April, 1989
------------------------------------------------------------------------------
Copyright 1989 by Nathan Glasser.
You may feel free to distribute this program in its current form.
Please do not remove this copyright information.
*/

#include "bj.h"

CARDINFO cardinfo[] =
{ {1,'A'}, {2,'2'}, {3,'3'}, {4,'4'}, {5,'5'}, {6,'6'}, {7,'7'},
  {8,'8'}, {9,'9'}, {10,'T'}, {10,'J'}, {10,'Q'}, {10,'K'}};

#define ACE 0

CARD *deck;
CARD *cardptr;

double bet;
double last_bet;

char inpstring[80];


/* Options */
double money = 100.0,
       table_min = 3.0;
int num_decks = 6,
    reshuffle_percentage = 66,
    ten_check = 0,
    hit_soft17 = 0,
    double_split = 1,
    resplit_pair = 1,
    late_surrender = 1,
    show_burn = 0,
    show_pct = 1;

main(argc,argv)
int argc;
char **argv;
{
    process_args(argc,argv);

    init_decks();

    last_bet = money / 100.0;
    if (last_bet < table_min)
    	last_bet = table_min;

    for (;;)
    {
	check_shuffle();

	printf("\nMoney = $%.2lf; Enter your bet [%.2lf]: ",money,last_bet);
	fgets(inpstring,80,stdin);
	if (sscanf(inpstring,"%lf",&bet) < 1)
	    bet = last_bet;
        else
	    last_bet = bet;
	if (bet < table_min)
	{
	    printf("Illegal bet. Table minimum is $%.2lf.\n",table_min);
	    continue;
	}
	money -= bet;
	play_hand();
    }
}

#define H_BJ_UTIL(c1,c2) (c1 == ACE && cardinfo[c2].bj_val == 10)
#define HAS_BJ(c1,c2) (H_BJ_UTIL(c1,c2) || H_BJ_UTIL(c2,c1))

#define MAX_SPLITS 10
/* Note that all bets are subtracted from your money as soon as they
are made. */
play_hand()
{
    CARD dealer_up,dealer_down;
    CARD player_1,player_2;
    CARD tmp;
    int dealer_has_bj,player_has_bj;
    int hand_totals[MAX_SPLITS];
    int doubled_down[MAX_SPLITS];
    int num_hands = 1;
    int hand_num;
    int got_ace,hit_already;
    char response;
    int didnt_bust = 0;
    int dealer_total,dealer_got_ace;
    int surrendered = 0;

    player_1 = *cardptr++;
    dealer_up = *cardptr++;
    player_2 = *cardptr++;
    dealer_down = *cardptr++;

    printf("Dealer shows:\t%c ?\n",cardinfo[dealer_up].display_char);
    printf("\nYou have:\t%c %c\n",
	   cardinfo[player_1].display_char,cardinfo[player_2].display_char);
    dealer_has_bj = HAS_BJ(dealer_up,dealer_down);
    player_has_bj = HAS_BJ(player_1,player_2);
    if (dealer_up == ACE)
    {
	printf("Do you wish to buy insurance? [n]: ");
	fgets(inpstring,80,stdin);
	if (sscanf(inpstring,"%1s",&response) < 1)
	    response = 'n';
	if (response == 'Y')
	    response = 'y';
	if (response == 'y')
	    money -= 0.5 * bet;
	if (dealer_has_bj)
	{
	    printf("Dealer's down card was %c -- Blackjack.\n",
		   cardinfo[dealer_down].display_char);
	    if (response == 'y')
	    {
		printf("Your insurance pays off.\n");
		money += 1.5 * bet;
	    }
	    if (player_has_bj)
	    {
	    	printf("Since you also have Blackjack, you push.\n");
	        money += bet;
	    }
	    return;
	}
	printf("No Blackjack.\n");
    }
    else if (cardinfo[dealer_up].bj_val == 10 && ten_check)
    {
        if (dealer_has_bj)
	{
	    printf("Dealer's down card was A -- Blackjack.\n");
	    if (player_has_bj)
	    {
	    	printf("Since you also have Blackjack, you push.\n");
		money += bet;
	    }
	    return;
	}
	printf("No Blackjack.\n");
    }
    if (player_has_bj)
    {
    	printf("You have Blackjack.\n");
	if (dealer_has_bj)	/* Up card must be a 10 of some sort */
	{
	    printf("Dealer's down card was A.");
	    printf(" Dealer has Blackjack, so you push.\n");
	    money += bet;
	    return;
	}
	printf("Dealer's down card was %c.\n",
	  cardinfo[dealer_down].display_char);
	money += bet * 2.5;
	return;
    }
    

    for (hand_num = 0; hand_num < num_hands; hand_num++)
    {
    	if (num_hands > 1)
	{
	    player_2 = *cardptr++;
	    printf("Hand %d: You have %c and are dealt %c.\n",hand_num + 1,
	      cardinfo[player_1].display_char,
	      cardinfo[player_2].display_char);
	}

    	got_ace = player_1 == ACE || player_2 == ACE;
	hit_already = 0;
	hand_totals[hand_num] = cardinfo[player_1].bj_val +
	  cardinfo[player_2].bj_val;
	doubled_down[hand_num] = 0;

	/* Only one card and no further splitting if you split Aces. */
	if (num_hands > 1 && player_1 == ACE)
	{
	    if (hand_totals[hand_num] < 12)
	    	hand_totals[hand_num] += 10;
	    didnt_bust = 1;
	    continue;
	}

	for (;;)
	{
	    printf("Your options are H(Hit), S(Stand)");
	    if (!hit_already)
	    {
	    	if (num_hands == 1 || double_split)
		    printf(", D(Double Down)");
		if (player_1 == player_2 && (num_hands == 1 || resplit_pair))
		    printf(", P(Split)");
		if (num_hands == 1 && late_surrender)
		    printf(", L(Late Surrender)");
	    }
	    printf(": ");
	    do
	    	fgets(inpstring,80,stdin);
	    while (sscanf(inpstring,"%1s",&response) < 1);
	    if (isupper(response))
	    	response = tolower(response);

	    switch (response)
	    {
	    	case 'h':
		    hit_already = 1;
		    if ((tmp = *cardptr++) == ACE)
		    	got_ace = 1;
		    printf("You get:\t%c\n",cardinfo[tmp].display_char);
		    if ((hand_totals[hand_num] += cardinfo[tmp].bj_val) > 21)
		    {
		    	printf("Your total is %d -- you busted.\n",
			  hand_totals[hand_num]);
			break;
		    }
		    continue;
		case 'd':
		    if (hit_already || num_hands > 1 && !double_split)
		    {
		    	printf("Bad option.\n");
			continue;
		    }
		    money -= bet;
		    doubled_down[hand_num] = 1;
		    if ((tmp = *cardptr++) == ACE)
		    	got_ace = 1;
		    printf("You get:\t%c\n",cardinfo[tmp].display_char);
		    if ((hand_totals[hand_num] += cardinfo[tmp].bj_val) > 21)
		    {
		    	printf("Your total is %d -- you busted.\n",
			  hand_totals[hand_num]);
			break;
		    }
		    /* fall through... */
		case 's':
		    if (got_ace && hand_totals[hand_num] < 12)
		    	hand_totals[hand_num] += 10;
		    didnt_bust = 1;
		    break;
		case 'p':
		    if (hit_already || player_1 != player_2 ||
		      num_hands > 1 && !resplit_pair)
		    {
		    	printf("Bad option.\n");
			continue;
		    }
		    num_hands++;
		    hand_num--;
		    money -= bet;
		    break;
		case 'l':
		    if (hit_already || num_hands > 1 || !late_surrender)
		    {
		    	printf("Bad option.\n");
			continue;
		    }
		    money += bet / 2.0;
		    surrendered = 1;
		    break;
		default:
		    printf("Bad option.\n");
		    continue;
	    }

	    break;
	}
    }

    if (dealer_has_bj)
    {
    	double tmp = 0;

	printf("Dealer's down card was A. Dealer had Blackjack all along.\n");
	for (hand_num = 0; hand_num < num_hands; hand_num++)
	{
	    if (hand_num > 1)
	    	tmp += bet;
	    if (doubled_down[hand_num])
	    	tmp += bet;
	}
	money += tmp;
	if (tmp > 0.0)
	    printf("$%.2lf has been returned to you.\n",tmp);
	if (surrendered)
	    money -= bet / 2.0;
	return;
    }

    if (!didnt_bust)
    {
	printf("Dealer's down card was %c.\n",
	  cardinfo[dealer_down].display_char);
	return;
    }

    dealer_got_ace = dealer_up == ACE || dealer_down == ACE;
    dealer_total = cardinfo[dealer_up].bj_val + cardinfo[dealer_down].bj_val;
    printf("Dealer:\t\t(%c) %c",cardinfo[dealer_up].display_char,
      cardinfo[dealer_down].display_char);
    for (;;)
    {
	if (dealer_total >= 17 || dealer_got_ace && dealer_total < 12 && 
	  (dealer_total >= 8 || !hit_soft17 && dealer_total == 7))
	    break;
	tmp = *cardptr++;
	printf(" %c",cardinfo[tmp].display_char);
	dealer_total += cardinfo[tmp].bj_val;
	if (dealer_total > 21)
	    break;
    }
    if (dealer_total < 12)
    	dealer_total += 10;
    printf(" -> %d",dealer_total);
    if (dealer_total > 21)
    	printf(" -- busted");
    printf(".\n");

    for (hand_num = 0; hand_num < num_hands; hand_num++)
    {
    	if (num_hands > 1)
	    printf("Hand %d:\t\t",hand_num + 1);
	if (hand_totals[hand_num] > 21)
	    printf("busted.\n");
	else
	{
	    printf("Your total:\t%d -- you ",hand_totals[hand_num]);
	    if (hand_totals[hand_num] > dealer_total || dealer_total > 21)
	    {
	    	printf("win.\n");
		money += 2.0 * bet;
		if (doubled_down[hand_num])
		    money += 2.0 * bet;
	    }
	    else if (hand_totals[hand_num] == dealer_total)
	    {
	    	printf("push.\n");
		money += bet;
		if (doubled_down[hand_num])
		    money += bet;
	    }
	    else
	    	printf("lose.\n");
	}
    }
}

process_args(argc,argv)
int argc;
char **argv;
{
    int tmp;
    char *rest;
#ifndef MSDOS
    double atof();
#endif

    while (++argv,--argc)
    {
    	if (argv[0][0] != '-' && argv[0][0] != '/' || strlen(argv[0]) < 3)
	    show_usage();

	if (isupper(tmp = argv[0][1]))
	    tmp = tolower(tmp);

	rest = &argv[0][2];

	switch (tmp)
	{
	    case 'b':	/* money */
	    	money = atof(rest);
		break;
	    case 'm':	/* table minimum */
	    	table_min = atof(rest);
		break;
	    case 'n':	/* number of decks */
	    	num_decks = atoi(rest);
		break;
	    case 'p':	/* pct after which to reshuffle */
	    	reshuffle_percentage = atoi(rest);
		break;
	    case 't':	/* check for bj on tens */
	    	ten_check = atoi(rest);
		break;
	    case 'h':	/* hit on soft 17's */
	    	hit_soft17 = atoi(rest);
		break;
	    case 'd':	/* allow doubling down after splitting */
	    	double_split = atoi(rest);
		break;
	    case 'r':	/* allow resplitting */
	    	resplit_pair = atoi(rest);
		break;
	    case 'l':	/* allow late surrendering */
	    	late_surrender = atoi(rest);
		break;
	    case 'c':	/* show burned card */
	    	show_burn = atoi(rest);
		break;
	    case 's':	/* show remaining deck */
	    	show_pct = atoi(rest);
		break;
	    default:
	    	show_usage();
	}
    }
}

show_usage()
{
    printf("Usage: bj [-b<num>] [-m<num>] [-n<num>] [-p<num>] [-t<bit>]\n");
    printf("          [-h<bit>] [-d<bit>] [-r<bit>] [-l<bit>] [-c<bit>]\n");
    printf("          [-s<bit>]\n");
    printf("-b: Specify starting bankroll [%.2lf].\n",money);
    printf("-m: Specify minimum bet allowed [%.2lf].\n",table_min);
    printf("-n: Specify number of decks [%d].\n",num_decks);
    printf("-p: Specify percentage of cards after which to reshuffle [%d].\n",
      reshuffle_percentage);
    printf("-t: Whether dealer checks for Blackjack on tens [%d].\n",
      ten_check);
    printf("-h: Whether dealer hits on soft 17's [%d].\n",hit_soft17);
    printf("-d: Whether player can double down after splitting [%d].\n",
      double_split);
    printf("-r: Whether player can split more than once [%d].\n",
      resplit_pair);
    printf("-l: Whether player can late surrender on two cards [%d].\n",
      late_surrender);
    printf("-c: Whether to show all burned cards [%d].\n",show_burn);
    printf("-s: Whether to show the portion of the deck remaining [%d].\n",
      show_pct);
    exit(1);
}