card game

How do you create a game where two players each draw a card, where the card deck is created by an array?
Use vector :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <vector>

card pick(std::vector<card>& deck){
    card c;
    int i;
    i=rand()%deck.size();
    c=deck[i];
    deck.erase(deck.begin()+i);
    return c;
}

int main(){
    std::vector<card> deck;
    (here use deck.push_back(yourCard) to add cards)

    std::vector<card> deck_player;
    deck_player.push_back(pick(deck)); //fill the deck of a player, removing card from the global deck
    
return 0;
}
Last edited on
@Zaap vector seems just a tad bit complicated for this, why would he use it?
One advantage is that you can dynamically resize the deck after its been drawn, which is what is shown.

Of course, this can be done with arrays too, but then you need to keep track of what the "real" size of the deck array is, and have to do all the swapping/shifting of the card array manually, instead of just erasing the element.

std::vector<Card> cards(52); isn't that much more complicated than Card cards[52]; in itself.
both can still be assigned like
1
2
3
4
for (int i = 0; i < 52; i++)
{
    cards[i] = Card(...);
}
Last edited on
@highwayman, @azsxd, I'm with @Ganado on this point, while it seems arrays are simpler, they are in fact more work in all but trivial examples, and that work is more likely to invite bugs. Obviously a simple deck of cards is close to bare bones trivial, and some students need to practice with arrays anyway.

I'm also a fan of std::deque, an underused container, for this kind of purpose.

One of the issues with using an array is creating the deck and shuffling it. There are algorithms in the STL which can shuffle the deck, without having to build an algorithm to do that manually in an array.

One might argue that the shuffle algorithms could apply to arrays, but by the time one has familiarity with STL algorithms, using vector or deque (or even something else, perhaps) is usually a net gain, and what complexity is perceived over the C style array evaporates once the algorithms are learned.

At best, an array is as simple as a vector. That's if you're doing almost nothing with it.

As soon as you want to start doing anything with it, using an array is much more complicated than using a vector. I go so far as to say that in C++, arrays aren't for beginners; vector is for beginners and an array is for intermediate level C++ programmers.

The number of C++ courses I see that teach arrays before vector; effectively teaching C first. I try to stay calm but it's just massively missing the point of using C++.
Last edited on
The trouble with that is that many programmers won't get to arrays ever if they do vectors first. Which is not crippling but there will be knowledge gaps if you let the tool do it all for you, and you may struggle harder when confronted with something you just can't do with the built in tools or scratching your head when something is slow due to under the hood stuff. And, this IS crippling if they have to move to a language that lacks containers. (the point of classwork is to learn a generic programming knowledge, not to master a language). If your first job is in C, and you skipped arrays and pointers, you might be in for a rough period.

So I can see it both ways. You will use vectors mostly, and they are the more important tool. But you will use them better if you did a few array programs (before or after, does not matter to me).

That said, how is that code complicated? Its inefficient, but its fairly simple.
Not a fan of erase -- its more efficient to shuffle the deck and just iterate it card by card, so you can reshuffle and go again without all the inserts and deletes, which makes my point above...
if you must take the card from the deck 'physically', then shuffle and do pop back.
doing the exact same thing in an array would take about as much code.
Last edited on
I was just saying that an array would be simpler because it doesn’t even seem like the op necessarily want to constantly resize the array. It seems like we are using a useful tool without fully considering its purpose. Nowhere in the question does the op say that the deck would change in terms of space, just in terms of the number of cards the difference I am seeing here is that in one there is a fixed amount of space of which the deck holds. This does not necessarily mean that the space defines the amount of cards, but it seems we are going to be unnecessarily (I use that word way too much lol) resizing the array just because we can. I will concede, seeing as y’all are a lot more experienced than me, but just saying..
I agree, so I will clarify: the *algorithm* in that snippet with the grow to fit and remove back out stuff is over-engineered and unnecessary. the *code* expressing it, however is simple. A better algorithm would have about the same code at about the same reading level. And it may not matter. The extra work here is a bit head scratching but this isnt a 10 to the grillionth chef problem, its 50-something cards. I personally cringe at anything that is doing too much work, but that is my own hangups.
Last edited on
Ok ya alright. I have just been personally a bit terrified of vectors for a while, that’s just me though.
my 2 cents:

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
#include <cstdio> //a pile of common includes. not all needed here. 
#include <cstring>
#include <iostream>
#include <string>
#include <algorithm>
#include <ctype.h>
#include <stdint.h> 
#include <cmath>
#include <vector>
#include <numeric>
#include <random>
using namespace std;

int main()
{
 string suit ="CSHD"; //the 4 suits
 string face = "A23456789XJQKA"; //the 13 cards see note maybe T for 10 instead of X?
 vector<int> deck(52);
 iota(deck.begin(), deck.end(), 0);
 std::shuffle(deck.begin(), deck.end(), mt19937{std::random_device{}()});
 
 for(int i = 0; i<deck.size(); i++) 
 cout << suit[deck[i]/13]<<face[deck[i]%13]<<endl; //+1 is 2,3,..A while as is =  A,2,...K
 //so the above loop is just going thru the deck.  add logic in the loop to
 //alternate players and do whatever the game rules need.  
//reshuffle and repeat as needed to play multiple times in a loop etc. 
//there are better ways to represent which card is which.  this is a simple one. 
}
Last edited on
Arrays are fine for a fixed number of items. But if the number of items changes, use a vector instead. Clearly when you deal a card from a deck, the deck has one less card, so you don't want a vector.

Another nice thing about using a vector is that a player's hand and a deck of cards start looking like the same code, at least partially.

Spend a little time coding up a Card class. One important thing to keep in mind: the way you represent the cards internally doesn't have to be the same way that you display the cards to the user. For example, you might be tempted to do this:
1
2
3
4
5
6
7
8
class Card {
public:
    string suit;
    string value;
};
ostream operator << (ostream &os, const Card &card) {
    return os << card.value << " of " << card.suit;
}

That's easy for doing the I/O but how will you compare cards for, say a straight in poker (5 cards with successive values)? That becomes a nightmare.

It's better to represent the suit and value as integers, or enums, or a combination. Create code to convert the internal representation to/from a user-friendly string.
It's better to represent the suit and value as integers, or enums, or a combination. Create code to convert the internal representation to/from a user-friendly string.

which I did in a very crude way.

if you want to go all OOP on it, I would be tempted to not fool with a card class at all for this program. Your deck/container class can be both the deck and a player's hand (so it needs a generic name). And all it has to do is store/manage the values in each container and convert those values to text/graphics on the back end. If you replace my suit and face strings with a vector of strings, you can have full names ("ace" etc) and "hearts", and do 100% of the program sans OOP, though you do have a design flaw of a few tightly coupled vectors (most of which are static lookups) roaming around outside of a pen.
Last edited on
It's better to represent the suit and value as ...

Best is what works and meets sufficiently the requirements (and -- from a programmer point of view -- is easy to maintain in case the customer changes some silly stipulations).
The OP requested "a game where two players each draw a card, where the card deck is created by an array." That is very vague over all but very clear about array.

What creates a card deck? Would an array of flags be sufficient? Two values, 1=in deck, 0=dealt out, the array index is the card number which denotes suit and avers (face) by fixed sequences. To shuffle the deck there is no need to move data within the array, just all flags=1 is enough as dealing is fortuitously choosing a card (at random) still available in deck. Remaining cards in deck (to trigger another shuffle)? Sum the array. How about two or more decks? NP, resize the array accordingly. Find a working example at http://www.cplusplus.com/forum/general/252307/#msg1110816 -- just argue, bitset is an array, sort of, it is an array of bits.
Topic archived. No new replies allowed.