10 Replies - 1382 Views - Last Post: 05 June 2012 - 03:40 AM Rate Topic: ***-- 1 Votes

#1 Atrixium  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 03-June 12

Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 12:46 PM

First off I'm a beginner programmer so please bear with me. I thought I was doing really well until I reached the last example program of the text I'm reading (Beginning C++ Game Programming). I transcribe all the code from the text into my IDE manually so it is possible I've made a typo and I fully expected to make a few typos and then have bugs to correct, I find I learn concepts better this way. In this case however I've gone over the text dozens of times and I cannot find the bug so I'm thinking this now might be an error in the text itself. The most frustrating part is that I can't find the bug when I step through the logic, it seems like it should be working!

In any event, the game seems to work fine for a hand or two but will eventually spit out a bunch of crap to the terminal, an example of said crap has been included below the code.

I think the problem is in the code that prints the contents of the hand to the terminal. It seems to me that the program is sending either a dangling pointer to cin or the function is trying to print a pointer that has been incremented into an unspecified memory address. The reason that I think it's one of those is because the program craps out while attempting to display every players hand and the subsequent contents definitely contain portions of my source code.

If anyone could help me understand what is happening here I would greatly appreciate it!



//Blackjack
//Plays a simple version of Blackjack

#include <iostream>
#include <string>
#include <vector>
#include <algorithm> //included for random_shuffle()
#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, DIAMONDS, HEARTS, SPADES};
    //overloading << operator so we can send Card objects to standard out
    friend ostream& operator<<(ostream& os, const Card& aCard);

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

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

    //flips a card; if facing up it 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 card 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:
    Hand();

    virtual ~Hand();

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

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

    //gets hand total value, intelligently treats aces as 1 or 11
    int GetTotal() const;

protected:
    vector<Card*> m_Cards;
};

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

Hand::~Hand() //don't use the keyword virtual outside of class definition
{
    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 a value of 0, then card is face down; return 0
    if (m_Cards[0]->GetValue() == 0)
        return 0;

    //add up card values, treat each ace as a 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.end(); ++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 of not the generic player wants to keep hitting
    virtual bool IsHitting() const = 0;

    //returns whether a 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)
{}

Player::~Player()
{}

bool Player::IsHitting() const
{
    cout << m_Name << ", do you want to 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));

    srand(time(0));     //seed the random number generator
    m_Deck.Populate();
    m_Deck.Shuffle();

}

Game::~Game()
{}

void Game::Play()
{
    //deal initial 2 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);
    }

    //hide 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(); ++pPlayer)
            if ( !(pPlayer->IsBusted()) )
            {
                if (pPlayer->GetTotal() > m_House.GetTotal())
                    pPlayer->Win();
                else if (pPlayer->GetTotal() < m_House.GetTotal())
                    pPlayer->Lose();
                else
                    pPlayer-> Push();
            }
    }

    //remove 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' || '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","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& aGenericPlayer)
{
    os << aGenericPlayer.m_Name << ":\t";

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

        if (aGenericPlayer.GetTotal() != 0)
            cout << "(" << aGenericPlayer.GetTotal() << ")";
    }
    else
    {
        os << "<empty>";
    }
        return os;
}





Output Sample

		Welcome to Blackjack!

How many players? (1 -7): 1
Enter player name: Rob

Rob:	As	Ah	(12)
House:	XX	6h	

Rob, do you want to hit? (Y/N): y
Rob:	As	Ah	2h	(14)
Rob, do you want to hit? (Y/N): y
Rob:	As	Ah	2h	Ad	(15)
Rob, do you want to hit? (Y/N): y
Rob:	As	Ah	2h	Ad	H�H9��H��[��UH��H�}�H�u�H�E�H�H�E�H���UH��H�}�H�E���UH��H�� H�}�H�u�H�E�H�H�E�H�H��H�H�E�H�U�H�E�H��H�������H�E���UH��SH��H�}�H�u�H�E�H�������H�H��H�E�H�������H�H��H)�H��H��H��[��UH��H�� H�}�H�u�H�U�H�E�H��H�����UH��H�� H�}�H�u�H�E�H�H�E�H�H��H��H�H�E�H�U�H�E�H��H���UH��ATSH��H�}�H�E�H�@H��H�E�H�H��H)�H��H��H��H���������H��H��H�E�HH�E�H��H�H�E�H���h���H��[A\�É�I��H�E�H���N���L��Hc�H�������UH��H�}�H�E���UH��H�� H�}�H�u�ĞUH��H�}�H�u�H�E�H�H�E�H���UH��H�}�H�E���UH��H��H�}�H�u�H�E�H��o@H�E�H�H�E�H��UH��ATSH��H�}�H�u�H�U�H�E�H��H�������H�E�H��o@H�E�H�P H�E�H�� H��H���R������I��H�E�H���c���L��Hc�H�������H��[A\��UH��H��H�}�H�u�H�U�H�E�H��H���g���H�E�H�po@��UH��AVAUATSH�� H�}�H�u�H�U�L�e�L���(�����H��H��H��t3H��H�U�H��H��������A��IH�E��ĞUH��H��H�}�H�u�H�U�H�E�H��H�������H�E�H�P H�E�H�� H��H�������H�E���UH��H��H�}�H�u�H�U�H�E�H��H�������H�E��ĞUH��ATSH�ĀH�}�H�u�H��x���H�E�H�H�E�H�@H9��H�E�H�H�P�H�E�H�H�E�H��H�������H�E�H�H�P(H�E�H�H��x���H�E�H��H���8���H�E�H�L�`�H�E�H�H�X�H�E�H����H�L��H��H����
                              H�E�H�������H�U�H��H������H�E�H��������p��I��H�EH�E�H�E�H�������H�E�H�U�H�E�H��H���gH�E�H�E�H�U�H��H��H�E�H�E�H�E�H�U�H��H��H�H��H��HM�H�E�H��x���H��H���Y���H�E�H�E�H������I��H�E�H����H�H�E�H�H�U�L��H��H���fH�E�H�E�(H�E�H�������I��H�E�H�H�E�H���|H�H�U�L��H��H���%H�E�H�E�H�������H��H�E�H�H�E�H�H��H���z���H�E�H�@H��H�E�H�H��H)�H��H��H��H���������H��H��H�E�HH�E�H��H���H�E�H�U�H�H�E�H�U�H�H�U�H��H��H�H��H��HU�H�E�H�P� H���&���H�}�u*H�"H�E�H�������H��H�M�H�E�H��H�������H�E�H�U�H�M�H��H��
�w�����I���}���L��Hc�H�������H���[A\��UH��H�}�H�u�H�E�H�H�E�H���UH��H�}�H�E�����UH��H��H�}�H�E�H����
                       ��UH��ATSH��H�}�H�E�H�@H��H�E�H�H��H)�H��H��H��H�E�HH�E�H��H����
����UH��H�}�H�E���UH��H�� H�}�H�u�H�U�H�U�H�E�H��H������
                                                      �ĞUH��AVAUATSH�� H�}�H�u�H�U�L�e�L���m���H��H��H��t3H��H�U�H��H���+����A��I��L��H���O���L��Ic�H���j���H�� [A\A]A^�ĞUH��ATSH��`H�}�H�u�H�U�H�E�H�H�E�H�@H9��H�E�H�H�P�H�E�H�H�E�H��H���5���H�E�H�H�H�E�H�H�U�H�E�H��H�������H�E�H�L�`�H�E�H�H�X�H�E�H����
                                                                H�L��H��H����
                                                                             H�E�H����
      H�U�H��H�������H�E�H���v����>��I��H�E�H���`���L��Hc�H���b���H�E���n@�H����
  H�E�H�E�H���t
               H�E�H�U�H�E�H��H����
                                   H�E�H�E�H�U�H��H����
                                                       H�E�H�E�H�E�H�E�H��H��HM�H�E�H�U�H��H���
                 ���H�E�H�E�H�������I��H�E�H���
H�H�E�H�H�U�L��H��H���}
                        H�E�H�EH�E�H�������I��H�E�H�H�E�H���}
H�H�U�L��H��H���<
                 H�E�H�E�H���D���H��H�E�H�H�E�H�H��H���5���H�E�H�@H��H�E�H�H��H)�H��H��H��H�E�HH�E�H��H����	H�E�H�U�H�H�E�H�U�H�H�E�H��H��HU�H�E�H�P��H���p���H�}�u H�E�H��H��HU�H�E�H��H����
                                       �"H�E�H�������H��H�M�H�E�H��H���y���H�E�H�U�H�M�H��H��	�˾����I���ѿ��L��Hc�H���C���H��`[A\��UH��H�� H�}�H�E�H�H�E�H��H���M
  H�E��ĞUH��H��H�}�H�E�H���J
                             H�E�H�H�E�H�H�E�H�@�ĞUH��H��H�}�H�E�H���&
                                                                        ��UH��H��H�}�H�u�H�U�H�E�H��H���

                         �ĞUH��H�}�H�E���UH��H�}�H����������UH��H��H�}�H�u�H�}�tH�E�H�M��H��H���
����UH��H�� H�}�H�u�H�U�H�M�H�U�H�M�H�E�H��H���
�ĞUH��H�� H�}�H�u�H�U�H�E�H���F�����UH��SH��(H�}�H�u�H�U�H�E�H��
H��H�E�H��
H�U�H��H��
H��([��UH��SH��8H�}�H�u�H�U�H�E�H�������H��H�E�H������H��H)�H�E�H9����t
                                                                        H�E�H���~���H�E�H�������H��H�E�H�������H�E�H�U�H�E�H��H���~
H�H�H�E�H�E�H�������H;E�wH�E�H���W���H;E�sH�E�H���E����H�E�H��8[��UH��SH��(H�}�H�u�H�U�H�M�H�M�H�U�H�]�H�E�H��H���h���H��([��UH��SH��(H�}�H�u�H�E�H���6���H��H�E�H���'���H��H����	H��([�ĞUH��H��H�}�H�E�H���
H�E�H�H�E�H�H�E�H�@�ĞUH��H��H�}�H�E�H����	��UH��H�� H�}�H�u�H�U�H�}�tH�E�H�U�H�M�H��H����	��UH��H��H�}�H�u�H�U�H�E�H��H����	�ĞUH��AUATSH��H�}�H�u�H�E�H�������H��H�E�H���(���H��H�E�H��H��H����	H�E�H�������I��H�E�L� H�E�H�������H��H�E�H�������L��L��H��H����	H�U�H�H��[A\A]�É�I��H�E�H�������L��Hc�H�������UH��SH��(H�}�H�u�H�U�H�E�H����	H��H�E�H����	H�U�H��H����	H��([�ĞUH��AVAUATSH�� H�}�H�u�H�E�H;E�
                              H�E�H���'���H�E�H�E�H�������H;E�����H�E�H�������I��H�E�H�������H��H�]�H�E�L��H��H����	H�E�H�E�H���@���H��H�E�H�H�E�H�H��H���1���H�E�H�@H��H�E�H�H��H)�H��H��H��H�E�HH�E�H��H���;���H�E�H�U�H�H�E�H�H�U�H��H�H�E�H�P�H�E�H���8���H;E����tiH�E�H�������I��H�E�H�������H��H�E�H���a���I��H�E�H�������I��H�E�H�������L��L��H���0	L��H��H���h	��H�E�H�H�E�L� H�E�H�������H��I�
          H�E�H�H��H��H���U	H�E�H�������I��H�E�L�H�E�H�H�E�L�0H�E�H���[���H��I�L��L��H��H���Z���H�E�H�H�U�H��H�H�E�H�H�E�H�� [A\A]A^��UH��SH��8H�}�H�u�H�U�H�E�H���=	H��H�E�H���H��H)�H�E�H9����t
                                            H�E�H���F���H�E�H���H��H�E�H���H�E�H�U�H�E�H��H���FH�H�H�E�H�E�H���H;E�wH�E�H���H;E�sH�E�H����H�E�H��8[��UH��SH��H�}�H�u�H�E�H�������H�H��H�E�H�������H�H��H)�H��H��H��H���������H��H��[�ĞUH��H��H�}�H�u�H�}�tH�E�H�M��H��H�������UH��SH��(H�}�H�u�H�U�H�M�H�M�H�U�H�]�H�E�H��H���H��([�ĞUH��H��H�}�H�u�H�E�H�H�H�E�H�����ĞUH��H��H�}�H�E�H���H�E�H�H�E�H�H�E�H�@�ĞUH��H��H�}�H�E�H���UH��H�� H�}�H�u�H�U�H�}�tH�E�H�U�H�M�H��H������UH��H��H�}�H�u�H�U�H�E�H��H�����ĞUH��H�}�H�E���UH��SH��(H�}�H�u�H�U�H�E�H����H��H�E�H����H�U�H��H����H��([��UH��H�}�H�E�H��ĞUH��SH��8H�}�H�u�H�U�H�E�H��H��H�E�H����H��H)�H�E�H9����t
                      H�E�H���r���H�E�H����H��H�E�H����H�E�H�U�H�E�H��H���rH�H�H�E�H�E�H���yH;E�wH�E�H����H;E�sH�E�H����H�E�H��8[��UH��H�� H�}�H�U�H�E�H��H����H�E���UH��SH��H�}�H�u�H�E�H�����H�H��H�E�H���|���H�H��H)�H��H��H��[�ĞUH��H��H�}�H�u�H�}�tH�E�H�M��H��H��������UH��SH��(H�}�H�u�H�U�H�M�H�M�H�U�H�]�H�E�H��H���H��([�ĞUH��H��H�}�H�u�H�E�H��輳����UH��H�}�H�u�H�E�H�H�E�H���UH��H��H�}�H�E�H������UH��H�}���UH��H�}�H�u���UH��H�� H�}�H�u�H�U�H�E�H�������H;E���H�����t�ӳ��H�E�H��H���#�����UH��H�� H�}�H�u�H�U�H�U�H�M�H�E�H��H���X��UH��H�}�H�E���UH��ATSH�� H�}�H�u�H�U�H�E�H���RI��H�E�H���CH��H�E�H���4L��H��H���4H�� [A\��UH��H�}�H�u�H�E�H�H�E�H�H9�sH�E��H�E���UH��H�}�H�u�H�E�H�H�E�H�E�H�H�E�H�H�E�H�U�H��ĞUH��H��H�}�H�E�H������UH��H�}���UH��H�� H�}�H�u�H�U�H�E�H���\�����UH��H��H�}�H�u��H�E�H����H�E�(H�E�H;E����u���UH��ATSH�� H�}�H�u�H�U�H�E�H�U�H��H����H�U�H�E�H��H������H�U�H�H�E�H�H�E�H�H�E�H�H�U�H��H�H�E�H�PH�� [A\�É�I��H�E�H�������L��Hc�H���0���UH��H��0H�}�H�u�H�U�H�M�H�U�H�M�H�E�H��H���3��UH��H�}�H�E���UH��ATSH�� H�}�H�u�H�U�H�E�H���-I��H�E�H���H��H�E�H��L��H��H��H�� [A\�ĞUH��ATSH��@H�}�H�u�H�U�H�M�H�E�H�U�H��H�������H�E�H�E�H�������H��H�U�H�]�H�E�H��H������H�E�H��@[A\��H���۰��H�E�H�U�H�M�H��H�������������I��腰��L��Hc�H�������UH��SH��8H�}�H�u�H�U�H�E�H���tH��H�E�H���eH�U�H��H���dH��8[��UH��H��0H�}�H�u�H�U�H�U�H�E�H��H������UH��SH��(H�}�H�u�H�U�H�E�H���c���H��H�E�H���T���H�U�H��H����H��([��UH��H�}�H�E�H�H��H�E�H�H��H)�H��H��H��H���������H����UH��H��H�}�H�E�H����H������UH��H�� H�}�H�u�H�U�H�E�H���pH;E���H�����t�=���H�U�H��H��H�H��H��胯����UH��H�� H�}�H�u�H�U�H�M�H�U�H�M�H�E�H��H��� ��UH��H��H�}�H�E�H���4��UH��H�}���UH��H�� H�}�H�u�H�U�H�E�H���|�����UH��H��H�}�H�u��H�E�H����H�EH�E�H;E����u���UH��H�}�H�E���UH��ATSH�� H�}�H�u�H�U�H�E�H����I��H�E�H����H��H�E�H����L��H��H����H�� [A\��UH��H�}�H�E�H�H��H�E�H�H��H)�H��H���ĞUH��H��H�}�H�E�H���H������UH��H�� H�}�H�u�H�U�H�E�H���rH;E���H�����t苭��H�E�H��H���ۭ����UH��H�� H�}�H�u�H�U�H�M�H�U�H�M�H�E�H��H���,��UH��H�}���UH��H�� H�}�H�u�H�U�H�U�H�M�H�E�H��H���������UH��H�}�H�E���UH��H��0H�}�H�u�H�U��E�H�U�H�M�H�E�H��H������UH��H�}���UH��H��H�}�H�E�H�H�H�E�H�����ĞUH��H��H�}�H�u�H�E�H�U�H��H����H�E�H�H�E�H�H�E�H�@��UH��H��0H�}�H�u�H�U�H�U�H�M�H�E�H��H������UH��H�}�H�E���UH��H��0H�}�H�u�H�U��E�H�U�H�M�H�E�H��H������UH��H�}�H�E���UH��ATSH��@H�}�H�u�H�U�H�H�E�H�U�H�E�H��H�������H�E�H��@[A\��UH��H�� H�}�H�u�H�U�H�E�H��H������UH��ATSH�� H�}�H�u�H�U�H�E�H������I��H�E�H���	���H��H�E�H�������L��H��H����H�� [A\��UH��H�}�H�E���UH��H�}�H�fffffff��UH��H�� H�}�H�u�H�U�H�U�H�M�H�E�H��H����ĞUH��H�}���UH��H��H�}�H�E�H���������UH��H�}�H�E���UH��H��0H�}�H�u�H�U��E�H�U�H�M�H�E�H��H�����ĞUH��H�}�H�E���UH��H�}�H����������UH��H�� H�}�H�u�H�U�H�U�H�M�H�E�H��H����UH��H��0H�}�H�u�H�U�H�U�H�E�H��H)�H��H��H�E�H�E�H��H�E�H��H��HE�H�M�H��H���*���H�E�H��H��HE��ĞUH��H��H�}�H�u�H�U�H�E�H��H���Q��UH��H��0H�}�H�u�H�U�H�U�H�M�H�E�H��H���2��UH��H��0H�}�H�u�H�U�H�U�H�E�H��H)�H��H��H��H���������H��H�E��"H�m�(H�m�(H�U�H�E�H��H�������H�m�H�}�����u�H�E���UH��H��H�}�H�E�H�������H���UH��H��H�}�H�E�H�������H���UH��H��0H�}�H�u�H�U��E�H�U�H�M�H�E�H��H������UH��H�}�H�u���UH��H��0H�}�H�u�H�U��E�H�U�H�M�H�E�H��H���Z��UH��AVAUATSH��0H�}�H�u�H�U�H�E�H�E��nL�e�L���(����H��H��H��tHH��H�U�H��H��������4A��I��L��H�������L��Ic�H���ħ��H�U�H�E�H��H���3����*H�E�(H�E�(H�E�H;E����u�H�E�H��0[A\A]A^���@�����I���F���L��Hc�H��踧��UH��H��0H�}�H�u�H�U�H�U�H�E�H��H)�H��H��H�E��"H�mH�mH�U�H�E�H��H���|���H�m�H�}�����u�H�E���UH��AVAUATSH��0H�}�H�u�H�U�H�E�H�E��nL�e�L�������H��H��H��tHH��H�U�H��H��袥���4A��I��L��H�������L��Ic�H��葦��H�U�H�E�H��H����������I������L��Hc�H��腦���UH��H�}�H�u���UH��SH��8H�}�H�u�H�U�H�E�H�������H��H�E�H�������H�U�H��H���jH��8[��UH��H�� H�}�H�u�H�U�H�U�H�E�H��H)�H��H��H��H�M�H�E�H��H���
        ���H�U�H�E�H��H)�H��H��H��HE���UH��ATSH��0H�}�H�u�H�U�H�E�H���)���I��H�E�H���i���H��H�E�H���Z���L��H��H�������H��0[A\���������������fffff.�H�l$�L�d$�H�-A L�%A L�l$�L�t$�L�|$�H�\$�H��8L)�A��I��H��I�����H��t1@L��L��D��A��H��H9�r�H�\H�l$L�d$L�l$ L�t$(L�|$0H��8������UH��SH�H��@ H���t���`DH���H�H���u�H�[��H�����H�� Busts.
, do you want to hit? (Y/N):  wins.
 loses.
 pushes.
No card to flip!
Out of cards. Unable to deal.House		Welcome to Blackjack!

How many players? (1 -7): Enter player name: 
Do you want to play again? (Y/N): 0A23456789JQKcdhsXX:		()<empty>vector::reservevector::_M_insert_auxp@�@�@ p@�@�@@@p@�@@`p@�@4@@�p@F@�@г`p@�p@4Deckг`8p@`p@5Houseг`Xp@`p@6Playerг`�p@�p@13GenericPlayerP�`�p@4Hand;������������*���H���0	����X	$����	�����	����	�����	����
f���8
ȧ��X
4����
�����
���
����
��� 
     "���@
          R���`
               �����
                    �����
                         �����
                              &����
                                   `���
                                       ���� 
                                            ����@
                                                 ���`
                                                      N����
                                                           ~����
                                                                �����
                                                                     �����
d�������0,���P����pJ����>����2������6���0º��P:���x����������)����)%���7���F���`����������(n���H����h��������������,����P������(����H����h�����)����0J���Pj���p|����������H����h����*������������������
                             ����2����[�������0����P����p����������b����������������8����`�������������������:�������(���HJ���h2����N����\�����������������0���PI���p�����������������"���<���0����X����x��������*����b�������� ���@����h���������� ����z������������0����P����pT����b������������&���(P���H��h������������������(��Z���(|���H����h��������������D����^������(����Hq���p�������������������T�������8����X����x����B����h����v������������8����X����x����<����x������������� ����8 ����X ����x /���� \���� j���� ����� ����! ���8!:���X!D���x!f����!�����!0����!a���"o��� "����@"i���h"�����"�����"����"X����"z��#����(#���H#���h#$����#F����#z����#�����#���$
���($,���H$w���h$�����$�����$�����$�����$��%(���(%J���H%����h%�����%�����%�����%
 ����%��&����(&����H&
���h&����&L����&V����&p����&~��'����('����H'����h'�����'h����'�����'�����'.��(K���((h���H(����h(�����(�����(�����(
                                   ����(����)����8)0���X)����x)�������*zPRx�@
zPLRx�@�
]��$�����y��@AC��mܚ@AC�
������AC�AC�C�
t����0AC�C�AC�
[� A�����AC�C�
<�IAC�
\�9AC�
R���z���l��@AC�
��AC�
��0AC�
1AC�
T�$<AC�
D   ���� AC�
d����AC�
�����zAC�
�>���AC�
�4���%AC�
�:���)AC�
T��<AC�
$   `��� AC�
D`���AC�
dR���AC�
$�D���AC�
R�����@AC�
�     ����zAC�
���AC�
$,��AC�
$��)AC�@AC�
���AC�C��
����AC�AC�AC�
$<h����C�C�
a����;AC�C�C�
������AC�
�����AC�C�
  ����
�����2AC�AC�
,����AC�
<����AC�C��C�
\���AC�C�
�����1AC�
|����C��C�
$�(����L��




Is This A Good Question/Topic? 0
  • +

Replies To: Blackjack Example has Become Pointer Hell (novice)

#2 bobmax  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 20
  • Joined: 29-July 11

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 02:06 PM

First of all which Compiler are you using, because in my visual C++ i got loads of erorrs.... :sweatdrop: :sweatdrop: :sweatdrop: :sweatdrop:
Was This Post Helpful? 0
  • +
  • -

#3 aresh  Icon User is offline

  • It's a 16-Bit World!
  • member icon

Reputation: 273
  • View blog
  • Posts: 4,163
  • Joined: 08-January 12

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 02:38 PM

Strange. I compiled using Dev-Cpp, and the program seemed to run fine, except for a few logical errors like an infinite loop after some time...
Was This Post Helpful? 1
  • +
  • -

#4 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6039
  • View blog
  • Posts: 23,436
  • Joined: 23-August 08

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 02:43 PM

It compiles fine with g++ with warnings of -Wall -pedantic.

It crashed on this line for me:

os << RANKS[aCard.m_Rank] << SUITS[aCard.m_Suit];


Here's the value for aCard:

$6 = (const Card &) @0x100100e10: {m_Rank = KING, m_Suit = SPADES, 
  m_IsFaceUp = true}


And the value for RANKS[aCard.m_Rank]:

$7 = {
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7fff5fbff3f0 "X\016\020"}}


Here is the content of RANKS in memory:

(gdb) p RANKS
$8 = {{
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100e58 "0"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100f18 "A"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100f38 "2"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100f58 "3"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100f78 "4"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100f98 "5"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100fb8 "6"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100fd8 "7"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100100ff8 "8"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100101018 "9"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100101038 "J"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100101058 "Q"}}, {
    _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x100101078 "K"}}}


Something appears to be missing, no? So that explains your out-of-bounds access.

const string RANKS[] = {"0","A","2","3","4","5","6","7","8","9","J","Q","K"};


Quote

the program seemed to run fine


Welcome to the wonderful land of "undefined behavior".
Was This Post Helpful? 2
  • +
  • -

#5 FrozenSnake  Icon User is offline

  • En man från Sverige!

Reputation: 122
  • View blog
  • Posts: 995
  • Joined: 30-July 08

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 02:58 PM

I don't get that odd output how ever I had another bug. It said it was out of card and when I pressed "Y" it just asked the question again, and when I pressed "N" it ended up in a loop that wouldn't stop.

It said:

"Out of cards. Unable to deal. House: 2s (2)
Out of cards. Unable to deal. House: 2s (2)
Out of cards. Unable to deal. House: 2s (2)
..."

over and over. It might be able to help you locate at least one bug :)
Was This Post Helpful? 2
  • +
  • -

#6 Atrixium  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 03-June 12

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 06:46 PM

Wow, I did not expect to get such a good response so quickly, thank you all!

@bobmax - I am using GCC 4.4.3 as my compiler and Code::Blocks as my IDE and I did not receive any errors on compile with GCC set to -WALL and -Pedantic, what errors did you see?

@JackOfAllTrades - I did not receive any errors on compile with GCC set to -WALL and -Pedantic, how did you produce the information that you have there? I suspect that is from a debugger, unfortunately I don't understand the CB debugger well enough yet to produce useful information, or to interpret such information, which brings me to: I see that there is definitely something missing in RANKS from your example, but I don't understand what the output means, could you explain it a bit more?

@FrozenSnake && @aresh - I had not managed to progress through the game far enough yet to see the infinite loop you experienced but also realized that I had never declined to play again! It seems the infinite loop was caused by a logical error in the while condition in the game loop, I think I have that fixed now.

I changed the while loop from this:
while(again != 'n' || 'N')

which sounds logical when you say it but really it tells the computer (if I understand this correctly)
while(again != 'n' || 'N' == true)

which will always be true since it is a non-zero value (thus the infinite loop)

To this:

while(again != 'n' && again != 'N')

That seems to have ended the infinite loop problem, now I just need to solve the issues that JackOfAllTrades pointed out (once I understand them!)


Thanks everybody, I really appreciate the feedback!
Was This Post Helpful? 0
  • +
  • -

#7 Atrixium  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 03-June 12

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 03 June 2012 - 07:53 PM

Found it!

I did not realize that in my const string RANKS[] line I failed to include the 10 which is of course what JackOfAllTrades was alluding too without actually giving me the answer!

After adding the 10 in there the unexpected behaviour no longer occurs and the game now ends as expected. Having the computer tell you that it's out of cards and being unable to do anything about it sucks, but that's one of the chapter end challenges that I will now proceed to work on, thank you all very much for your assistance!

@JackOfAllTrades - Although I've now found the bug could you please explain the output that you provided anyway, I'm intrigued by it and I want to learn more!
Was This Post Helpful? 1
  • +
  • -

#8 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6039
  • View blog
  • Posts: 23,436
  • Joined: 23-August 08

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 04 June 2012 - 02:43 AM

The output comes from building in debug mode using this command line:

g++ -ggdb3 -Wall -pedantic -o bj bj.cpp


and running the code in gdb, the debugger. If you're using Code::Blocks, then Google for "Debugging with Code::Blocks" to find resources on this; I use the command line, because I'm old and crusty like that.
Was This Post Helpful? 2
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,595
  • Joined: 16-October 07

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 04 June 2012 - 04:12 AM

Looking at the code, I'm unclear as to why you need pointers at all. What am I missing?

Don't make friends so easily. Give the class in question a print method and just call it in your overload. e.g.
class Card {
	// ...
	void print(std::ostream &) const;
	// ...
}
// ...

ostream &operator<<(ostream &os, const Card &c) { c.print(os); return os; }



Your hierachy is odd.
class Hand
class Deck : public Hand
class GenericPlayer : public Hand
class House : public GenericPlayer



You say GenericPlayer "is a" Hand, but shouldn't your GenericPlayer just "have a" Hand.

I'm not real fond of the face up or down state being part of the card. It's not something card shold really have to worry about. It doesn't really make send in context of Deck. It might make sense in Hand depending on the game.

It looks like pointers and even vectors are adding unnecessary complexity here.

Hope this helps.
Was This Post Helpful? 3
  • +
  • -

#10 Atrixium  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 9
  • Joined: 03-June 12

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 04 June 2012 - 07:48 AM

View Postbaavgai, on 04 June 2012 - 04:12 AM, said:

Looking at the code, I'm unclear as to why you need pointers at all... It looks like pointers and even vectors are adding unnecessary complexity here.


That is a good observation, the answer is likely that the author of the book I'm using decided to over complicate a simple example in order to stress the usage of vectors, friends and overloaded operators.


Quote

Your hierachy is odd... You say GenericPlayer "is a" Hand, but shouldn't your GenericPlayer just "have a" Hand.


I noticed that as well, the author seems to have a fondness for is-a rather than has-a relationships, not sure why.


Thanks!
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3471
  • View blog
  • Posts: 10,705
  • Joined: 05-May 12

Re: Blackjack Example has Become Pointer Hell (novice)

Posted 05 June 2012 - 03:40 AM

View PostAtrixium, on 04 June 2012 - 07:48 AM, said:

Quote

Your hierachy is odd... You say GenericPlayer "is a" Hand, but shouldn't your GenericPlayer just "have a" Hand.

I noticed that as well, the author seems to have a fondness for is-a rather than has-a relationships, not sure why.


Some C++ teachers/books are not as good as others in teaching those concepts. Most of them focus on inheritance when talking about classes and why inheritance is good, but there is not as much focus on containment (or encapsulation for that matter).

To muddy the waters, C++ has the concept of private inheritance. The inappropriate use of private inheritance make a class almost act like it "has-a" Foo even though semantically it is written as "is-a".
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1