Solved Blackjack Game Help

Hexui Undetected CSGO Cheats Sinkicheat PUBG Cheat

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
So I'm having problem with this code:
C++:
//Blackjack
//Plays a simple version of the casino game of blackjack; for 1 - 7 players

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <ctime>
using namespace std;

class Card
{
public:
	enum rank { ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING };
	enum suit{ CLUBS, DIAMONS, HEARTS, SPADES };

	// overloading << operator so can send Card object to standard output
	friend ostream& operator<<(ostream& os, const Card& aCard);

	Card(rank r = ACE, suit s = SPADES, bool ifu = true);

	// return the value of a card, 1-11
	int GetValue() const;

	// flips a card; if face up, becomes face down and vice versa
	void Flip();

private:
	rank m_Rank;
	suit m_Suit;
	bool m_IsFaceup;
};

Card::Card(rank r, suit s, bool ifu) : m_Rank(r), m_Suit(s), m_IsFaceup(ifu)
{}

int Card::GetValue() const
{
	// if a cards is face down, it's value is 0
	int value = 0;
	if (m_IsFaceup)
	{
		// value is number showing on card
		value = m_Rank;
		// value is 10 for face cards
		if (value > 10)
		{
			value = 10;
		}
	}

	return value;
}

void Card::Flip()
{
	m_IsFaceup = !(m_IsFaceup);
}

class Hand
{
public:
	virtual ~Hand();

	// adds a card to the hand
	void Add(Card* pCard);

	// clears hand of all cards
	void Clear();

	// gets total value, intelligently treats ace as 1 or 11
	int GetTotal() const;
protected:
	vector<Card*> m_Cards;
};

Hand::Hand()
{
	m_Cards.reserve(7);
}

Hand::~Hand()
{
	Clear();
}

void Hand::Add(Card* pCard)
{
	m_Cards.push_back(pCard);
}

void Hand::Clear()
{
	// iterate through vector, freeing all memory on the heap
	vector<Card*>::iterator iter = m_Cards.begin();
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
	{
		delete *iter;
		*iter = 0;
	}

	// clear vector of pointers
	m_Cards.clear();
}

int Hand::GetTotal() const
{
	// if no cards in hand, return 0
	if (m_Cards.empty())
	{
		return 0;
	}

	// if a first card has value of 0, then card is face down; return 0
	if (m_Cards[0]->GetValue() == 0)
	{
		return 0;
	}

	// adds up card values, treat each ace as 1
	int total = 0;
	vector<Card*>::const_iterator iter;
	for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
	{
		total += (*iter)->GetValue();
	}

	// determine if hand contains an ace
	bool containsAce = false;
	for (iter = m_Cards.begin(); iter != m_Cards.begin(); ++iter)
	{
		if ((*iter)->GetValue() == Card::ACE)
		{
			containsAce = true;
		}

	}

	// if hand contains ace and total is low enough, treat ace as 11
	if (containsAce && total <= 11)
	{
		// add only 10 since we've already added 1 for the ace
		total += 10;
	}

	return total;

}

class GenericPlayer : public Hand
{
	friend ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer);

public:
	GenericPlayer(const string& name = "");

	virtual ~GenericPlayer();

	// indicates whether or not generic player wants to keep hitting
	virtual bool IsHitting() const = 0;

	// return whether generic player has busted - has a total greater than 21
	bool isBusted() const;

	// announces that the generic player busts
	void Bust() const;

protected:
	string m_Name;
};

GenericPlayer::GenericPlayer(const string& name):
m_Name(name)
{}

GenericPlayer::~GenericPlayer()
{}

bool GenericPlayer::isBusted() const
{
	return (GetTotal() > 21);
}

void GenericPlayer::Bust() const
{
	cout << m_Name << " busts.\n";
}

class Player : public GenericPlayer
{
public:
	Player(const string& name = "");
	
	virtual ~Player();

	// returns whether or not the player wants another hit
	virtual bool IsHitting() const;

	// announces that the player wins
	void Win() const;

	// announces that the player loses
	void Lose() const;

	// announces that the player pushes
	void Push() const;
};

Player::Player(const string& name):
	GenericPlayer(name)
{}

bool Player::IsHitting() const
{
	cout << m_Name << " , do you want a hit? (Y/N)?: ";
	char response;
	cin >> response;
	return (response == 'y' || response == 'Y');
}

void Player::Win() const
{
	cout << m_Name << " wins.\n";
}

void Player::Lose() const
{
	cout << m_Name << " loses.\n";
}

void Player::Push() const
{
	cout << m_Name << " pushes.\n";
}

class House : public GenericPlayer
{
public:
	House(const string& name = "House");

	virtual ~House();

	// indicates whether house is hitting - will always hit on 16 or less
	virtual bool IsHitting() const;

	// flips over first card
	void FlipFirstCard();
};

House::House(const string& name):

GenericPlayer(name)
{}

House::~House()
{}

bool House::IsHitting() const
{
	return (GetTotal() <= 16);
}

void House::FlipFirstCard()
{
	if(!(m_Cards.empty))
	{
		m_Cards[0]->Flip();
	}
	else
	{
		cout << "No card to flip!\n";
	}
}

class Deck : public Hand
{
public:
	Deck();

	virtual ~Deck();

	// create a standard deck of 52 cards
	void Populate();

	// shuffle cards
	void Shuffle();

	// deal one card to a hand
	void Deal(Hand& aHand);

	// give additional cards to a generic player
	void AdditionalCards(GenericPlayer& aGenericPlayer);
};

Deck::Deck()
{
	m_Cards.reserve(52);
	Populate();
}

Deck::~Deck()
{}

void Deck::Populate()
{
	Clear();
	// create standard deck
	for (int s = Card::CLUBS; s <= Card::SPADES; ++ s)
	{
		for (int r = Card::ACE; r <= Card::KING; ++r)
		{
			Add(new Card(static_cast<Card::rank>(r),
				static_cast<Card::suit>(s)));
		}
	}
}

void Deck::Shuffle()
{
	random_shuffle(m_Cards.begin(), m_Cards.end());
}

void Deck::Deal(Hand& aHand)
{
	if (!m_Cards.empty())
	{
		aHand.Add(m_Cards.back());
		m_Cards.pop_back();
	}

	else
	{
		cout << "Out of cards. Unable to deal.";
	}
}

void Deck::AdditionalCards(GenericPlayer& aGenericPlayer)
{
	cout << endl;
	// continue to deal a card as long as generic player isn't busted
	// and wants another hit

	while (!(aGenericPlayer.isBusted()) && aGenericPlayer.IsHitting() )
	{
		Deal(aGenericPlayer);
		cout << aGenericPlayer << endl;

		if(aGenericPlayer.isBusted())
		{
			aGenericPlayer.Bust();
		}
	}
}

class Game
{
public:
	Game(const vector<string>& names);
	~Game();

	// plays the game of blackjack
	void Play();
private:
	Deck m_Deck;
	House m_House;
	vector<Player> m_Players;
};

Game::Game(const vector<string>& names)
{
	// create a vector of players from a vector of names
	vector<string>::const_iterator pName;
	for(pName = names.begin(); pName != names.end(); ++pName)
	{
		m_Players.push_back(Player(*pName));
	}

	// seed the random number generator
	srand(static_cast<unsigned int>(time(0)));
	m_Deck.Populate();
	m_Deck.Shuffle();
}

Game::~Game()
{}

void Game::Play()
{
	// deal 2 initial cards to everyone
	vector<Player>::iterator pPlayer;
	for (int i = 0; i < 2; ++i)
	{
		for (pPlayer = m_Players.begin(); pPlayer != m_Players.end();
			++pPlayer)
		{
			m_Deck.Deal(*pPlayer);
		}
			m_Deck.Deal(m_House);
	}

	// hides house's first card
	m_House.FlipFirstCard();

	// display everyone's hand
	for(pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)
	{
		cout << *pPlayer << endl;
	}

	cout << m_House << endl;

	// deal additional cards to players
	for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)
	{
		m_Deck.AdditionalCards(*pPlayer);
	}

	// reveal house's first card
	m_House.FlipFirstCard();
	cout << endl << m_House;

	// deal additional cards to house
	m_Deck.AdditionalCards(m_House);

	if(m_House.isBusted())
	{
		// everyone still playing wins
		for(pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)
		{
			if( !(pPlayer->isBusted()))
			{
				pPlayer->Win();
			}
		}
	}

	else
	{
		// compare each player still playing to house
		for (pPlayer = m_Players.begin(); pPlayer != m_Players.end();)
		{
			if( !(pPlayer->isBusted()))
			{
				if (pPlayer->GetTotal() > m_House.GetTotal())
				{
					pPlayer->Win();
				}
				else if(pPlayer->GetTotal() < m_House.GetTotal())
				{
					pPlayer->Lose();
				}
				else
				{
					pPlayer->Push();
				}
			}
		}
	}

	// removes everyone's cards
	for(pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)
	{
		pPlayer->Clear();
	}
	m_House.Clear();
}

// function prototypes
ostream& operator<<(ostream& os, const Card& aCard);
ostream& operator<<(ostream os, const GenericPlayer& aGenericPlayer);

int main()
{
	cout << "\t\tWelcome to Blackjack!\n\n";

	int numPlayers = 0;
	while(numPlayers < 1 || numPlayers > 7)
	{
		cout << "How many players? (1-7): ";
		cin >> numPlayers;
	}

	vector<string> names;
	string name;
	for (int i = 0; i < numPlayers; ++i)
	{
		cout << "Enter player name: ";
		cin >> name;
		names.push_back(name);
	}

	cout << endl;

	// the game loop

	Game aGame(names);
	char again = 'y';
	while(again != 'n' && again != 'N')
	{
		aGame.Play();
		cout << "\nDo you want to play again? (Y/N): ";
		cin >> again;
	}

	return 0;
}

// overloads << operator so Card object can be sent to cout
ostream& operator<<(ostream& os, const Card& aCard)
{
	const string RANKS[] = {"0","A","2","3","4","5","6","7","8","9","10,","J","Q","K"};
	
	const string SUITS[] = {"c","d","h","s"};

	if(aCard.m_IsFaceup)
	{
		os << RANKS[aCard.m_Rank] << SUITS[aCard.m_Suit];
	}

	else
	{
		os << "XX";
	}

	return os;
}

// overloads << operator so a GenericPlayer object can be sent to cout
ostream operator<<(ostream& os, const GenericPlayer& aGenricPlayer)
{
	os << aGenricPlayer.m_Name << ":\t";

	vector<Card*>::const_iterator pCard;
	if (!aGenricPlayer.m_Cards.empty())
	{
		for(pCard = aGenricPlayer.m_Cards.begin();
			pCard != aGenricPlayer.m_Cards.end();
			++pCard)
		{
			os << *(*pCard) << "\t";
		}
	}

	if(aGenricPlayer.GetTotal() != 0)
	{
		cout << "(" << aGenricPlayer.GetTotal() << ")";
	}

	else
	{
		os << "<empty";
	}

	return os;
}
And I get these compiler errors, I'm rather new to classes and have googled my arse off but no avail.

C++:
1>------ Build started: Project: Blackjack Game, Configuration: Debug Win32 ------
1>  Source.cpp
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(78): error C2600: 'Hand::Hand' : cannot define a compiler-generated special member function (must be declared in the class first)
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(174): error C2264: 'Hand::Hand' : error in function definition or declaration; function not called
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(265): error C2276: '!' : illegal operation on bound member function expression
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(296): error C2264: 'Hand::Hand' : error in function definition or declaration; function not called
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(530): error C2556: 'std::ostream operator <<(std::ostream &,const GenericPlayer &)' : overloaded function differs only by return type from 'std::ostream &operator <<(std::ostream &,const GenericPlayer &)'
1>          c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(152) : see declaration of 'operator <<'
1>c:\users\admin\documents\visual studio 2012\projects\blackjack game\blackjack game\source.cpp(530): error C2040: 'operator <<' : 'std::ostream (std::ostream &,const GenericPlayer &)' differs in levels of indirection from 'std::ostream &(std::ostream &,const GenericPlayer &)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
C++:
class Hand
{
public:
    virtual ~Hand();

    Hand();
 
    // adds a card to the hand
    void Add(Card* pCard);
 
    // clears hand of all cards
    void Clear();
 
    // gets total value, intelligently treats ace as 1 or 11
    int GetTotal() const;
protected:
    vector<Card*> m_Cards;
};
 
Hand::Hand()
{
    m_Cards.reserve(7);
}
You have to declare the constructor before using it. As for the rest, I'm not sure.
 

Solaire

Respected Hacker
Dank Tier VIP
Dec 15, 2013
1,051
16,353
62
Yeah haha, I'm glad I stopped before classes :p. Just check out cplusplus.com and review. Now that you're this far, everything there that's new will be pretty easy to catch on to.

Good luck! :)
 

TheGreatUnknown

Jr.Coder
Full Member
Nobleman
Dec 20, 2012
58
417
1
Cheers mate, you've always been a great help :) I'll think of games to make using classes while reading up on them. I know the basics as you said, so not long before I understand classes. Cheers once again :)
 
Attention! Before you post:

Read the How to Ask Questions Guide
99% of questions are answered in the Beginner's Guide, do it before asking a question.

No Hack Requests. Post in the correct section.  Search the forum first. Read the rules.

How to make a good post:

  • Fill out the form correctly
  • Tell us the game name & coding language
  • Post everything we need to know to help you
  • Ask specific questions, be descriptive
  • Post errors, line numbers & screenshots
  • Post code snippets using code tags
  • If it's a large project, zip it up and attach it

If you do not comply, your post may be deleted.  We want to help, please make a good post and we will do our best to help you.

Community Mods