Sorting cards with text descriptions

Pages: 12
I'm trying to create a function that will sort out a list of cards, but with text descriptions. I have numerical descriptions, but am having a hard time translating that into text form.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  #include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <string>

using namespace std;

//Global constants
const int NUM_COLS=13;
const int NUM_ROWS=4;

//Create Function prototypes for card loading and shuffling deck of cards
void unwrap(vector<int> &);
void shuffle(vector<int> &);
void printCards(vector<int>);

//Function for dealing cards to players
void deal(vector<vector<int>>&, const vector<int>&);
void showHands(const vector<vector<int>>&);

// Function for sorting cards with a text description in each hand
void selectionSort (vector<string>&);



int main() {

    //Declare vector for the number of cards
    vector <int> deck;


    //Call function for showing cards in ascending order, and shuffling cards
    cout << "The deck before shuffling: " << endl;
    unwrap(deck);
    printCards(deck);

    cout << "The deck after shuffling: " << endl;
    shuffle(deck);
    printCards(deck);

    //Declare 2d vector for dealing the cards to each player
    vector<vector<int>> players(NUM_ROWS, vector<int>(NUM_COLS, 0));

    cout << " Before cards have been dealt " << endl;
    showHands(players);

    cout << " After the cards have been dealt "<<endl;
    deal(players, deck);
    showHands(players);

    return 0;
}

//Function definitions that load cards and randomly shuffles them
void unwrap(vector<int> &deck)
{
    //Load vector with ints from 0 to 51
    for (int i = 0; i <= 51; i++)
    {
        deck.push_back(i);
    }

}

// Randomize the cards in the deck
void shuffle(vector<int> &deck)
{
    random_shuffle(deck.begin(), deck.end());

}
void printCards(vector<int> deck)
{
    for(int j=0; j<deck.size(); j++)
    {
        cout<< deck[j] << endl;
    }
}
// deal one card to each player in order, repeat until the entire deck is dealt
void deal(vector<vector<int>>& players, const vector<int>& deck)
{
    int card_count = 0;

    for (int cols = 0; cols < NUM_COLS; cols++)
    {
        for (int rows = 0; rows < NUM_ROWS; rows++)
        {
            players[rows][cols] = deck[card_count];
            card_count++;
        }
    }
}
//Show hand after cards have been randomly dealt to each player
void showHands(const vector<vector<int>>& players)
{
    for (int rows = 0; rows < NUM_ROWS; rows++)
    {
        cout << "Player " << rows + 1 << ": ";
        for (int cols = 0; cols < NUM_COLS; cols++)
        {
            cout << players[rows][cols] << ' ';
        }
        cout << '\n';
    }
}

// Sorts string vector in ascending order
void selectionSort(vector<string> &deck)
{
    int minIndex;
    string minValue;

    for (int start = 0; start < deck.size(); start++)
    {
        minIndex = start;
        minValue = deck[start];
        for (int i = start + 1; i < deck.size(); i++)
        {
            if (deck[i]<minValue)
            {
                minValue=deck[i];
                minIndex=i;
            }

        }
        swap(deck[minIndex],deck[start]);
    }
    

}




I figured I could declare a couple of const string arrays for ranks and suits like this:

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



But then I get stuck on exactly how to use them and sort them in my function.
Last edited on
Two possibilities
1. You could keep your current setup and just perform the conversion of 0-51 to words at the time of printing. e.g.
1
2
3
4
5
6
7
8
9
const string WORDS[] = {"Ace of Spades", "2 of Spades", "3 of Spades"...};

void printCards(vector<int> deck)
{
    for(int j=0; j<deck.size(); j++)
    {
        cout<< WORDS[deck[j]] << endl;
    }
}


2. Redesign so that deck is not a vector<int> anymore, but a vector<Card> , and then you could have helper methods to convert to string for printing, sort based on Card.Value , etc.
closed account (E0p9LyTq)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <vector>
#include <iostream>
#include <numeric>
#include <random>
#include <chrono>

using card = unsigned short;

void showDeck(std::vector<card>&);

int main()
{
   // manufacture a deck of cards:
   std::vector<card> deck(52);
   std::iota(deck.begin(), deck.end(), 0);

   // display the unshuffled deck
   std::cout << "The deck before shuffling:\n";
   showDeck(deck);

   // shuffle the deck:
   std::default_random_engine rng(static_cast<unsigned> (std::chrono::system_clock::now().time_since_epoch().count()));
   std::shuffle(deck.begin(), deck.end(), rng);

   // display the shuffled deck:
   std::cout << "\nThe deck after shuffling:\n";
   showDeck(deck);
}

void showDeck(std::vector<card>& deck)
{
   // create two lamda functions to print text
   auto rank = [ ](card c) { return "AKQJT98765432"[c % 13]; };
   auto suit = [ ](card c) { return "SHDC"[c / 13]; };

   for (size_t loop = 0; loop < deck.size(); loop++)
   {
      std::cout << rank(deck[loop]) << suit(deck[loop]) << ' ';

      if (0 == ((loop + 1) % 13))
      {
         std::cout << "\n";
      }
   }

}

The deck before shuffling:
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S
AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H
AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D
AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C

The deck after shuffling:
JS KS TH AD TC QS 5H AS TS 3S 5S AC 8D
8S 4D KC 7H 7C 9C JH 8H 3C 4H 5D AH 2H
7D QC 6S 2D QD JC 9D KH 2C 4S TD 6D 6H
9S 9H 6C JD QH 3D 8C 5C KD 7S 4C 2S 3H
Btw, if you're going with #1 for printing ease, depending on your sorting preference, you could arrange the WORDS array so that it's sorted ascending.

Assuming you want Ace>King>Queen>...>3>2 and Spades(strongest)>Hearts>Diamonds>Clubs(weakest):

const string WORDS[] = {"2 of Clubs", "2 of Diamonds", "2 of Hearts", "2 of Spades",..., "Ace of Hearts", "Ace of Spades"};

Your sort method can then keep the vector<int> signature. Perhaps add a descending default parameter:
void selectionSort(vector<int>& deck, bool descending=false)
Last edited on
@FurryGuy, I am not use to seeing code like that, so I'm having a hard time understanding what is going on.
@icy1 would I still need to do that even though I have a function that already displays the ascending order?
"that"?
even though I have a function that already displays the ascending order

Are you refering to printCards()? That displays the cards, but not in a human friendly manner. It just shows the card number, not the suit and rank.

Icy1 is right, you want to store the cards by number, like you do now, and only convert to text when you want to print them out. This is an example of a very important concept in program design: there may be a difference between the way you represent your data in the program, and the way that you present it to the user (or read it from the user).

You may have gotten confused with your representation of the hands. You currently code 13 hands with 4 cards each. Or is that 4 hands with 13 cards each? Is that what you intended? Either way, deal() seems wrong to me. The comment says that you should deal out the cards until the deck is empty. Instead, you assume that the cards will go evenly into the hands that are presented.

To your original question, do you just mean that you need sort the cards and print them out, or do you really want to sort based on the text description? If you really want to sort based on text (e.g, Jack King Queen instead of Jack Queen King) then use a custom comparison function that gets the text description of the two cards and compares them.

deal() and showhands() both have the number of hands and the size of each one hard-coded. Use vector::size() instead so they will work with any size hand and any number of hands.
closed account (E0p9LyTq)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // std::shuffle
#include <numeric>   // std::iota
#include <random>    // std::default_random_engine
#include <chrono>    // std::chrono::system_clock

using cards = unsigned short;

const cards NUM_CARDS = 52;
const cards NUM_PLAYERS = 4;

// the size of a player's hand may have undealt cards after dealing 
const cards PLAYER_HAND = NUM_CARDS / NUM_PLAYERS;

void DisplayCard(const cards);
void ShowCards(const std::vector<cards>&);
void ShuffleDeck(std::vector<cards>&);
void ShowHand(const std::vector < std::vector<cards>>&, unsigned short);
void ShowHands(const std::vector < std::vector<cards>>&);
void DealCards(std::vector<std::vector<cards>>&, const std::vector<cards>&);

int main()
{
   // create a deck of cards, NUM_CARDS sized, zero filled.
   std::vector<cards> deck(NUM_CARDS);

   // fill the deck with increasing values from 0 to 51.
   std::iota(deck.begin(), deck.end(), 0);

   std::cout << "The deck before shuffling:\n";
   ShowCards(deck);

   ShuffleDeck(deck);

   std::cout << "\nThe deck after shuffling:\n";
   ShowCards(deck);

   // create a 2D vector, each player's hand a separate vector
   std::vector<std::vector<cards>> players(NUM_PLAYERS, std::vector<cards>(PLAYER_HAND, 0));

   std::cout << "\nBefore the cards have been dealt:\n";
   ShowHands(players);

   DealCards(players, deck);

   std::cout << "\nAfter the cards have been dealt:\n";
   ShowHands(players);
}

void DisplayCard(const cards card)
{
   std::string ranks = "AKQJT98765432";
   std::string suits = "SHCD";

   std::cout << ranks.at(card % 13) << suits.at(card / 13) << ' ';
}

void ShowCards(const std::vector<cards>& deck)
{
   for (const cards card : deck)
   {
      DisplayCard(card);
   }
   std::cout << '\n';
}

void ShuffleDeck(std::vector<cards>& deck)
{
   // get a seed based on the current time
   unsigned seed = static_cast<unsigned> (std::chrono::system_clock::now().time_since_epoch().count());

   // create a random engine
   std::default_random_engine URNG;

   // seed the engine
   URNG.seed(seed);

   // shuffle the cards
   std::shuffle(deck.begin(), deck.end(), URNG);
}

void ShowHand(const std::vector<std::vector<cards>>& players, unsigned short player)
{
   std::cout << "Player " << player + 1 << ": ";

   for (unsigned short hand = 0; hand < PLAYER_HAND; hand++)
   {
      DisplayCard(players[player][hand]);
   }
   std::cout << '\n';
}

void ShowHands(const std::vector<std::vector<cards>>& players)
{
   for (unsigned short player = 0; player < NUM_PLAYERS; player++)
   {
      ShowHand(players, player);
   }
}


void DealCards(std::vector<std::vector<cards>>& players, const std::vector<cards>& deck)
{
   cards card_count = 0;

   // deal one card to each player in order, repeat until the entire deck is dealt
   // there may be left over cards depending on the number of players
   for (unsigned short hand = 0; hand < PLAYER_HAND; hand++)
   {
      for (unsigned short player = 0; player < NUM_PLAYERS; player++)
      {
         players[player][hand] = deck[card_count];
         card_count++;
      }
   }
}

The deck before shuffling:
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D

The deck after shuffling:
8D TH 2C TD 9D 6H JS QC 4C 3H 9C QH 2S AC 2D 8C 7S 5S 7D KS 7H 8H QD QS JC 8S KD KH 4H 4D 5C AS 3C 2H 5D 5H 9H KC 9S AD TC JD 7C 6S AH 3D TS 3S 6D JH 6C 4S

Before the cards have been dealt:
Player 1: AS AS AS AS AS AS AS AS AS AS AS AS AS
Player 2: AS AS AS AS AS AS AS AS AS AS AS AS AS
Player 3: AS AS AS AS AS AS AS AS AS AS AS AS AS
Player 4: AS AS AS AS AS AS AS AS AS AS AS AS AS

After the cards have been dealt:
Player 1: 8D 9D 4C 2S 7S 7H JC 4H 3C 9H TC AH 6D
Player 2: TH 6H 3H AC 5S 8H 8S 4D 2H KC JD 3D JH
Player 3: 2C JS 9C 2D 7D QD KD 5C 5D 9S 7C TS 6C
Player 4: TD QC QH 8C KS QS KH AS 5H AD 6S 3S 4S


Change the number of players to 5 (There will be undealt cards left over):
The deck before shuffling:
AS KS QS JS TS 9S 8S 7S 6S 5S 4S 3S 2S AH KH QH JH TH 9H 8H 7H 6H 5H 4H 3H 2H AC KC QC JC TC 9C 8C 7C 6C 5C 4C 3C 2C AD KD QD JD TD 9D 8D 7D 6D 5D 4D 3D 2D

The deck after shuffling:
8S 8C 2D 6H 9D KD QH JH JD 4C AC 4S KC AH KS 3D 6C TS KH 2C 5C JC 2S 3H AD 5D 8H 7S 8D 7H QC QS 7C 6S 4D 9C 9S JS QD TH 3S 3C 5S 5H 7D 2H AS 6D TC TD 9H 4H

Before the cards have been dealt:
Player 1: AS AS AS AS AS AS AS AS AS AS
Player 2: AS AS AS AS AS AS AS AS AS AS
Player 3: AS AS AS AS AS AS AS AS AS AS
Player 4: AS AS AS AS AS AS AS AS AS AS
Player 5: AS AS AS AS AS AS AS AS AS AS

After the cards have been dealt:
Player 1: 8S KD AC 3D 5C 5D QC 9C 3S 2H
Player 2: 8C QH 4S 6C JC 8H QS 9S 3C AS
Player 3: 2D JH KC TS 2S 7S 7C JS 5S 6D
Player 4: 6H JD AH KH 3H 8D 6S QD 5H TC
Player 5: 9D 4C KS 2C AD 7H 4D TH 7D TD
closed account (E0p9LyTq)
A couple of modifications to make the program be more generic as to number of players and cards dealt, so the program knows the number of undealt cards:

11
12
13
14
15
const cards NUM_CARDS = 52;
const cards NUM_PLAYERS = 5;

// the size of a player's hand may have undealt cards after dealing 
const cards PLAYER_HAND = 7;


48
49
50
51
   std::cout << "\nAfter the cards have been dealt:\n";
   ShowHands(players);

   std::cout << "\nThere are " << NUM_CARDS - (NUM_PLAYERS * PLAYER_HAND) << " cards undealt.\n";

blah, blah, blah
.
.
After the cards have been dealt:
Player 1: 8C 6D JC 3S 3H AC QS
Player 2: 4H 2D JD TS KS 9D TD
Player 3: AS 5H 5S 4C 8S KC 7S
Player 4: TH AH 3D 9H 3C 5C 6S
Player 5: 5D QC 2H 7D KH 9C TC

There are 17 cards undealt.
Last edited on
Thank you!

Would it be OK if I created a new data type through a struct for "cards?" Would that work instead if I find that to be an easier approach?
closed account (E0p9LyTq)
No real need to create a struct, at this point an alias for a POD int works just fine.

More productive would be creating a few classes to do the logic grunt work for:

1. A playing card: displaying what the card is (8 of Hearts, etc.), keeping track of the number of suits and ranks for displaying.

2. A player and their hand of cards

3. A deck of cards: dealing cards to a player, keeping track of what cards have been dealt and what cards haven't.

A deck of cards class could be a derived class from a playing card class, a player card class be friends with a player class.

With well crafted card classes creating a variety of card games becomes easy. Poker, Uno, etc. The game logic for each card game could be encapsulated in a class.

Your current approach is more C based procedural logic. C++ allows for dealing with objects, each object being testable separately.

Two structs, a card's rank and suit, could be helpful for the card class. structs that hold the text representation of the rank or suit and a numeric for what the card's suit or rank is.

Those are a few thoughts of how I would create this, making it easier to test each portion of the program. Creating code that is reusable and easy to modify without introducing errors that are hard to pin down.
Last edited on
The only problem is that we have not learned classes, unfortunately. So I wouldn't even know where to begin with how to use those with the procedures that I'm currently using (using them within what I already have up there).

This is an example of what the output should look like:


Hand1 holds:
3 of Spades
Jack of Spades
Queen of Spades
2 of Hearts
7 of Hearts
8 of Hearts
Queen of Hearts
Ace of Diamonds
3 of Diamonds
Jack of Diamonds
Queen of Diamonds
4 of Clubs
King of Clubs

Hand2 holds:
4 of Spades
6 of Spades
10 of Spades
Ace of Hearts
3 of Hearts
5 of Hearts
6 of Hearts
10 of Hearts
Jack of Hearts
7 of Diamonds
2 of Clubs
7 of Clubs
Queen of Clubs

Hand3 holds:
5 of Spades
7 of Spades
8 of Spades
9 of Spades
King of Spades
4 of Hearts
2 of Diamonds
4 of Diamonds
9 of Diamonds
Ace of Clubs
6 of Clubs
8 of Clubs
Jack of Clubs

Hand4 holds:
Ace of Spades
2 of Spades
9 of Hearts
King of Hearts
5 of Diamonds
6 of Diamonds
8 of Diamonds
10 of Diamonds
King of Diamonds
3 of Clubs
5 of Clubs
9 of Clubs
10 of Clubs
Last edited on
closed account (E0p9LyTq)
If you have learned about structs, you have learned some of the basics of classes.

Structs combine related variables into a single package, classes combine variables and functions using those variables.

Two functions in my previous code get modified for the output you desire:

52
53
54
55
56
57
58
59
void DisplayCard(const CARDS card)
{
   std::vector<std::string> ranks { "Ace", "King", "Queen", "Jack", "Ten", "Nine", "Eight",
                                    "Seven", "Six", "Five", "Four", "Three", "Two", "One" };
   std::vector<std::string> suits { "Spades", "Hearts", "Clubs", "Diamonds" };

   std::cout << ranks[card % 13] << " of " << suits[card / 13] << '\n';
}


84
85
86
87
88
89
90
91
92
93
void ShowHand(const std::vector<std::vector<CARDS>>& players, unsigned short player)
{
   std::cout << "Player " << player + 1 << ":\n";

   for (unsigned short hand = 0; hand < PLAYER_HAND; hand++)
   {
      DisplayCard(players[player][hand]);
   }
   std::cout << '\n';
}

Player 1:
Four of Hearts
Jack of Spades
Three of Diamonds
Ace of Spades
Two of Spades
King of Diamonds
Jack of Diamonds
Queen of Clubs
Three of Clubs
Six of Clubs
Queen of Hearts
Five of Clubs
Two of Clubs

Player 2:
Five of Diamonds
Seven of Hearts
Nine of Diamonds
Ten of Hearts
Jack of Hearts
Nine of Clubs
Seven of Spades
King of Spades
Ten of Spades
Six of Hearts
Six of Spades
Ace of Hearts
Eight of Spades

Player 3:
Seven of Clubs
Eight of Clubs
Nine of Hearts
Eight of Diamonds
Two of Hearts
Four of Diamonds
Two of Diamonds
King of Clubs
Three of Hearts
Ten of Diamonds
Five of Spades
Ace of Diamonds
King of Hearts

Player 4:
Four of Clubs
Ten of Clubs
Six of Diamonds
Three of Spades
Queen of Diamonds
Jack of Clubs
Nine of Spades
Four of Spades
Eight of Hearts
Queen of Spades
Seven of Diamonds
Five of Hearts
Ace of Clubs


Minor edits and the output is more human readable.
Last edited on
Okay, so this is what I've done. I know my output isn't correct, but I wanted to get started on trying to solve this issue. I'm able to print the strings, but still having issues converting the player hands into strings.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <string>

using namespace std;


//Global constants
const int NUM_COLS=13;
const int NUM_ROWS=4;

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


//Create Function prototypes for card loading and shuffling deck of

void unwrap(vector<int> &);
void shuffle(vector<int> &);
void printCards(vector<int>);

//Function for dealing cards to players
void deal(vector<vector<int>>&, const vector<int>&);
void showHands(const vector<vector<int>>&);


int main() {

    //Declare vector for the number of cards
    vector <int> deck;

    // Store the integers 0 to 51 in the vector
    const int DECK_SIZE = 52;
    for(int i = 0; i < DECK_SIZE; i++)
        deck.push_back(i);



    cout << "The deck before shuffling: " << endl;
    unwrap(deck);
    printCards(deck);

    cout << "The deck after shuffling: " << endl;
    shuffle(deck);
    printCards(deck);

    //Declare 2d vector for dealing the cards to each player
    vector<vector<int>> players(NUM_ROWS, vector<int>(NUM_COLS, 0));

    cout << " Before cards have been dealt " << endl;
    showHands(players);

    cout << " After the cards have been dealt "<<endl;
    deal(players, deck);
    showHands(players);
    // Print the string associated with each card based on rank and suit
    for (int each : deck)
    {
        // cout << each << " : rank " << each % 13 << " - suit " << each / 13 << " : " << endl;
        cout << RANKS[each % 13] << " of " << SUITS[each / 13] << endl;
    }

    return 0;
}

//Function definitions that load cards and randomly shuffles them
void unwrap(vector<int> &deck)
{
    //Load vector with ints from 0 to 51
    for (int i = 0; i <= 51; i++)
    {
        deck.push_back(i);
    }

}

// Randomize the cards in the deck
void shuffle(vector<int> &deck)
{
    random_shuffle(deck.begin(), deck.end());

}
void printCards(vector<int> deck)
{
    for(int j=0; j<deck.size(); j++)
    {
        cout<< deck[j] << endl;
    }
}
// deal one card to each player in order, repeat until the entire deck is dealt
void deal(vector<vector<int>>& players, const vector<int>& deck)
{
    int card_count = 0;

    for (int cols = 0; cols < NUM_COLS; cols++)
    {
        for (int rows = 0; rows < NUM_ROWS; rows++)
        {
            players[rows][cols] = deck[card_count];
            card_count++;
        }
    }
}
//Show hand after cards have been randomly dealt to each player
void showHands(const vector<vector<int>>& players)
{
    for (int rows = 0; rows < NUM_ROWS; rows++)
    {
        cout << "Player " << rows + 1 << ": ";
        for (int cols = 0; cols < NUM_COLS; cols++)
        {
            cout << players[rows][cols] << ' ';
        }
        cout << '\n';

    }

}



My output is looking really funky.
Before cards have been dealt
Player 1: 0 0 0 0 0 0 0 0 0 0 0 0 0
Player 2: 0 0 0 0 0 0 0 0 0 0 0 0 0
Player 3: 0 0 0 0 0 0 0 0 0 0 0 0 0
Player 4: 0 0 0 0 0 0 0 0 0 0 0 0 0
After the cards have been dealt
Player 1: 40 49 24 1 6 33 17 34 21 36 27 0 5
Player 2: 45 11 35 30 47 15 22 7 27 48 14 47 22
Player 3: 45 49 26 13 42 16 34 23 31 4 29 30 7
Player 4: 8 44 48 18 26 13 51 11 33 4 39 31 25
2 of Clubs
7 of Clubs
7 of Clubs
9 of Spades
Jack of Clubs
Queen of Spades
Jack of Clubs
6 of Clubs
Queen of Hearts
10 of Diamonds
Ace of Diamonds
10 of Clubs
2 of Spades
5 of Diamonds
Ace of Hearts
6 of Hearts
7 of Spades
9 of Clubs
4 of Clubs
Ace of Diamonds
8 of Diamonds
3 of Hearts
4 of Hearts
Ace of Hearts
5 of Hearts
10 of Hearts
9 of Diamonds
King of Clubs
9 of Diamonds
8 of Spades
Jack of Hearts
Queen of Spades
9 of Hearts
2 of Diamonds
6 of Diamonds
8 of Diamonds
Jack of Diamonds
10 of Clubs
5 of Spades
5 of Spades
2 of Diamonds
2 of Hearts
4 of Diamonds
Ace of Clubs
Ace of Spades
9 of Clubs
5 of Diamonds
6 of Diamonds
6 of Spades
10 of Hearts
8 of Spades
King of Hearts
10 of Spades
9 of Spades
Jack of Spades
King of Diamonds
King of Spades
King of Clubs
8 of Clubs
3 of Spades
6 of Spades
9 of Hearts
3 of Diamonds
8 of Hearts
7 of Hearts
10 of Spades
Queen of Diamonds
5 of Clubs
Jack of Hearts
4 of Clubs
10 of Diamonds
7 of Diamonds
3 of Clubs
6 of Hearts
King of Diamonds
Queen of Clubs
2 of Spades
Ace of Clubs
4 of Hearts
7 of Hearts
Jack of Diamonds
7 of Diamonds
3 of Spades
3 of Diamonds
Queen of Diamonds
Jack of Spades
4 of Diamonds
6 of Clubs
5 of Clubs
7 of Spades
2 of Clubs
2 of Hearts
Queen of Clubs
King of Hearts
King of Spades
5 of Hearts
4 of Spades
8 of Hearts
8 of Clubs
Queen of Hearts
4 of Spades
3 of Clubs
Ace of Spades
3 of Hearts
Last edited on
Lines 37-38 basically create the deck. Then unwrap() puts another deck in the deck! So you're basically playing with two decks.

Create a function to convert a card number to the human readable string. Use that whenever printing a card.

I wouldn't pre-populate the hands. To me, it makes more sense to have the hands start empty, and have deal() add cards to the them.

NUM_COLS? NUM_ROWS? What do columns and rows have to do with a card game? Just use one number that's the number of PLAYERS.

Deal() still doesn't do what it says it does. The function is supposed to deal all the cards, even if that means that some players have different numbers in the end. Also "deck" shouldn't be const. When you deal a card, you transfer the card to the player, so upon exit, deck should be empty.

When dealing and showing the cards, use the size of the vector, not the constants. That way the code will work regardless of how the deck got populated or the hands got dealt.

Here is your code with the changes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <string>

using namespace std;


//Global constants
const int NUM_CARDS = 52;
const int NUM_PLAYERS=4;

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


//Create Function prototypes for card loading and shuffling deck of

void unwrap(vector<int> &);
void shuffle(vector<int> &);
void printCards(vector<int>);

//Function for dealing cards to players
void deal(vector<vector<int>>&hands, vector<int>&deck);
void showHands(const vector<vector<int>>&hands);


int main() {

    //Declare vector for the number of cards
    vector <int> deck;


    cout << "The deck before shuffling: " << endl;
    unwrap(deck);
    printCards(deck);

    cout << "The deck after shuffling: " << endl;
    shuffle(deck);
    printCards(deck);

    //Declare 2d vector for dealing the cards to each player
    vector<vector<int>> players(NUM_PLAYERS);

    cout << " Before cards have been dealt " << endl;
    showHands(players);

    cout << " After the cards have been dealt "<<endl;
    deal(players, deck);
    showHands(players);

    return 0;
}

//Function definitions that load cards and randomly shuffles them
void unwrap(vector<int> &deck)
{
    //Load vector with ints from 0 to 51
    deck.clear();		// ensure that it starts emtpy
    for (int i = 0; i < NUM_CARDS; i++)
    {
        deck.push_back(i);
    }
}

// Randomize the cards in the deck
void shuffle(vector<int> &deck)
{
    random_shuffle(deck.begin(), deck.end());

}

// Print the card's name to cout
// Note that this doesn't print a space or newline after the card.
// That's the caller's business.
void printCard(int card)
{
    cout << RANKS[card % 13] << " of " << SUITS[card / 13];
}


void printCards(vector<int> deck)
{
    for(size_t j=0; j<deck.size(); j++)
    {
        printCard(deck[j]);
	cout << '\n';
    }
}
// deal one card to each player in order, repeat until the entire deck is dealt
void deal(vector<vector<int>>& players, vector<int>& deck)
{
    // clear the players' hands
    for (size_t i = 0; i < players.size(); ++i) {
	players[i].clear();
    }

    // Deal the cards from deck to the hands.
    for (size_t i = 0; i < deck.size(); ++i) {
	players[i%players.size()].push_back(deck[i]);
    }
    // now clear the deck because you transfered the cards to the players
    // hands.
    deck.clear();
}

//Show hand after cards have been randomly dealt to each player
void showHands(const vector<vector<int>>& players)
{
    for (size_t i = 0; i < players.size(); ++i) {
        cout << "Player " << i + 1 << ":\n";
	printCards(players[i]);
    }
}

Thank you @dhayden!

It's the most basic operations for the card game. I don't think our instructor is looking for the perfect output and perfect card game, just the basic coding of the game. For instance, the first part of the project, he just wanted to see us unwrap the deck in ascending order and then shuffle it.
Is my sorting okay? I need to sort while the cards are still in "int" form?
idk, is your sorting okay? Test your sorting function with a bunch of hand examples, print the "before" and "after" states, and see if it meets your expectations.

Last edited on
My code is not compiling now. Here is what I have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <string>

using namespace std;


//Global constants
const int NUM_CARDS = 52;
const int NUM_PLAYERS=4;

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


//Create Function prototypes for card loading and shuffling deck of

void unwrap(vector<int> &);
void shuffle(vector<int> &);
void printCards(vector<int>);

//Function for dealing cards to players
void deal(vector<vector<int>>&hands, vector<int>&deck);
void showHands(const vector<vector<int>>&hands);

//Function for sorting cards
void sort(vector<int>&); 
void swap(int deck[], int first, int second);


int main() {

    //Declare vector for the number of cards
    vector<int>deck;

    cout << "The deck before shuffling: " << endl;
    unwrap(deck);
    printCards(deck);

    cout << " The deck after shuffling: " << endl;
    shuffle(deck);
    sort(deck);
    printCards(deck);

    //Declare 2d vector for dealing the cards to each player
    vector<vector<int>> players(NUM_PLAYERS);

    cout << " Before cards have been dealt " << endl;
    showHands(players);

    cout << " After the cards have been dealt "<<endl;
    deal(players, deck);
    showHands(players);

    return 0;
}
void swap(int *deck, int first, int second)

{
    int temp = deck[first];
    deck[first] = deck[second];
    deck[second] = temp;
}
//Function definitions that load cards and randomly shuffles them
void unwrap(vector<int> &deck)
{
    //Load vector with ints from 0 to 51
    deck.clear();		// ensure that it starts emtpy
    for (int i = 0; i < NUM_CARDS; i++)
    {
        deck.push_back(i);
    }
}

// Randomize the cards in the deck
void shuffle(vector<int> &deck)
{
    random_shuffle(deck.begin(), deck.end());

}

// Print the card's name to cout
void printCard(int card)
{
    cout << RANKS[card % 13] << " of " << SUITS[card / 13];
}


void printCards(vector<int> deck)
{
    for(size_t j=0; j<deck.size(); j++)
    {
        printCard(deck[j]);
        cout << '\n';
    }
}
// deal one card to each player in order, repeat until the entire deck is dealt
void deal(vector<vector<int>>& players, vector<int>& deck)
{
    // clear the players' hands
    for (size_t i = 0; i < players.size(); ++i) {
        players[i].clear();
    }

    // Deal the cards from deck to the hands.
    for (size_t i = 0; i < deck.size(); ++i) {
        players[i%players.size()].push_back(deck[i]);
    }
    //clear deck
    deck.clear();
}

//Show hand after cards have been randomly dealt to each player
void showHands(const vector<vector<int>>& players)
{
    for (size_t i = 0; i < players.size(); ++i) {
        cout << "Player " << i + 1 << ":\n";
        cout << "------" <<endl;
        printCards(players[i]);
    }
}

void sort(vector <int> &deck)
{
    int firstCard, card;

    for(firstCard = 0; firstCard < (NUM_CARDS * NUM_PLAYERS - 1); firstCard++)
    {
        for(card = firstCard+1; card < (NUM_CARDS * NUM_PLAYERS); card++)
        {
            if( deck[card] < deck[firstCard] )
            {
                swap(deck, card, firstCard);
            }
        }
    }

}
Last edited on
Pages: 12