Console BlackJack question

Value of Aces.......

Page 1 of 1

10 Replies - 630 Views - Last Post: 21 August 2009 - 04:32 PM Rate Topic: -----

#1 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Console BlackJack question

Posted 21 August 2009 - 09:10 AM

Hello there. This will be my first post on deamincode.net so I hope I can get some help. Basically I am working on a code portfolio for myself to showoff at potential job interviews. The current project is a beefed up BlackJack game. The game itself works, I still have to implement getting blackjack, and, the tricky part, the changing of the value of Aces depending on if 11 would put the player over 21. Heres the code as is.

#include <iostream>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>

using namespace std;


static const char *card[] =	   // holds names of cards
{
	"2", "3", "4", "5", "6", "7", "8",
	"9", "10", "J", "Q", "K", "A"
};
static const char *suit[] =	   // holds suits of cards
{// diamonds, clubs, hearts, spades
	"\x04", "\x05", "\x03", "\x06"
};
static const int value[] =			// holds numerical value of cads
{
	2,3,4,5,6,7,8,9,10,10,10,10,11
};

// macro for determining card name
#define CARD(x) (card[ (x) % 13 ])
// macro for determining card suit
#define SUIT(x) (suit[ (x) / 13 ])
// macro for determining card value
#define VALUE(x) (value[ (x) % 13 ])


// amount of money the player has
static int playerMoney = 0;
// deck of cards
static int Deck[52];
static int nextCard = 0; // Next card to be dealt

// function prototypes
void PlayGame(void);
void Instructions(void);
void Shuffle (int seconds);
int DealCard(void);
void PrintHand(int hand[], bool dealer = false);
void Menu(void);
void DetermineOptions(bool options[], int hand[], bool firstDeal = false);
int PrintOptions(bool options[]);

// enumeration for player options
enum E_PLAYEROPTIONS
{
	EPO_HIT = 0,
	EPO_STAND,
	EPO_DD,
	EPO_SPLIT,
	EPO_COUNT, // number of options in total
};

// returns the character key that is pressed. Primarily used for menus and
char GetKey(void)
{
	char ch;
	while (!_kbhit())
	{}
	// in case of a key is hit, do these
	ch = _getch();
	return ch;
}
// print new lines to "clear" the console window
void ClearWindow(void)
{
	cout << "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}


// Main Entry Point 
int main (void)
{
	ClearWindow();
	
	cout << "Welcome to the BlackJack table.\n";
	cout << "Written by Brandon Beauchene   2006\n";
		
	Menu();

	return 0;
}

// Shuffles the deck of cards continuously for the specified number of seconds
void Shuffle (int seconds)
{	
	srand(time(0));
	int startTime = time(0);
	int curTime = 0;
	int progressTime = 0;

	// initialize card deck to starting values
	for (int i = 0; i < 52; i++)
	{
		Deck[i] = i;
	}
	
	cout << "Shuffling.";

	// keep shuffling until we have shuffled for the specified seconds
	while (curTime - startTime < seconds)
	{
		for (int i=0; i<(52-1); i++) 
		{
			int r = i + (rand() % (52-i)); // Random remaining position.
			int temp = Deck[i]; 
			Deck[i] = Deck[r]; 
			Deck[r] = temp;
		}
		// add a . to the "progress bar" every second
		if (curTime-progressTime>1)
		{
			cout << ".";
			progressTime = curTime;
		}
		curTime = time(0);
	}
	cout << "\n";
}


// display main menu while in game loop
void Menu(void)
{
	char key;
	bool quit = false;

	while (!quit)
	{
		cout << "\n\n";
		cout << "\xC9\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBB\n";
		cout << "\xBA		 Main Menu		 \xBA\n";
		cout << "\xC7\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xC4\xB6\n";
		cout << "\xBA  1) Play BlackJack		\xBA\n";
		cout << "\xBA  2) Instructions		  \xBA\n";
		cout << "\xBA  3) Quit				  \xBA\n";
		cout << "\xC8\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xBC\n";
 
		key = GetKey();
		switch (key)
		{
		case '1':
			PlayGame();
			break;
		case '2':
			Instructions();
			break;
		case '3':
			quit = true;
			break;
		default:
			cout << "\nInvalid selection.\n";
			break;
		}
	}
}

// Play while we have money
void PlayGame(void)
{
	// players current bet
	int bet = 0;
	int bet2 = 0; // for a split hand
	// true as long as the hand is not over
	bool bPlaying;
	// players hand
	int playerHandA[5];
	int numPlayerCardsA = 0;
	bool playerBustA = false;
	int playerTotal = 0;
	// in case of split we have a second hand
	int playerHandB[5];
	int numPlayerCardsB = 0;
	int activeHand = 1; // current hand we are playing 1 or 2
	bool playerBustB = false;
	
	bool winA = false;
	bool winB = false;

	// dealers hand
	int dealerHand[5];
	int numDealerCards = 0;
	bool dealerStand = false;
	bool dealerBust = false;
	int dealerTotal = 0;

	playerMoney = 500;

	// array of available options to the player
	bool playerOptions[EPO_COUNT];
	for (int i = 0; i < EPO_COUNT; i++)
	{
		playerOptions[i] = false;
	}

	// continue playing until the player has no more money
	while (playerMoney > 0)
	{
		bet = 0;
		// display beginning of hand prompt and get a bet amount
		ClearWindow();
		cout << "BlackJack --- Player ($" << playerMoney << ")\n";
		
		// loop until bet is positive amount
		while (bet <= 0)
		{
			cout << "Enter your bet : ";
			cin >> bet;
		}

		// make sure you cant bet more than you have
		if (bet > playerMoney)
			bet = playerMoney;

		// Shuffle the deck
		nextCard = 0;
		Shuffle(5);

		// reset our hands
		for (int i = 0; i < 5; i++)
		{
			playerHandA[i] = -1;
			playerHandB[i] = -1;
			dealerHand[i] = -1;
		}
		numPlayerCardsA = 0;
		numPlayerCardsB = 0;
		numDealerCards = 0;

		bPlaying = true;
		winA = false;
		winB = false;
		playerBustA = false;
		playerBustB = false;
		dealerBust = false;
		dealerStand = false;
		activeHand = 1;

		// deal 2 cards to both player and dealer (alternating)
		for (int i = 0; i < 2; i++)
		{
			playerHandA[numPlayerCardsA] = DealCard();
			numPlayerCardsA++;
			dealerHand[numDealerCards] = DealCard();
			numDealerCards++;
		}
		
		// this is the initial deal so determine our "first hand" options
		DetermineOptions(playerOptions,playerHandA, true);
		
		while (bPlaying)
		{
			ClearWindow();
		
			cout << "BlackJack --- Player ($" << playerMoney << "), Bet ($" << bet << ")\n";	
			cout << "\n";

			// print the hands
			cout << "Dealer : ";
			PrintHand(dealerHand, true);
			if (activeHand==1)
			{
				cout << "You   *: ";
			}
			else
			{
				cout << "You	: ";
			}
			PrintHand(playerHandA);
			// if we split print the second hand
			if (playerHandB[0] != -1)
			{
				if (activeHand==2)
				{
					cout << "Split *: ";
				}
				else
				{
					cout << "Split  : ";
				}
				PrintHand(playerHandB);
			}

			// print options and act accordingly
			switch (PrintOptions(playerOptions))
			{
			case 'H':
				// determine the active hand and deal another card to that hand
				if (activeHand == 1)
				{
					playerHandA[numPlayerCardsA] = DealCard();
					numPlayerCardsA++;
					playerTotal = 0;
					for (int i = 0; i < numPlayerCardsA; i++)
					{
						playerTotal += VALUE(playerHandA[i]);
					}
					if (playerTotal > 21)
					{
						// busted
						playerBustA = true;
						//move to next hand if we need to 
						if (playerHandB[0] != -1)
						{
							activeHand = 2;
						}
						else
						{
							// complete the hand
							bPlaying = false;
						}
					}
				}
				else
				{
					playerHandB[numPlayerCardsB] = DealCard();
					numPlayerCardsB++;
					playerTotal = 0;
					for (int i = 0; i < numPlayerCardsB; i++)
					{
						playerTotal += VALUE(playerHandB[i]);
					}
					if (playerTotal > 21)
					{
						// busted
						playerBustB = true;
						// end the hand
						bPlaying = false;
					}
				}		
				break;
			case 'P':
				// split the hand and set the second bet
				playerHandB[0] = playerHandA[1];
				playerHandA[1] = DealCard();
				playerHandB[1] = DealCard();
				numPlayerCardsA = 2;
				numPlayerCardsB = 2;				
				bet2 = bet;
				break;
			case 'D':
				// determine the active hand, double the bet and deal one card to that hand
				if (activeHand == 1)
				{
					bet *= 2;
					playerHandA[numPlayerCardsA] = DealCard();
					numPlayerCardsA++;
					// get our new total
					playerTotal = 0;
					for (int i = 0; i < numPlayerCardsA; i++)
					{
						playerTotal += VALUE(playerHandA[i]);
					}
					if (playerTotal > 21)
					{
						// busted
						playerBustA = true;
					}
				}
				else
				{
					bet2 *= 2;
					playerHandB[numPlayerCardsB] = DealCard();
					numPlayerCardsB++;
					// get our new total
					playerTotal = 0;
					for (int i = 0; i < numPlayerCardsB; i++)
					{
						playerTotal += VALUE(playerHandB[i]);
					}
					if (playerTotal > 21)
					{
						// busted
						playerBustB = true;
					}
				}
				// no break, just continue to auto-stand.
				
			case 'S':
				// determine the active hand
				if (activeHand == 1)
				{
					// move to the next hand if we have one
					if (playerHandB[0] != -1)
					{
						activeHand = 2;
					}
					else
					{
						bPlaying = false;
					}
				}
				else
				{
					// complete the hand
					bPlaying = false;
				}

				break;
			default:
				break;
			}//switch

			// determine new options for the current hand
			if (activeHand == 1)
			{
				// check for Five Card Charlie
				if ((numPlayerCardsA >= 5) && (!playerBustA))
				{
					winA = true;
					activeHand = 2;
					DetermineOptions(playerOptions, playerHandB);
				}
				else
				{
					DetermineOptions(playerOptions, playerHandA);
				}
			}
			else
			{
				// check for Five Card Charlie
				if ((numPlayerCardsB >= 5) && (!playerBustB))
				{
					winB = true;
					bPlaying = false;
				}
				else
				{
					DetermineOptions(playerOptions,playerHandB);
				}
			}
		}//while(bPlaying)

		// reset hand totals
		dealerTotal = 0;
		playerTotal = 0;

		// calculate total for player's first hand that hasnt busted

		// check first hand
		if (playerBustA)
		{
			// hand A busted check second hand if there is one
			if (playerHandB[0] != -1)
			{
				// we have a second hand
				if (playerBustB)
				{
					// both hands busted
					activeHand = 0;
				}
				else
				{
					// we are comparing dealers hand to player hand B
					for (int i = 0; i < numPlayerCardsB; i++)
					{
						playerTotal += VALUE(playerHandB[i]);
					}
				}
			}
			else
			{
				// only one hand and it busted
				activeHand = 0;
			}
		}
		else
		{
			// we are comparing dealers hand to player hand A
			for (int i = 0; i < numPlayerCardsA; i++)
			{
				playerTotal += VALUE(playerHandA[i]);
			}
		}
		

		// Dealers turn
		while (!dealerStand)
		{
			// update our display
			ClearWindow();
		
			cout << "BlackJack --- Player ($" << playerMoney << "), Bet ($" << bet << ")\n";	
			cout << "\n";

			// print the hands
			cout << "Dealer*: ";
			// dont hide the dealers first card anymore
			PrintHand(dealerHand);
			cout << "You	: ";
			PrintHand(playerHandA);
			// if we split print the second hand
			if (playerHandB[0] != -1)
			{
				cout << "	   : ";
				PrintHand(playerHandB);
			}

			Sleep(1850); // delay between dealing cards
						
			if (activeHand == 0)
			{
				cout << "\nYou Busted, Dealer stands.\n";
				dealerStand = true;
			}
			else
			{
				// get dealers total
				dealerTotal = 0;
				for (int i = 0; i < numDealerCards; i++)
				{
					dealerTotal += VALUE(dealerHand[i]);
				}
				// check for bust
				if (dealerTotal > 21)
				{
					dealerBust = true;
				}
				//compare hands and take a hit if needed
				if ((!dealerBust) && (dealerTotal < playerTotal))
				{
					dealerHand[numDealerCards] = DealCard();
					numDealerCards++;
				}
				else
				{
					dealerStand = true;
				}
			}

					

		}//while(!dealerStand)
		Sleep(2000);

		// determine active hand and winner

		// update our display
		ClearWindow();
		
		cout << "BlackJack --- Player ($" << playerMoney << "), Bet ($" << bet << ")\n";	
		cout << "\n";

		// print the hands
		cout << "Dealer : ";
		// dont hide the dealers first card anymore
		PrintHand(dealerHand);
		cout << "You	: ";
		PrintHand(playerHandA);
		// if we split print the second hand
		if (playerHandB[0] != -1)
		{
			cout << "	   : ";
			PrintHand(playerHandB);
		}
		cout << "\n\n";
		if (!playerBustA)
		{
			// first (or only) hand did not bust, get total
			playerTotal = 0;
			for (int i = 0; i < numPlayerCardsA; i++)
			{
				playerTotal += VALUE(playerHandA[i]);
			}

			// check for 5 card charlie win
			if (winA)
			{
				cout << "Five Card Charlie! You win $" << bet*2 << " !\n";
				playerMoney += bet*2;
			}
			else
			{
				if (dealerBust)
				{
					cout << "Dealer busted. You win $" << bet << " !\n";
					playerMoney += bet;
				}
				else if (playerTotal > dealerTotal)
				{
					// win
					cout << "You won and gained $" << bet << " !\n";
					playerMoney += bet;
				}
				else if (playerTotal == dealerTotal)
				{
					// push/tie
					cout << "The hand is a push!\n";
				}
				else if (playerTotal < dealerTotal)
				{
					// lose
					cout << "Dealer won. You lost $" << bet << " !\n";
					playerMoney -= bet;
				}
			}
		}
		else
		{
			if (dealerBust)
			{
				cout << "You and dealer both busted busted. Hand is a push!\n";
			}
			else
			{
				// busted hand, lose
				cout << "You busted and lost $" << bet << " !\n";
				playerMoney -= bet;
			}
		}

		// if there is a second split hand
		if (playerHandB[0] != -1)
		{
			// pause for a second before calculating results
			Sleep(1800);
			if (!playerBustB)
			{
				// first (or only) hand did not bust, get total
				playerTotal = 0;
				for (int i = 0; i < numPlayerCardsB; i++)
				{
					playerTotal += VALUE(playerHandB[i]);
				}
			
				// check for five card charlie win
				if (winB)
				{
					cout << "Split has Five Card Charlie! You win $" << bet2*2 << " !\n";
					playerMoney += bet2*2;
				}
				else
				{
					if (dealerBust)
					{
						cout << "Dealer busted. You win $" << bet2 << " !\n";
						playerMoney += bet2;
					}
					else if (playerTotal > dealerTotal)
					{
						// win
						cout << "Split won! You gained $" << bet2 << " !\n";
						playerMoney += bet2;
					}
					else if (playerTotal == dealerTotal)
					{
						// push/tie
						cout << "The split hand is a push!\n";
					}
					else if (playerTotal < dealerTotal)
					{
						// lose
						cout << "Split lost! You lost $" << bet2 << " !\n";
						playerMoney -= bet2;
					}
				}
			}
			else
			{


This post has been edited by qwertyCoder23: 21 August 2009 - 09:24 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Console BlackJack question

#2 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Re: Console BlackJack question

Posted 21 August 2009 - 09:26 AM

Ok so the code is longer than one post... heres the rest

				if (dealerBust)
				{
					cout << "Split and dealer both busted. Split is a push!\n";
				}
				else
				{
					// busted hand, lose
					cout << "Split busted! You lost $" << bet << " !\n";
					playerMoney -= bet2;
				}
			}
		}
		Sleep(2200);

		
	}//while(playerMoney>0)
	ClearWindow();
	cout << "You have run out of money. Better luck next time.\n";
	cout << "Thanks for playing.\n\nPress any key to continue...\n";
	GetKey();
	ClearWindow();
}
// displays instructions for blackjack
void Instructions(void)
{
	ClearWindow();
	cout << "Basic Rules\n";
	cout << "-Objective-\n";
	cout << " The object of the game is to beat the dealers hand by getting\n";
	cout << "as close to 21 as you can without going over. You place a bet \n";
	cout << "and are then dealt 2 cards. At this point you have a 2 options:\n";
	cout << "A) Hit and take another card adding its value to your total value\n";
	cout << "B) Stand and let the dealer try to beat your total\n\n";
	cout << "If you go over 21 when you hit, it is called a 'bust' and you lose\n";
	cout << "automatically and forfeit your bet amount; however, if the dealer \n";
	cout << "'busts' or your total is higher, then you win a payout of 1 to 1.\n\n";
	cout << "Press any key to continue...\n";
	GetKey();
	ClearWindow();
	cout << "Additional Rules\n";
	cout << "-Split-\n";
	cout << "When the hand is first dealt, if your two cards are the same,\n";
	cout << "eg. both are tens, then you have the option, if you have enough\n";
	cout << "money, to 'double down'. This splits your cards into two hands and\n";
	cout << "deals another card to each. In addition, your bet is also doubled\n";
	cout << "and you play each hand separately against the dealers hand. When\n";
	cout << "you stand with the first hand, you then work on the second. Once\n";
	cout << "you stand with the second hand, the dealer then takes their turn.\n";
	cout << "Each hand is then either won or lost like normal, but if you win\n";
	cout << "with both you recieve double your bet; however if you lose with \n";
	cout << "both, you lose double your initial bet.\n\n";
	cout << "-Double Down-\n";
	cout << "When the hand is first dealt, you have the option to 'double down'\n";
	cout << "or double your bet. Similiar to the split with two exceptions. First\n";
	cout << "only one hand is played instead of 2, and second you only recieve one\n.";
	cout << "additional card and automatically stand.\n\n";
	cout << "-Aces-\n";
	cout << "In blackjack Aces are special. They are treated with the initial\n";
	cout << "value of 1, but if you go over 21, the value is dropped to 1.\n\n";
	cout << "Press any key to continue...\n";
	GetKey();
	ClearWindow();
	cout << "\n-BlackJack-\n";
	cout << "On the start of the hand, if you have a face card and an ace you\n";
	cout << "automatically win. This is called a BlackJack. The payout is one \n";
	cout << "and a half times your initial bet.\n\n";
	cout << "-Five Card Charlie-\n";
	cout << "If, during a hand, you have a total of 5 cards without going over\n";
	cout << "21, then you win with a 2 to 1 payout. In other words, you win\n";
	cout << "twice the amount of your bet.\n\n";
	cout << "Dealer\n";
	cout << "When a hand starts the dealer only shows one of their cards. After\n";
	cout << "you stand, the other card is flipped up and the dealer then hits or\n";
	cout << "stands depending on their card value total. House rules state that\n";
	cout << "the dealer must hit on anything below 18. After that he stays unless\n";
	cout << "the player has a higher value.\n\n";
	cout << "Press any key to continue...\n";
	GetKey();
	ClearWindow();
}

// deals a card and returns its card number
int DealCard(void)
{
	int card = Deck[nextCard];
	nextCard= nextCard+1;
	return card;
}
// display the card and suits that are in the specified hand
void PrintHand(int hand[], bool dealer)
{
	int total = 0;
	for (int i = 0; i < 5; i++)
	{
		if (hand[i] != -1)
		{
			if ((i==0) && (dealer))
			{
				// hand belongs to dealer so dont show the first card
				cout << "?? ";
			}
			else
			{
				cout << CARD(hand[i]) << SUIT(hand[i]) << " ";
				total += VALUE(hand[i]);
			}
		}
	}
	cout << "   = "<< total << "\n";
}
// Determine available options based on contents of hand
void DetermineOptions(bool options[], int hand[], bool firstDeal)
{
	for (int i = 0; i < EPO_COUNT; i++)
	{
		options[i] = false;
	}

	options[EPO_HIT] = true;
	options[EPO_STAND] = true;
	// at the start and only now, player can double down or has the chance to split
	if (firstDeal)
	{
		options[EPO_DD] = true;
		
		// can we split?
		if (CARD(hand[0]) == CARD(hand[1]))
		{
			options[EPO_SPLIT] = true;
		}
	}
}
// print a menu based on the current options available to the player
// and return the option selected
int PrintOptions(bool options[])
{
	int key = 0;

	for (int i = 0; i < EPO_COUNT; i++)
	{
		if (options[i])
		{
			// option is available so print the option
			switch (i)
			{
			case EPO_HIT:
				cout << "(H)it\n";
				break;
			case EPO_DD:
				cout << "(D)ouble Down\n";
				break;
			case EPO_SPLIT:
				cout << "S(p)lit\n";
				break;
			case EPO_STAND:
				cout << "(S)tand\n";
				break;
			default:
				break;
			}//switch
		}//if
	}//for

	// loop until we have a keypress that matches an available option
	while (!key)
	{
		key = GetKey();
		if ((key == 'h') || (key == 'H'))
		{
			if (options[EPO_HIT])
			{
				key = 'H';
			}
			else
			{
				key = 0;
			}
		}
		else if ((key == 'd') || (key == 'D'))
		{
			if (options[EPO_DD])
			{
				key = 'D';
			}
			else
			{
				key = 0;
			}
		}
		else if ((key == 'p') || (key == 'P'))
		{
			if (options[EPO_SPLIT])
			{
				key = 'P';
			}
			else
			{
				key = 0;
			}
		}
		else if ((key == 's') || (key == 'S'))
		{
			if (options[EPO_STAND])
			{
				key = 'S';
			}
			else
			{
				key = 0;
			}
		}
		else
		{
			key = 0;
		}
	}

	// return selected option
	return key;
}


Was This Post Helpful? 0
  • +
  • -

#3 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Console BlackJack question

Posted 21 August 2009 - 09:30 AM

I haven't read all your code, but when I did a Blackjack program I had a snippet of something similar:

//keep default ace at 11
if (curHandValue + AceValue > 21)
	 curHandValue++; //increment one since you'd bust


Was This Post Helpful? 0
  • +
  • -

#4 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Re: Console BlackJack question

Posted 21 August 2009 - 09:31 AM

So the problem comes in with how I am determining the card number, suit, and value. Using the macros defined at the top, like this

static const char *card[] =	   // holds names of cards
{
	"2", "3", "4", "5", "6", "7", "8",
	"9", "10", "J", "Q", "K", "A"
};
static const char *suit[] =	   // holds suits of cards
{// diamonds, clubs, hearts, spades
	"\x04", "\x05", "\x03", "\x06"
};
static const int value[] =			// holds numerical value of cads
{
	2,3,4,5,6,7,8,9,10,10,10,10,11
};

// macro for determining card name
#define CARD(x) (card[ (x) % 13 ])
// macro for determining card suit
#define SUIT(x) (suit[ (x) / 13 ])
// macro for determining card value
#define VALUE(x) (value[ (x) % 13 ])



It works fine, but then I need the option for Aces to have the value of 1 at certain times. The modular division makes this impossible as far as I can tell because if I say there are 56 cards in the deck (ie each ace is listed twice) then you wont have the CHOICE to change the value, you just get the value of that particular ace. So how do I adjust the value of 11 to a value of 1? The only thing i can figure is to create another function for determining the ace values based on the cards in a specified hand. In that function total my hand, if its over 21 search for the first ace and subtract 10 from the total. But how does that value maintain throughout the rest of the program? And even better, how can that apply to a split hand? Any thoughts, questions, concerns, inquiries, or even bombshells would be appreciated. Thanks in advance
Was This Post Helpful? 0
  • +
  • -

#5 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Console BlackJack question

Posted 21 August 2009 - 09:36 AM

An option would be to get rid of the macros and use objects. (Card class, Rank/Suit enums, etc...)
Was This Post Helpful? 0
  • +
  • -

#6 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Re: Console BlackJack question

Posted 21 August 2009 - 09:41 AM

View PostKYA, on 21 Aug, 2009 - 08:30 AM, said:

I haven't read all your code, but when I did a Blackjack program I had a snippet of something similar:

//keep default ace at 11
if (curHandValue + AceValue > 21)
	 curHandValue++; //increment one since you'd bust



First thanks for the reply. The only thing I can figure since I total the hands multiple times through the program would be to put it in a function like

// return total of hand
int TotalHand(int hand[])
{
   int total = 0;
   for (int i=0; i< 5; i++)
  {
	if (hand[i] != -1)
	{
	  // card in this spot
	  total += VALUE(hand[i]);
	}
  }
  return total;
}



and somewhere in there I have to determine if adding the ace value of 11 would put the hand total over 21 then only add one. That is easy except what if the ace is first, then it doesnt know to go back and change THAT ace......hmm

View PostKYA, on 21 Aug, 2009 - 08:36 AM, said:

An option would be to get rid of the macros and use objects. (Card class, Rank/Suit enums, etc...)


Normally I over use classes and objects. I love them. They are handy :)
But for the sake of my portfolio, Im trying to make it sort of chronological. In other words, even though Im coding this now, I want it to look like I did it shortly after starting my programming journey. So its the second thing listed in my portfolio. After this I plan to make a console library using classes to show that. But for blackjack Im wanting to stick with a functional approach. Thanks tho. (but this is why I prefer objects)
Was This Post Helpful? 0
  • +
  • -

#7 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Re: Console BlackJack question

Posted 21 August 2009 - 10:14 AM

Got it. For people who wish to know, or are making a blackjack game. Use this to tally your totals
int TotalHand(int hand[])
{
	int total = 0;
	int aces[4] = {-1,-1,-1,-1};
	int numAces = 0;

	for (int i=0; i< 5; i++)
	{
		if (hand[i] != -1)
		{
			// card in this spot
			if (!strcmp(CARD(hand[i]),"A"))
			{
				// this card is an Ace, save its location
				aces[numAces] = i;
				numAces++;
			}
			else
			{
				// add the total
				total += VALUE(hand[i]);
			}
		}
	}

	// now we need to add the the value of any aces to the total
	// value of ace is 11, unless it puts us over 21, then the value is 1
	for (int i = 0; i < numAces; i++)
	{
		if ((total+11) > 21)
		{
			total += 1;
		}
		else
		{
			total += 11;
		}
	}
	return total;
}



It actually does help to talk the problem out :)
Now to just add the blackjack win and Im done. woohoo less than 2 days of work.
Was This Post Helpful? 0
  • +
  • -

#8 KYA  Icon User is offline

  • g++ jameson.cpp -o beverage
  • member icon

Reputation: 3089
  • View blog
  • Posts: 19,136
  • Joined: 14-September 07

Re: Console BlackJack question

Posted 21 August 2009 - 10:20 AM

edit: Good, you found something. Feel free to disregard this.

Maybe something along these lines:

// return total of hand
int TotalHand(int hand[])
{
   int total = 0;
   for (int i=0; i< 5; i++)
  {
	if (hand[i] != -1)
	{
	  if (CARD(hand[i]) == ACE) //whatever value is ace 1 or 13, not sure{
			  if ((total + VALUE(hand[i])) > 21) {
					total += 1; 
			  }
	  }
	 else {
		  // card in this spot
		  total += VALUE(hand[i]);
	 }
	  
	}
  }
  return total;
}


This post has been edited by KYA: 21 August 2009 - 10:22 AM

Was This Post Helpful? 1
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5642
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: Console BlackJack question

Posted 21 August 2009 - 11:33 AM

Hmm... I think I'd do something like this:

int TotalHand(int hand[]) {
	int total = 0, aceCount = 0;
	
	for (int i=0; i< 5; i++) {
		if (hand[i] == -1) { break; }
		if (CARD(hand[i]) == ACE) { aceCount++; }
		total += VALUE(hand[i]));
	}
	while(total>21 && aceCount-->0) { total-=10; }
	return total;
}


Was This Post Helpful? 0
  • +
  • -

#10 qwertyCoder23  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 21-August 09

Re: Console BlackJack question

Posted 21 August 2009 - 02:19 PM

View Postbaavgai, on 21 Aug, 2009 - 10:33 AM, said:

Hmm... I think I'd do something like this:

int TotalHand(int hand[]) {
	int total = 0, aceCount = 0;
	
	for (int i=0; i< 5; i++) {
		if (hand[i] == -1) { break; }
		if (CARD(hand[i]) == ACE) { aceCount++; }
		total += VALUE(hand[i]));
	}
	while(total>21 && aceCount-->0) { total-=10; }
	return total;
}



Thanks for the response baavgai but when I use your snippet and run, oddly enough on the first hand the dealer gets an ace (first card is hidden ace is showing) so the total displayed should be 11 but instead was 0, once I stayed, dealer showed Q A and total was 21. strange no?
Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5642
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: Console BlackJack question

Posted 21 August 2009 - 04:32 PM

View PostqwertyCoder23, on 21 Aug, 2009 - 03:19 PM, said:

Thanks for the response baavgai but when I use your snippet and run, oddly enough on the first hand the dealer gets an ace (first card is hidden ace is showing) so the total displayed should be 11 but instead was 0, once I stayed, dealer showed Q A and total was 21. strange no?


Yep, strange. I can't replicate this. I wrote a quick test, looks like so:
#include <iostream>

using namespace std;

const char *getCardName(int cardNum) {
	static const char *name[] = { "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A" };
	return name[cardNum % 13];
}

int getCardValue(int cardNum) {
	static const int value[] = { 2,3,4,5,6,7,8,9,10,10,10,10,11 };
	return value[cardNum % 13];
	
}

bool isAce(int cardNum) { return (cardNum % 13)==12; }

int getHandValue(int hand[], int size) {
	int total = 0, aceCount = 0;
	for(int i=0; i<size; i++) {
		if (isAce(hand[i])) { aceCount++; }
		total += getCardValue(hand[i]);
	}
	while(total>21 && aceCount-->0) { total-=10; }
	return total;
}

void showHand(int hand[], int size) {
	cout << getHandValue(hand, size) << " : ";
	for(int i=0; i<size; i++) {
		cout << getCardName(hand[i]) << " ";
	}
	cout << endl;
}

int main() {
	int hand[6];
	int handSize = 0;
	
	hand[handSize++] = 12; showHand(hand, handSize);
	hand[handSize++] = 9; showHand(hand, handSize);
	hand[handSize++] = 3; showHand(hand, handSize);
	hand[handSize++] = 12; showHand(hand, handSize);
	hand[handSize++] = 10; showHand(hand, handSize);
	
	return 0;
}




You have created a tremendous amount of confusion for yourself by refusing to use any kind of object. If you just had a few classes like Card, Deck, Hand, your code would be much easier to follow.

e.g.
#include <iostream>
#include <string>
#include <vector>

using namespace std;

struct Card {
	static const unsigned int EmptyValue = 42;
	unsigned int face, suit;
	Card() : suit(EmptyValue), face(EmptyValue) { }
	Card(unsigned int x) : suit(x/13), face(x%13) { }
	bool isEmpty() const { return suit==EmptyValue; }
	bool isAce() const { return face==0; }
	
	const string &getCardName() const {
		static const string EmptyName = "NA";
		static const string name[] = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };
		return isEmpty() ? EmptyName : name[face];
	}

	const string &getSuitName() const {
		static const string EmptyName = "NA";
		static const string name[] = { "D", "C", "H", "S" }; // diamonds, clubs, hearts, spades
		//static const string name[] = { "\x04", "\x05", "\x03", "\x06" }; // diamonds, clubs, hearts, spades
		if (isEmpty()) { return EmptyName; }
		return isEmpty() ? EmptyName : name[suit];
	}
	
	int getValue() const {
		if (isAce()) { return 11;
		} else if (face<9) { return face+1;
		} else { return 10;
		}
	}
	
	friend ostream &operator<< (ostream &out, const Card &item) {
		out << item.getCardName() << item.getSuitName();
		return out;
	}
};


struct Hand {
	static const unsigned int MaxSize = 12;
	Card cards[MaxSize];
	int size;
	Hand() : size(0) { }
	
	void clear() { size=0; }
	
	void addCard(const Card &card) { cards[size++] = card; }
	
	int getValue() const {
		int total = 0, aceCount = 0;
		for(int i=0; i<size; i++) {
			if (cards[i].isAce()) { aceCount++; }
			total += cards[i].getValue();
		}
		while(total>21 && aceCount-->0) { total-=10; }
		return total;
	}
	
	friend ostream &operator<< (ostream &out, const Hand &item) {
		for(int i=0; i<item.size; i++) {
			cout << item.cards[i] << ' ';
		}
		return out;
	}
};


int main() {
	Hand hand;
	
	hand.addCard(Card(0)); cout << hand.getValue() << " : "<< hand << endl;
	hand.addCard(Card(10)); cout << hand.getValue() << " : "<< hand << endl;
	hand.addCard(Card(4)); cout << hand.getValue() << " : "<< hand << endl;
	hand.addCard(Card(0)); cout << hand.getValue() << " : "<< hand << endl;
	hand.addCard(Card(11)); cout << hand.getValue() << " : "<< hand << endl;
	
	return 0;
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1