KoV
KoV

Reputation: 33

C++ - Shuffling a vector of objects

I am trying to make a deck of cards, I have a vector of card objects but when I use my shuffle function and print the deck they are all in the same order as they were when they were made.

Here's my playingCards class:

#include <iostream>
#include <string>
#include <random>
#include <vector>
#include <algorithm>

using namespace std;

class playingCards {
private:
    struct card {
        char suit;
        char value;
    };

    const int deckSize = 52;
    vector<card> deck;

public:
    playingCards();
    void printDeck();
    void shuffle();
};

playingCards::playingCards() {
    deck.reserve(deckSize);

    for (int i = 0; i < deckSize; i++) {
        int setSuit = i % 4;

        if      (setSuit == 0) deck[i].suit = 'D';
        else if (setSuit == 1) deck[i].suit = 'H';
        else if (setSuit == 2) deck[i].suit = 'S';
        else if (setSuit == 3) deck[i].suit = 'C';

        int setValue = i % 13;

        if      (setValue == 0)  deck[i].value = 'A';
        else if (setValue == 9)  deck[i].value = 'T';
        else if (setValue == 10) deck[i].value = 'J';
        else if (setValue == 11) deck[i].value = 'Q';
        else if (setValue == 12) deck[i].value = 'K';
        else                     deck[i].value = '0' + (setValue + 1);
    }
}

void playingCards::printDeck() {
    for (int i = 0; i < deckSize; i++) {
        cout << deck[i].value << deck[i].suit << endl;
    }
}

void playingCards::shuffle() {
    auto rng = default_random_engine {};

    std::shuffle(begin(deck), end(deck), rng);
}

I've also tried to pass by reference my vector into the shuffle function like so:

void playingCards::shuffle(vector<card>& deck) {
    auto rng = default_random_engine {};

    std::shuffle(begin(deck), end(deck), rng);
}

This didn't work either. Any help would be appreciated, I'm new to using vectors so I really don't understand what could be happening here.

Upvotes: 2

Views: 1157

Answers (2)

user4222907
user4222907

Reputation:

You have to use

deck.emplace_back(value)

in order to create the actual vector. You just reserved the allocated memory which does not instantiate the vector. Beware of using deck[i], this can cause undefined behavior, instead, use deck.at(i). For this specific question, use deck.emplace_back(value) instead of deck[i].

Upvotes: 3

Benjamin Lindley
Benjamin Lindley

Reputation: 103733

deck.reserve(deckSize);

That doesn't add any elements to your vector, it only reserves space for them. So the size of your vector is zero, and when you shuffle it, nothing happens. The rest of your constructor, which sets (non-existent) elements of the vector, as well as your printDeck function, are both undefined behavior. Use resize instead.

deck.resize(deckSize);

In fact, it would be better to just remove the deckSize variable altogether, and just use deck.size().

Upvotes: 3

Related Questions