Hi quick question on this card program im writing. As of now the program should just create the deck and print it from main() using printDeck(). Im not sure why but the deck is printing in a strange format. It should print "Ace" "Spades" for example. Insead the output looks like this:

0x7fff5fbfa4f8 0x7fff5fbfa630
0x7fff5fbfa690 0x7fff5fbfa7c8
0x7fff5fbfa828 0x7fff5fbfa960
0x7fff5fbfa9c0 0x7fff5fbfaaf8
0x7fff5fbfab58 0x7fff5fbfac90
0x7fff5fbfacf0 0x7fff5fbfae28
0x7fff5fbfae88 0x7fff5fbfafc0
0x7fff5fbfb020 0x7fff5fbfb158
0x7fff5fbfb1b8 0x7fff5fbfb2f0

Is this hexadecimal? Why is it printing like this?

// Cards.h
#include <string>
#include <iostream>
using namespace std;

#ifndef __PROGRAMMING_1__Cards__
#define __PROGRAMMING_1__Cards__

#define DECK_SIZE 52

struct Card
{
    const string rank[13] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
    const string suit[4] = {"Spades", "Hearts", "Clubs", "Diamonds"};
};

class CCardDeck {
public:
    CCardDeck();
    void Shuffle();
    void printDeck();  
    void Insert();
    void Remove();

    int getSize(); // # cards left in the deck

private:
    Card deck[52]; //Array of 52 cards (suits,rank)
};

#endif /* defined(__PROGRAMMING_1__Cards__) */

-

// Cards.cpp

#include "Cards.h"
#include <iomanip>

CCardDeck::CCardDeck()
{
    deck; 
}

void CCardDeck::printDeck()
{
    for(int i=0; i<52; i++)
    {
        cout << deck[i].rank << " ";
        cout << deck[i].suit << endl;
    }
}

int CCardDeck::getSize()
{
    // return size of the deck
    return sizeof(deck) / sizeof( deck[0]);
}

-

// main.cpp
#include <iostream>
#include "Cards.h"

int main()
{
    CCardDeck deck;

    deck.printDeck();
    cout << endl;

    deck.getSize();


    return 0;
}
struct Card
{
    const string rank[13] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
    const string suit[4] = {"Spades", "Hearts", "Clubs", "Diamonds"};
};

These are string arrays. The only purpose of them is to provide a quick way of converting a number from 0 to 51 to a string like "Ace Of Diamonds". Hence they can just be floating around (i.e. not part of a struct). There are a variety of ways to approach all of this. If you were not a beginner, I would suggest making these arrays public static constant string arrays which are members of the Card struct. However, that adds one more tricky thing to learn (i.e. you'd have to learn about static versus non-static class/struct variables). The confusion and extra learning is not worth it at this point, so you can just make them regular old global constant string arrays not defined as part of any class or struct.

Sometimes the best way to learn is to simply view code that works as-is. Look at the code below and see if it makes sense. I've tried to keep things in line with your code from this thread, plus your prior thread. There's still plenty for you to do, of course. Note that I combined this all into one file just for my own ease. I am not suggesting that you change it from three files to one file. It just made it faster for me to do it this way. The code itself will be the same regardless of the number of files.

#include <string>
#include <iostream>
#include <iomanip>
using namespace std;


const string rank[13] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
const string suit[4] = {"Spades", "Hearts", "Clubs", "Diamonds"};


struct Card
{
    // members
    unsigned int card_value;

    // methods
    string toString();
};
string Card::toString()
{
    if(card_value >= 52)
    {
        return "Invalid";
    }
    return  rank[card_value % 13] + " of " + suit[card_value/13]; // where card_value ranges from 0 to 51.
}


class CCardDeck {
public:
    CCardDeck();
    void Shuffle();
    void printDeck();  
    void Insert();
    void Remove();
    int getSize(); // # cards left in the deck
private:
    Card deck[52]; //Array of 52 cards (suits,rank)
};


CCardDeck::CCardDeck()
{
    //deck;  // Delete this line.  It is meaningless, confusing, and error-producing. Instead, see below.

    // Go through the deck and initialize each card.
    for(int i = 0; i < 52; i++)
    {
        deck[i].card_value = i;
    }
}
void CCardDeck::printDeck()
{
    for(int i=0; i<52; i++)
    {
        cout << deck[i].toString() << endl;
    }
}
int CCardDeck::getSize()
{
    // return size of the deck
    return sizeof(deck) / sizeof( deck[0]);
}


int main()
{
    CCardDeck deck;
    deck.printDeck();
    cout << endl;
    cout << "Deck size = " << deck.getSize() << endl;
    return 0;
}

Edited 4 Years Ago by VernonDozier

The code itself will be the same regardless of the number of files.

Some elaboration on that. It matters what code goes where. Stick these two lines(lines 7 and 8 in my last post) in Cards.cpp file right below the #include <iomanip> line.

const string rank[13] = {"Ace", "2", "3", "4", "5", "6", "7", "8", "9", "10", "Jack", "Queen", "King"};
const string suit[4] = {"Spades", "Hearts", "Clubs", "Diamonds"};

More elaboration. Stick my lines 19 to 26 right below the two lines in my last post. They are implementation code for a Card struct member function, so they need to be in Card.cpp.

string Card::toString()
{
    if(card_value >= 52)
    {
        return "Invalid";
    }
    return  rank[card_value % 13] + " of " + suit[card_value/13]; // where card_value ranges from 0 to 51.
}

Ok! Thanks for the insightful comments. I think I understand enough to finish this program now.

I am getting an error on this line

return rank[card_value % 13] + " of " + suit[card_value/13];

The error is "reference to 'rank' is ambiguous" im not sure why this error is appearing becuase when suit[card_value/13] is called there is no error only rank produces this error. Any ideas?

EDIT: So i figured by the ambiguity error was because the compiler is confusing 'rank' for something else. I changed the const string rank[13] to - const string Rank[13]
Now the code compiles correctly but im not sure why that error occured in the first place. Maybe its my compiler?

Edited 4 Years Ago by jongiambi

Ok so ive got the program to get the size of the deck and shuffle it. Now im trying to remove the top three cards of the deck, print the deck, and then put the three cards back into the deck.

So far ive written this function to remove a card

void CCardDeck::Remove()
{
    for(int i=0; i < getSize(); i++)
    {
        deck[i] = deck[i + 1];
    }

    memmove(deck + 0, deck, sizeof(deck) -sizeof( deck[0]));
}

This function removes the top card of the deck but since the top card is removed an "Ace of Spades" is added to the end of the deck. Is there a solution to work around this? S

A "deck" should always have exactly 52 cards, right? Now perhaps sometimes not all 52 cards are used. You need to really think about what it means to "remove" a card from a deck. You have DEFINED the deck as having 52 cards in your CCard class. If your instructor has provided an explanation of what he/she means by "removing" and "adding" a card, go with that. Otherwise you'll need to think of a meaning yourself. Only when you decide for sure exactly what terms mean in English can you truly program it.

Now there are numerous games and magic tricks where I might not use all 52 cards in the deck. However, those cards, even the ones that are unused, will still exist. Think about it in real life. When you "deal" five cards, the other 47 cards still exist. They are simply out-of-play for that hand. If I were you, I would create a class called "Hand", which would represent any subset of the 52 cards in the deck.

You can also add a boolean variable in the Card class called in_use. in_use would be true if the particular card was being used (i.e. in someone's Hand). You could "remove" or "add" a card by setting the value of in_use. Shuffling is a different animal entirely. You neither remove or add, but you instead change the ORDER of the array.

Also, think about "inserting" and "removing". You have no parameters for those functions. If you always insert from the top or the bottom, say that explicitly in the comments. Can I "remove" a card from the 15th position in the deck? Your instructor may have told you exactly what all of these functions do, but we do not know and cannot assume. There are a million different ways to define and implement the functions, so it's very likely that I could write one that makes sense to me and works, but is not what your instructor wants. Hence you may need to clarify the overall specification of the assignment.

At any rate, if the deck does not always contain all 52 cards, you need to change the printDeck() function because that's printing all of them.

Now the code compiles correctly but im not sure why that error occured in the first place. Maybe its my compiler?

http://en.cppreference.com/w/cpp/keyword

rank is not a C++ keyword. I don't know why there would be anything ambiguous about it. An error message will give you an exact error message and will very often point to at least one line number. Not seeing your exact code and not seeing the exact error message, I can't comment on the error.

Ok I got the shuffling working fine:

used this method:

void CCardDeck::Shuffle()
{
  std::random_shuffle(deck, deck + getSize());
}

Also changed the print function to work around the size of the deck at any size

void CCardDeck::printDeck()
{
    // Print each card 
    for(int i=0; i< getSize(); i++)
    {
        cout << deck[i].toString() << endl;
    }
}

int CCardDeck::getSize()
{
    // return size of the deck
    return sizeof(deck) / sizeof( deck[0]);
}

Im going to try the bool in_hand method you mentioned to add and remove cards. Thanks!

Edited 4 Years Ago by jongiambi

This article has been dead for over six months. Start a new discussion instead.