vectors and card dealing

Hi - I written some code that has a class card and clas DeckofCrads. So far I have managed to create the deck and print the deck, then shuffle the pack and print the shuffled pack.
I need to deal the cards. I was thinking of creating a class called player or hand which would be a vector container to hold the cards. This way it would be easier to change the number of cards dealt to each playerand number fo players?
What I would like to do is take the tope card, postion 52 in the vector deckofcards, and then place it in the first position of the player/hand vector. I can do this with push_back, but how do I renove the card from ther deck and resize the vector so it goes from 52 - 0 when all cards are gone. I have a size of deck function. I would also like to deal the cards so player 1 first card player 2 second card etc until either all cards are gone or the correct amount has been dealt.

Below is what I have managed so far. I am just a beginner

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
142
  #include <iostream>
#include "Card.hpp"
#include "DeckOfCards.hpp"

int main() {
    
    
    DeckOfCards testDeck;
    //show deck before shuffle
    std::cout << "Deck of cards" << std::endl;
    for (int i = 0; i < 52; i++) {
        std::string display = testDeck.showCard(i).printCard();
        std::cout << display << std::endl;
    }
    
    //shuffle and print deck
    std::cout << "\nDeck of Cards after shuffled" << std::endl;
    testDeck.shuffle();
    for (int i = 0; i < 52; i++) {
        std::string display = testDeck.showCard(i).printCard();
        std::cout << display << std::endl;
    }
    
    
    std::cout << "Number of cards available is: " << testDeck.sizeOfDeck() << std::endl;
    
    return 0;
}

#include "Card.hpp"
#include <iostream>
#include <string>

Card::Card( int face_val, int suit_val ){
    suit = suit_val;
    face = face_val;
}

std::string Card::faces[13] = {"Ace","Two","Three", "Four", "Five", "Six",
    "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King" };

std::string Card::suits[4] = {"Hearts", "Clubs", "Diamonds", "Spades" };

std::string Card::getFace(){
    return faces[face];
}

std::string Card::getSuit(){
    return suits[suit];
}

std::string Card::printCard(){
    
    std::string faceAndSuit = getFace() + " of " + getSuit();
    return faceAndSuit;
}

#ifndef Card_hpp
#define Card_hpp
#include <string>

class Card{
public:
    Card( int suit_val, int face_val );
    static std::string faces[13];
    static std::string suits[4];
    std::string getSuit();
    std::string getFace();
    std::string printCard();
private:
    int face;
    int suit;
};

#endif /* Card_hpp */

#include "DeckOfCards.hpp"
#include <ctime>
#include <cstdlib>


DeckOfCards::DeckOfCards(){
    for (int suit = 0; suit < 4; suit++){
        for (int face = 0; face < 13; face++) {
            Card cards(face, suit);
            deck.push_back(cards);
        }
    }
}

Card DeckOfCards::showCard(int i){
    Card topCard = deck[i];
    return topCard;
};


void DeckOfCards::shuffle(){
    srand(static_cast<unsigned int>(time(NULL)));
    for (int i = 0; i < 52; i++) {
        int shuffle = ( rand() % 52 );
        Card c1 = deck[i];
        Card c2 = deck[shuffle];
        Card temp = c1;
        deck[shuffle]= temp;
        deck[i] = c2;
    }
}

bool DeckOfCards::moreCards(){
    if (deck.size() > 0) {
        return true;
    }
    else
        return false;
}

unsigned long int DeckOfCards::sizeOfDeck(){
    return deck.size();
}

#ifndef DeckOfCards_hpp
#define DeckOfCards_hpp
#include <vector>
#include "Card.hpp"



class DeckOfCards{
public:
    DeckOfCards();
    void shuffle();
    void dealCard();
    Card showCard(int i);
    bool moreCards();
    unsigned long int sizeOfDeck();
private:
    std::vector<Card> deck;
    int currentCard;
};

#endif /* DeckOfCards_hpp */
Suppose you have 4 players and you want to give them 9 cards each. You'll need a DeckOfCards object that holds all the cards at the beginning of the game and a vector<DeckOfCards>, size 4 for the 4 players that'll receive the dealt cards. Once the vector<DeckOfCards> has been populated, i.e. the cards have been dealt, you can use them to instantiate objects of a class Player for example or any other way that you wish.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
vector<Card>& :: DeckOfCards getCard()//a getter method to return the deck member of given DeckOfCards object; 
{
	return *this.deck;
}
DeckOfCards master;//the default ctor already populates this deck with 52 cards; 
vector<vector<Card>> dealt_cards;
for (int i = 0; i < 9; i++)
{
	for (int j = 0; j < 4; j++)
	{
		vector<Card>::reverse_iterator itr = std::next(getCard(master).rbegin(), 1);
		//returns the 1st successor of reverse iterator getCard(master).rbegin();
		dealt_cards[j].push_back(move(master.getCard().back()));
		//moves the last element of master.getCard() to the j'th vector<Card> in dealt_cards;
		//the cell in master.getCard() that held the moved card still remains but does not necessarily contain the same value as before; 
		master.getCard().erase(master.getCard().rbegin(), itr);
		//removes actual cell from which the card moved from master.getCard() AND reduces the master.getCard() container size;
	}
	
	i++;
}

Since you're moving cards from the back of the master.getCard (or as you say, 'position 52') a vector container is fine but if you were to move cards from the front then a STL deque would have been a more appropriate choice. Also if your compiler is C+11 compliant, you may wish to use crbegin() which is a constant reverse iterator that cannot modify the value of an element as it iterates through master.getCard(). To make sure that not more than 52 cards are dealt out from master.getCard() you can also have some additional conditions in your loops to preclude this event. Additional header files to include: iterator (for back_inserter), algorithm (for next, move, erase)

This is a stylized solution of how to deal the cards; if you find it useful please try and adapt it according to your needs and then come back here if something is still unclear or doesn't work.
Last edited on
Cheers! I have a bit of a rethink. I can create a vector of cards with the following:-
I have written the following in main() and it works as expected. the card constructor is called int he .push_back function and the meber fucntions are used to get the correct intgeres for face and suit. Once I have dealt the hand how do I then remove that card from the pack?

I'm not sure if this is possible but here goes... I would like to create a class called players which has four postions [0,1,2,3] representing each player. Then at each position would be a class called hand which would hold the player cards that have been dealt from the pack. Or is that maybe just to complicated?

1
2
3
4
5
6
7
8
9
std::vector<Card> deal;
    
    std::cout << "Deal 5 cards from the deck" << std::endl;
    for (int i = 0; i < 5; i++) {
        std::cout << "Card: " << i + 1;
        std::string dealcard = testDeck.dealCard(i).printCard();
        std::cout << " " << dealcard << std::endl;
        deal.push_back(Card(testDeck.showCard(i).getIntegerFace(),testDeck.showCard(i).getIntegerSuit()));
    }
No matter if you deal from a vector<Card> object directly or through a DeckOfCards object by accessing its deck member which is also of type vector<Card>. As long as you want to remove the card from the pack after it has been dealt you're in the realm of C++'s move semantics where you'd have to call move() and erase() in turn as shown in my previous post. And, as mentioned there, erase() would remove the vector element that held the card dealt and resize (reduce) the vector<Card>.

If you have Class Player then you probably don't need a Class Hand and I describe above how you can instantiate the vector<Card> data member of Player directly from the cards that have been dealt.

Lastly, want to draw your attention to couple of edits in my previous post: line 6 should be vector<vector<Card>> dealt_cards which'd make line 13:

dealt_cards[j].push_back(move(master.getCard().back()));
Last edited on
Thanks! I will give it a go later and let you know how I get on!!!

Thanks again.

James
Hi Sorry to ask again but I am really struggling with this. Can't seem to get it towork at all 😞
All I want to do is take a number of cards from the deck, store them in another DeckOfCards object and reduce the original deck by the number of cards dealt?
Why is proving to be so difficult lol

James
Please can anyone help!!
Just typing up my reply
Here you go:

Most important thing you need to do is to define the move copy constructor and the move assignment operator for the Card class since you're moving Card objects around

Also, the erase function to reduce the size of the container after a card has been dealt has to be a member function of Deck since we're reducing the size of the container<Card> member of object of type Deck.

Other than that I've changed the container from vector to deque since it's more efficient for removing and inserting elements at both ends (and not just from the back which is the case for vectors and in this example, so deque gives you more flexibility)

Header: http://pastie.org/10954572
Implementation: http://pastie.org/10954574
Main(): http://pastie.org/10954575

Please read, research and if something is still unclear do come back here.

edit: range loops and auto declarations require C++11 compilers
Last edited on
Cheers I have created a class hand, and moved my vector<Card> deck from private to public. Now I can do this:-

Hand player( 10, testDeck);

std::cout << "Hand dealt:" << std::endl;
for (int i = 0; i < player.sizeOfDeck(); i++) {
std::string display = player.showCard(i).printCard();
std::cout << display << std::endl;
}

Where my hand constructor uses an int and the deck, then copies thsi to the hand vector of Cards. Ive essentially 'copied' the deck class but changed constructor???

It does work the correct cards go into hand but seems a bit of a shitty way really.
Please bear in mind i am new to c++ and its only a'hobby'for the dark nights..

James

Can you show the implementation of class Hand?
Thanks gunnerfunner I really appreciate you taking time to help me. I have looked at your code, and bearing in mind I am very new to this, I need time to read it and try and understand. You have used operator overloading and constructor overloading. We have thus far only used constructor overloading. I am working through CPP How to program chapter by chapter, on a self teach basis. As you can imagine it isnt all that easy trying to learn 'the right way' from a book.

Thanks again!

James
Topic archived. No new replies allowed.