Hi. Im trying to write a simple deck of cards program. I am having difficulty in expressing my integer deck into a printable form. The deck is generated as this:

00102030405060708090100110120011121314151617181911011111210212223242526272829210211212203132333435363738393103113123

The leading numbers assign to suits and the following number assign to card rank. Basically how can I convert this to print in the form:

Card 1: Ace of spades
Card 2: 2 of spades
Card 3: 3 of spades
etc;

Could I use if statements and BREAKS to change the ints into strings? Perhaps a char value for suit would be better..

Any suggestions? Any help would be appreciated. I will post the question to give you a better idea of my though process. Please just help me in the right direction I am not looking for answers.

Here is the question

Write and compile a C++ program to simulate a deck of cards. A card is a C++ struct with both a suit (1 through 4) and a rank (1 through 13). A class CCardDeck provides the required functionality of a deck, as shown below. This class also includes a more involved member function to shuffle a deck. There are many ways to shuffle a deck. One approach is to divide a deck into two smaller decks. From here, the original deck is recreated by taking a few (random number of) cards at a time, from each of the two smaller decks, and placing them on the original deck. As an added note, the main function must also initialize the random number generator (srand(time(NULL)) where time(...) is in the <time.h> file).

A sketch of a possible interface of the CCardDeck class is given as follows, that is

public:
constructor (initialize a deck with the 4 × 13 = 52 cards of a standard deck) insert top card (add a given card to the top of a deck)
remove top card (remove the top card from a deck and return it)
get number of cards(return the current number of cards in a deck)
print (function to print, to the screen, all of the cards in a deck)
shuffle (shuffle the current deck, as described above)

private:
card type array (an array to hold a pile of cards, maximum of 52 cards)
Feel free to add any functions to these classes that you think you need.

Test your program using the script given below (code this in the main function), namely

Create a deck
Print the deck
Remove the top 3 cards
Print the deck
Put back the 3 cards into the deck Print the deck
Shuffle the deck
Print the deck
Shuffle the deck
Print the deck

I think I found a potential solution. I think I can use a function similar to this

void CCardDeck::Sort()
{
    int i = 0; 

        for(i; i<52; i++) {
             if(i<=13) {
                     Deck[i].suit = 'c';
                     Deck[i].rank = i;
             }
             else if (i<=26)

             // ...
        }
}

Ill try and post back my results.

Ill post all my code so far. I also changed the Card struct from int rank, suit. To int rank, char suit. Now the printed deck is in the form 0C1C2C3C4C5C6C7C8C9C10C11C12C13C14D15D16D17D18D19D20.

Hmm another problem. Any idea how to stop the deck from counting up to 52? I know the problem lies in my for-loop as i is getting added by 1 for every loop. So the .rank keeps counting up.

// Cards.h

#include <iostream>
using namespace std;

#ifndef __PROGRAMMING_1__Cards__
#define __PROGRAMMING_1__Cards__

#define DECK_SIZE 52

struct Card
    {   
        char suit; // (spades, diamonds, hearts, clubs)
        int rank; // (Ace,2,3,4,5,6,7,8,9,10,jack,queen,king)
    };


class CCardDeck {
    public:
        CCardDeck();

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

        void printDeck(); 


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


#endif /* defined(__PROGRAMMING_1__Cards__) */

-

// Cards.cpp

#include "Cards.h"


// New constructor
CCardDeck::CCardDeck()
{
    int i = 0; 

    for(i; i < 52; i++) {
        if(i<=13) {
            deck[i].suit = 'C'; //Clubs
            deck[i].rank = i;
        }
        else if (i<=26){
            deck[i].suit = 'D'; //Diamonds
            deck[i].rank = i;
            }
        else if (i<=39){
            deck[i].suit = 'H'; //Hearts
            deck[i].rank = i;
        }
        else if (i<=52){
            deck[i].suit = 'S'; //Spades
            deck[i].rank = i;
        }
}
}

void CCardDeck::printDeck()
{
    int i;


    for (i = 0; i < 52; i++) {
        cout << deck[i].rank;
        cout << deck[i].suit;
    }

}

-

// main.cpp

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


int main()
{
    CCardDeck Deck;
    Deck.printDeck();

    return 0;
}

Alright so I figured the improper counting problem for the deck. Here is my new constructor.

CCardDeck::CCardDeck()
{
    int i = 0; 

    for(i; i < 52; i++) {
        if(i<=13) {
            deck[i].suit = 'C'; //Clubs
        }
        else if (i<=26){
            deck[i].suit = 'D'; //Diamonds
            }
        else if (i<=39){
            deck[i].suit = 'H'; //Hearts
        }
        else if (i<=52){
            deck[i].suit = 'S'; //Spades
        }
}

    for (i = 0; i < 52; i++) {
        deck[i].rank = i % 13;
    }
}

Now I get a nice neat deck of cards to play with:
0C 1C 2C 3C 4C 5C 6C 7C 8C 9C 10C 11C 12C 0C 1D 2D 3D 4D 5D 6D 7D 8D 9D 10D 11D 12D 0D 1H 2H 3H 4H 5H 6H 7H 8H 9H 10H 11H 12H 0H 1S 2S 3S 4S 5S 6S 7S 8S 9S 10S 11S 12S

Any idea why that when the suits should end at C13 there is another C0 hanging around at the end? I think its because the arrays start at 0 but I cant find exactly where to fix it. Help?

Ok I have worked out all previous errors. Now im trying to format the deck to print nicely.

Here is my new function to print as well as a helper function to convert the chars into facecards (it doesent work as of now).

void CCardDeck::checkNumbers()
{
    int i;

        if (deck[i].rank == 0)
            cout << "Ace";
        else if (deck[i].rank == 10)
            cout << "Jack";
        else if (deck[i].rank == 11)
            cout << "Queen";
        else if (deck[i].rank == 12)
            cout << "King";
}

void CCardDeck::goodPrint()
{
    int i = 0;

    for(i; i <= 52; i++){

        if(i<=12) {
            cout << deck[i].rank << " ";
            deck[i].suit = 'C'; //Clubs
            cout << "of Clubs" << " " << endl;
        }


        else if (i<=25){
            cout << deck[i].rank << " ";
            deck[i].suit = 'D'; //Diamonds
            cout << "of Diamonds" << " " << endl;
        }


        else if (i<=38){
            cout << deck[i].rank << " ";
            deck[i].suit = 'H'; //Hearts
            cout << "of Hearts" << " " << endl;
        }


        else if (i<=51){
            cout << deck[i].rank << " ";
            deck[i].suit = 'S'; //Spades
            cout << "of Spades" << " " << endl;
        }
    }

}

Here is this output.
0 of Clubs
1 of Clubs
2 of Clubs
3 of Clubs
4 of Clubs
5 of Clubs
6 of Clubs
7 of Clubs
8 of Clubs
9 of Clubs
10 of Clubs
11 of Clubs
12 of Clubs.......

Im not sure how to replace the 0 with Ace, 10 with Jack, etc. I can insert an if statement:

if (deck[i].rank == 0)
    cout << " Ace";

to print Ace when there is a 0. But the 0 still remains in the output. I think I really hit a wall here. Suggestions?

Ok still stuck on how to change the numbers to face cards. But I have written functions to shuffle the deck and return the ammount of cards in them. Just need to figure out how to add/remove three cards.

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

void CCardDeck::Shuffle()
{
    // I opted for an easier shuffle method than the one you suggested
    std::random_shuffle(deck, deck + getSize());
}

Hmm Any ideas on how to remove the top three cards and put them back again after? Im lost here.

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

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

Quite a few questions in this thread. Not sure which ones are still relevant and which are already solved. First, from an overall design, there is more than one way to do this. There are two main ways and you have mentioned them both. One is to have the Card be a single integral value ranging from 0 to 51. The other is to have two elements: suit and value. It is quite easy to map one to the other...

int suit = card / 13;  // takes a card from 0 to 51 and returns a suit from 0 to 3
int value = card % 13; // takes a card from 0 to 51 and returns a value from 0 to 12.

For easy display purposes, you'll want to set up a few arrays...

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

To print out a card, do something like this...

cout << suits[card/13] << " of " << values[card % 13]; // where card ranges from 0 to 51.

I like the array way of doing things rather than doing it with the if-then statements. I also having a function that returns the string representation.

#include <iostream>
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <string>
using namespace std;


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


string StringRepresentation(unsigned int card)
{
    if(card >= 52)
    {
        return "Invalid";
    }

    return  values[card % 13] + " of " + suits[card/13]; // where card ranges from 0 to 51.
}

int main()
{
    // Deals a random card
    srand(time(NULL));
    int card = rand() % 52;

    cout << card << ", " << StringRepresentation(card) << endl;
    return 0;
}
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.