OK so I need to make a card dealing program that takes random cards from a deck and dispenses a 5 card poker hand, but i also have to right functions to tell if its a flush straight royal flush, etc... I have no Idea what to do after this.

// Card shuffling dealing program.
#include <iostream>

using std::cout;
using std::left;
using std::right;

#include <iomanip>

using std::setw;

#include <cstdlib>  // prototypes for rand and srand
#include <ctime>    // prototype for time

// prototypes
void shuffle( int [][ 13 ] );
void deal( const int [][ 13 ], const char *[], const char *[] );

int main()
{
   // initialize suit array
   const char *suit[ 4 ] =  
      { "Hearts", "Diamonds", "Clubs", "Spades" };
   
   // initialize face array
   const char *face[ 13 ] = 
      { "Ace", "Deuce", "Three", "Four",
        "Five", "Six", "Seven", "Eight",
        "Nine", "Ten", "Jack", "Queen", "King" };

   // initialize deck array
   int deck[ 4 ][ 13 ] = { 0 };

   srand( time( 0 ) );        // seed random number generator

   shuffle( deck );
   deal( deck, face, suit );

   return 0;  // indicates successful termination

} // end main

// shuffle cards in deck
void shuffle( int wDeck[][ 13 ] )
{
   int row;
   int column;

   // for each of the 52 cards, choose slot of deck randomly
   for ( int card = 1; card <= 52; card++ ) {

      // choose new random location until unoccupied slot found
      do {
         row = rand() % 4;
         column = rand() % 13;
      } while( wDeck[ row ][ column ] != 0 ); // end do/while

      // place card number in chosen slot of deck
      wDeck[ row ][ column ] = card;

   } // end for

} // end function shuffle

// deal cards in deck
void deal( const int wDeck[][ 13 ], const char *wFace[],
           const char *wSuit[] )
{
   // for each of the 52 cards
   for ( int card = 1; card <= 52; card++ )

      // loop through rows of wDeck
      for ( int row = 0; row <= 3; row++ )

         // loop through columns of wDeck for current row
         for ( int column = 0; column <= 12; column++ )

            // if slot contains current card, display card
            if ( wDeck[ row ][ column ] == card ) {
               cout << setw( 5 ) << right << wFace[ column ] 
                    << " of " << setw( 8 ) << left 
                    << wSuit[ row ]
                    << ( card % 2 == 0 ? '\n' : '\t' );

            } // end if
system("pause");
} // end function deal

Recommended Answers

All 2 Replies

I would use structs to represent the cards, rather than just arbitrary arrays. Here's a blackjack game I wrote a few years ago for school that might give you the right idea.

/*************************************************************************
Project:	 Lab 4
Files:		 main.cpp
Date:		 March. 24, 2008
Author:		 Kyle Wesley Class: 2D
Instructor:	 Cindy Chung Course: CNT252
Description: Blackjack game that uses structures, type def, and binary write
			 techniques to load and save the deck of cards.
*************************************************************************/
#include<iostream>
#include<fstream>
#include<ctime>
#include<iomanip>
using namespace std;

//The card's structure
struct SDeck
{
	int m_Value;	//value of the card 
	char m_Suit[10];//suit of the card
	char m_Face[10];//face of the card
	bool is_used;	//flag if its used
	bool is_ace;	//flag if its an ace
};

//total dump of game data.  used to save/load
struct SGame
{
	double m_dCash;			//total cash
	int m_iCards;			//total cards played
	SDeck CurrentDeck[52];	//dump of current deck of cards
};

//makes more sense to refer to cards as cards...
typedef SDeck CARD;

int GetRand(int, int);
double GetDouble(char [], double, double);
void DoLoad (SDeck [], double &, int &);
bool InitDeck(SDeck []);
void DoSave (SGame);
void DrawCard(SDeck [], CARD &);
void ShowCard(const CARD);
const char* DECKLOCATION = "Lab4CardDeckTextFile.txt";

int main()
{
	//****************************************************************
	//Initialize the game
	//****************************************************************
    double dMoney = 110,	//self explanitory...
		   dBet = 0;		//bet placed
	bool bHasAce = false,	//flag if the player (comp or user) has an ace
		 bBust = false,		//flag if the user busts by drawing too many cards
		 bFiveCardWin = false, // auto win if you get 5 cards
		 bBlackJack = false;//flag if the user gets a blackjack, thus getting 1.5x bet
	int iCardsPlayed = 0,	//total cards played so far
		iHandValue = 0,		//Value of the players hand
		iCompHandValue = 0; //Value of the computers had  
	char cAnother = 0;
	int i = 0;
	SGame Game = {0};
	SDeck Deck[52] = {0};					   //init the deck array struct
	CARD Card = {0};						   //init your card
	CARD CompCard = {0};					   //init the computers card
	srand(static_cast<unsigned int>(time(0))); //makes seed for randomized number
	if (InitDeck(Deck))								//load the deck, check if it worked
	{
		//****************************************************************
		//Start of actual game code...
		//****************************************************************
		DoLoad(Deck, dMoney, iCardsPlayed);		  //load the game, if wanted
		do
		{
			//-------------
			//reset everything that need to be reset
			//-------------
			bHasAce = false;					
			iHandValue = 0;
			bBust = false;
			bBlackJack = false;
			iCompHandValue = 0;

			//startup text
			cout << "		Blackjack";
			if (iCardsPlayed >= 42)			//hardcoded shuffle-point so the deck 
											//doesnt run out of cards
			{
				cout << "\nThe deck has been re-shuffled..."; 
				InitDeck(Deck);				//reshuffle the deck
				iCardsPlayed = 0;			//cards played resets
			}

			//display cash, get bet
			cout << "\nPlay a hand of blackjack...";
			cout << "\n\nYou have $" << setprecision(2) << fixed << dMoney - 10 << endl;
			dBet = GetDouble("Enter bet: ", 5.0, dMoney);
			DrawCard(Deck, Card);			//draw the card from the deck

			cout << "\nCard " << 1 << ": "; //card 1 is hardcoded because its mandatory
			iHandValue += Card.m_Value;		//add to the card value
			ShowCard (Card);				//display the card
											//*********************************************
			if (Card.is_ace)				//ace detection, I chose not to have any sort of
				{							//ace value entry.  I thought it would be much more
											//useful to always have the ace to your advantage,
					bHasAce = true;			//so I wrote an algorithm to do so
					iHandValue -= 10;		//*********************************************
				}
			iCardsPlayed++;					//inrement cards played
			cout << endl;
			for (i = 1; i < 5; i++) //start loop of drawing cards, up to 5
			{							
				iCardsPlayed++;				//increment cards played
				DrawCard(Deck, Card);		//draw a card from the deck...
				cout << "\nCard " << i + 1 << ": ";
				iHandValue += Card.m_Value;	//add the value to the hand
				ShowCard (Card);			//display the card
				if (Card.is_ace)			//*ace detection*
				{
					bHasAce = true; 
					iHandValue -= 10;
				}
				//Some code for deciding a bust or a blackjack, or a 5 card win, which cancels the
				//rest of the cards, and skips the computer.
				//Flags and a break from the loop are used to do this.
				if (i == 1 && iHandValue == 11 && bHasAce == true)
				{
					cout << "\nBlackjack!";
					dMoney += (dBet * 1.5);	//if I remember blackjack correctly, if a player
											//gets a blackjack, they get 150% of the bet
					bBlackJack = true;
					iHandValue += 10;		//autocorrects hand value since it has an ace
					break;
				}
				if (iHandValue > 21)
				{
					cout << "\nBust!  You lose!";	
					dMoney -= dBet;			//they lose...we get their money!
					bBust = true;
					break;
				}
				if (i == 5 && iHandValue <= 21)	//test the 5 card win rule
				{
					bFiveCardWin = true;
					cout << "\nFive cards, no bust, you win!";
					dMoney += dBet;
				}
				else
				{
					//weird looking way to make the Another Card always line up
					cout << setw(50 - (strlen(Card.m_Face) + strlen(Card.m_Suit) + 4)) 
						 << right << "Another card (y/n)? ";
					cin >> cAnother;
					cAnother = tolower(cAnother);//makes it easier to detect valid entry
					//sentinel loop (theres a lot of this same loop in this program.  I regret not
					//making a function out of it.
					while ((cAnother != 'y' && cAnother != 'n') || cin.rdbuf()->in_avail() > 1 || cin.fail())
					{
						cin.clear();
						cin.ignore(cin.rdbuf()->in_avail());
						cout << "Invalid Entry...\n";
						cout << "Another card (y/n)? ";
						cin >> cAnother;
					}
					//flush the buffer! 
					cin.ignore(cin.rdbuf()->in_avail());
					if (cAnother == 'n')
						break;
					}
			}
			if (bHasAce && (iHandValue <= 11)) //automatically make the ace work to your advantage
				iHandValue += 10;
				
			//Display the hand value
			cout << "\nHand Value: " << iHandValue << endl;
			if (i == 5 && iHandValue <= 21)
			{
				bFiveCardWin = true;
				cout << "\nFive cards, no bust, you win!";
				dMoney += dBet;
			}
			if (!bBust && !bBlackJack && !bFiveCardWin) //these 3 thinks mean the computer doesnt play
			{
				bHasAce = false;
				cout << "\nThe Computer will now play...";
				for (i = 0; i < 5; i++)
				{
					//**********************
					//computer algorithm begins
					//**********************
					iCardsPlayed++;				//increment the cards again
					DrawCard (Deck, CompCard);	//get a card for the computer
					cout << "\nCard " << i + 1 << ": ";
					ShowCard (CompCard);
					if (CompCard.is_ace)	//add a bit of strategy when the dealer gets an ace
					{						//so he will use it to his advantage (I'm pretty sure
											//thats part of the rules?  Makes it funner I think)
						bHasAce = true;
						iCompHandValue -= 10;
					}
					cout << endl;
					iCompHandValue += CompCard.m_Value;		//add the to computers hand value
					if (iCompHandValue > iHandValue && bHasAce)		//if he's got a better hand 
																	//with a low ace, he will continue
																	//to play with the ace as a 1
						bHasAce = false;
					//if he needs it to beat you, the computer will make an ace a 11
					if ((iCompHandValue <= 11) && (iCompHandValue < iHandValue) && bHasAce)
						iCompHandValue += 10;
					//standard house rules, dealer stays at 17
					if (iCompHandValue >= 17)
						break;
				}
				cout << "\nComputer Hand Value: " << iCompHandValue;
				
				//**********
				//hand comparison begins
				//***********
				if ((iHandValue > iCompHandValue) && iHandValue <= 21)
				{
					cout << "\nYou win $" << dBet << " !";
					dMoney += dBet;
				}
				else if (iCompHandValue > 21)
				{
					cout << "\nDealer busts, you win $" << dBet << " !";
					dMoney += dBet;
				}
				else if ((iCompHandValue > iHandValue) && iCompHandValue <= 21)
				{
					cout << "\nDealer wins !";
					dMoney -= dBet;
				}
				else if (iCompHandValue == iHandValue)
					cout << "\nPush!";
			}
			if (dMoney > 15) //if you have money, offer another hand, otherwise they get kicked out
			{
				cout << "\nYou now have $" << dMoney - 10 << "	would you like to play another hand (y/n) ?";
				//same loop again.  i use cAnother for all of em.  no point in wasting memory
				cin >> cAnother;
				cAnother = tolower(cAnother);
				while ((cAnother != 'y' && cAnother != 'n') || cin.rdbuf()->in_avail() > 1 || cin.fail())
				{
					cin.clear();
					cin.ignore(cin.rdbuf()->in_avail());
					cout << "Invalid Entry...\n";
					cout << "Another hand (y/n)? ";
					cin >> cAnother;
				}
				//clear the buffer
				cin.ignore(cin.rdbuf()->in_avail());
				cout << "\n\n\n\n\n\n\n";
			}
		} while (cAnother != 'n' && dMoney != 10.00);
		//load the deck into the game variable
		//and prepare the Game variable for saving
		if (dMoney > 15)
		{
			for (int ii = 0; ii < 52; ii++)
				Game.CurrentDeck[ii] = Deck[ii];
			Game.m_iCards = iCardsPlayed;
			Game.m_dCash = dMoney; 
			DoSave(Game);		//save game
		}
		else	//display a message if you run out of money
		{
			cout << "\nGame over!  You gambled away your savings!";
			cout << "\nYou don't have enough money to make a valid bet!";
			cin.get();
		}
	}
	else 
		//wait for input to quit
		cout << "\n\nPress enter to quit...";
		cin.ignore(cin.rdbuf()->in_avail());
		cin.get();
	return 0;
}
/*************************************************************************
Function:	 void DoLoad (SDeck Deck[], double &dMoney, int &iCards)
Paramaters:	 SDeck Deck[]	- The Deck structure for loading to
			 Double &dMoney - reference to the total money
			 int	iCards  - total cars played so far
Description: Loads a binary file into SGame, then from there disperses the deck,
			 money and cards to their respective variables
Returns:	 void
*************************************************************************/
void DoLoad (SDeck Deck[], double &dMoney, int &iCards)
{
	char cAnother;				//used in the y/n loop to load the game
	SGame Game;					//game struct holding all game status
	char szFileName[255] = {0};	//filename to load from
	ifstream InFile;			//file opened thats being loaded from
	cout << "Would you like to load a game (y/n)? ";	
	cin >> cAnother;
	cAnother = tolower(cAnother);//same sentinel again
	while ((cAnother != 'y' && cAnother != 'n') || cin.rdbuf()->in_avail() > 1 || cin.fail())
	{
		cin.clear();
		cin.ignore(cin.rdbuf()->in_avail());
		cout << "Invalid Entry...\n";
		cout << "Would you like to load a game (y/n)? ";
		cin >> cAnother;
		cAnother = tolower(cAnother);
	}
	//clear the buffers
	cin.clear();
	cin.ignore(cin.rdbuf()->in_avail());
	if (cAnother == 'y')
	{
		cout << "\nEnter filename to load from: ";
		cin.getline(szFileName, 255);
		if (!InFile.fail())
		{
			//open the file for reading and read in the structs size worth of bytes
			//which is (hopefully) all of them.
			InFile.open(szFileName, ios::in | ios::binary);
			InFile.read(reinterpret_cast<char*>(&Game), sizeof(SGame));
			InFile.close();
			//spread out the freshly loaded data
			Deck = Game.CurrentDeck;
			dMoney = Game.m_dCash;
			iCards = Game.m_iCards;
			cout << "\nGame loaded successfully!\n\n";
		}
		else	//error opening file
			cout << "\nError opening file...";
	}

	return;
}
/*************************************************************************
Function:	 void DoSave (SGame Game)
Paramaters:	 SGame Game - The game status all in one package
Description: Does a binary dump of all the game's status
Returns:	 void
*************************************************************************/
void DoSave (SGame Game)
{
	char cAnother;
	char szFileName[255] = {0};
	ofstream OutFile;			//open the file 
	cout << "\nWould you like to save(y or n)?";
	cin >> cAnother;
	cAnother = tolower(cAnother);		//some old loop
	while ((cAnother != 'y' && cAnother != 'n') || cin.rdbuf()->in_avail() > 1 || cin.fail())
	{
		cin.clear();
		cin.ignore(cin.rdbuf()->in_avail());
		cout << "Invalid Entry...\n";
		cout << "Would you like to save (y/n)? ";
		cin >> cAnother;
	}
	cin.ignore(cin.rdbuf()->in_avail());
	if (cAnother == 'y')
	{
		//get the filename to save to
		cout << "\nEnter filename to save to: ";
		cin.getline(szFileName, 255);
		//open it
		OutFile.open(szFileName, ios::out | ios::binary);
		if (!OutFile.fail())
		{
			//write all the bytes in the Game struct to the file
			OutFile.write(reinterpret_cast<char*>(&Game), sizeof(SGame));
			OutFile.close();
			cout << "File Saved Succeffully!";
		}
		else //access violation or no admin status might cause this
			cout << "\nError opening file for saving...";
	}
	return;
}
/*************************************************************************
Function:	 double GetDouble(char szDisplay[], double dMin, double dMax)
Paramaters:	 char	szDisplay[] - text to be displayed
			 double	dMin - minimum entry allowed
			 double dMax - maximum entry allowed
Description: Loads a double for the bet entry, with a sentinel
Returns:	 dValue
*************************************************************************/
double GetDouble(char szDisplay[], double dMin, double dMax)
{
	double dValue = 0;		//value to be input
	cout << szDisplay;
	cin >> dValue;
	//sentinel loop
	while (cin.fail() || cin.rdbuf()->in_avail() > 1 || dValue < dMin || dValue > dMax)
	{
		cin.clear();
		cin.ignore(cin.rdbuf()->in_avail());
		cout << "Invalid Bet...\n";
		cout << szDisplay;
		cin >> dValue;
	}
	cin.ignore(cin.rdbuf()->in_avail());
	return dValue;
}
/*************************************************************************
Function:	 void InitDeck(SDeck Deck [])
Paramaters:	 SDeck Deck [] - deck (array of cards) to be initialized
Description: Loads all the cards from the card txt file.  Hardcoded max of
			 52 cards.  I guess this could be made dynamic if a custom/more
			 decks were wanted to be used
Returns:	 void
*************************************************************************/
bool InitDeck(SDeck Deck [])
{
	bool bNoError = true;
	ifstream InFile;
	InFile.open(DECKLOCATION);  //uses the hardcoded constant DECKLOCATION location
	if (!InFile.fail())
	{
		for (int i = 0; i < 52; i++)
		{
			//load the values
			InFile >> Deck[i].m_Suit >> Deck[i].m_Face >> Deck[i].m_Value;
			Deck[i].is_used = false;		//not in use, default not an ace
			Deck[i].is_ace = false;
			if (Deck[i].m_Value == 11)		//ace detection
				Deck[i].is_ace = true;		//use this for clarity in other ace
											//detections
		}
		
	}
	else		//couldnt find the file
	{
		cout << "Error!\nFile: " << DECKLOCATION << " could not be opened.\nThere's n o Deck to be used!\n";
		bNoError = false;
	}
	InFile.close();
	return bNoError;
}
/*************************************************************************
Function:	 void ShowCard(const CARD Card)
Paramaters:	 const CARD Card - the card, constant for safety
Description: Show the card in a more readable form
Returns:	 dValue
*************************************************************************/
void ShowCard(const CARD Card)
{
	cout << Card.m_Face << " of " << Card.m_Suit;
	return;
}

/*************************************************************************
Function:	 void DrawCard(SDeck Deck[], CARD &Card)
Paramaters:	 SDeck Deck[] - the deck to be drawn from
			 CARD &Card - the card to draw, passed by reference
Description: Randomly draws a card from the deck to be used int he game
Returns:	 void
*************************************************************************/
void DrawCard(SDeck Deck[], CARD &Card)
{    
	int iRandomIndex;		//index to try and use
	do
	{
		iRandomIndex = GetRand(0, 51); //makes a random number to be used as an index
		Card = Deck[iRandomIndex]; //sets the card to the card at that index in the deck
	} while (Deck[iRandomIndex].is_used);	//makes sure that card isnt in use
	Deck[iRandomIndex].is_used = true;		//set the card in use flag 	
	Card.is_used = true;					//not really used for anything...but set to 
											//be safe

	return;
}
/*************************************************************************
Function:	 int GetRand(int iMin, int iMax)
Paramaters:	 int iMin - minimum number 
			 int iMax - maximum number
Description: Generates a random integer between iMin and iMax
Returns:	 iResult - the random number...
*************************************************************************/
int GetRand(int iMin, int iMax)
{
	int iResult;
	//the seed was set in main, since it only needs to be set once
	iResult = iMin + rand()%(iMax - iMin + 1);  //generate the number
	return iResult;
}

Awesome thanks man I really appreciate it. This is a beginners class im in so i actually can only use the arbitrary array, but i imagine i can find out another way to do this based off some of your stuff

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.