Ophitect
Ophitect

Reputation: 543

Vector not getting inserted

I have two class which is Player and Deck. Both Player and Deck has a vector of Card type. I'm trying to draw card from deck, which then remove the card in the deck card vector and then adding it into the player card vector. However, the card in deck is removed successfully but the card in my player is not being added. The vector size of cards in Player remain 0.

Code:

(Deck)

void Deck::GiveCards(std::vector<Player> pv) {
    for (int i = 0; i < 7; i++) {
        for each(Player p in pv) {
            int a = rand() % Deck::deckCards.size();
            CardType card = Deck::deckCards[a];
            p.DrawCard(card, p.GetHands());
            Deck::deckCards.erase(Deck::deckCards.begin()+a);
        }
    }
}

(Player)

void Player::DrawCard(CardType card, std::vector<CardType>& hand) {
    hand.push_back(card);
}

std::vector<CardType> Player::GetHands() {
    return Player::handCards;
}

I'm sure that the code in Deck is working perfectly. It execute the entire code in Deck. But, for some reason, it's not pushing the value into the vector in Player class.

Full code:

(Deck)

Deck::Deck() {
    for (int i = 0; i < 4; i++) { // i refer to color
        CardType card(EnumValue::ZERO, EnumValue::NONE, i);
        Deck::InsertCardToDeck(card);
        for (int j = 1; j <= 18; j++) {
            int cardValue = ceil(j / 2.0);
            CardType card(cardValue, EnumValue::NONE, i);
            Deck::InsertCardToDeck(card);
        }
        for (int j = 0; j < 6; j++) {
            if (j < 2) {
                CardType card(EnumValue::SKIP, EnumValue::SKIP_EFFECT, i);
                Deck::InsertCardToDeck(card);
            }
            else if (j < 4) {
                CardType card(EnumValue::REVERSE, EnumValue::REVERSE_EFFECT, i);
                Deck::InsertCardToDeck(card);
            }
            else {
                CardType card(EnumValue::DRAW2, EnumValue::DRAW2_EFFECT, i);
                Deck::InsertCardToDeck(card);
            }
        }
    }
    for (int j = 0; j < 4; j++) {
        CardType card(EnumValue::DRAW4, EnumValue::DRAW4_EFFECT, EnumValue::RAINBOW);
        Deck::InsertCardToDeck(card);
    }
    for (int j = 0; j < 4; j++) {
        CardType card(EnumValue::WILD, EnumValue::WILD_EFFECT, EnumValue::RAINBOW);
        Deck::InsertCardToDeck(card);
    }
}

void Deck::InsertCardToDeck(CardType card) {
    Deck:deckCards.insert(deckCards.end(), card);
}

std::string Deck::PrintDeck() {
    std::string textOutput = "";
    std::vector<int>::size_type sz = Deck::deckCards.size();
    for (int i = 0; i < sz; i++) {
        textOutput += std::string("Card ") + std::to_string(i) + ": It's a " + GetColorValue(deckCards[i].GetColor()) + " " + GetNumberValue(deckCards[i].GetValue()) + "\r\n";
    }
    return textOutput;
}

std::string Deck::GetColorValue(int color) {
    switch (color) {
    case 0:
        return "RED";
    case 1:
        return "YELLOW";
    case 2:
        return "GREEN";
    case 3:
        return "BLUE";
    default:
        return "RAINBOW";
    }
}

std::string Deck::GetNumberValue(int color) {
    switch (color) {
    case 0:
        return "ZERO";
    case 1:
        return "ONE";
    case 2:
        return "TWO";
    case 3:
        return "THREE";
    case 4:
        return "FOUR";
    case 5:
        return "FIVE";
    case 6:
        return "SIX";
    case 7:
        return "SEVEN";
    case 8:
        return "EIGHT";
    case 9:
        return "NINE";
    case 10:
        return "SKIP";
    case 11:
        return "REVERSE";
    case 12:
        return "DRAW 2";
    case 13:
        return "DRAW 4";
    default:
        return "WILD";
    }
}

void Deck::ShuffleDeck() {
    std::random_shuffle(Deck::deckCards.begin(), Deck::deckCards.end());
}

void Deck::GiveCards(std::vector<Player>& pv) {
    for (int i = 0; i < 7; i++) {
        for(Player p:pv) {
            int a = rand() % Deck::deckCards.size();
            CardType card = Deck::deckCards[a];
            p.DrawCard(card, p.GetHands());
            Deck::deckCards.erase(Deck::deckCards.begin()+a);
        }
    }
}

(Player)

void Player::DrawCard(CardType card, std::vector<CardType>& hand) {
    hand.push_back(card);
}

std::vector<CardType>& Player::GetHands() {
    return handCards;
}

Player::Player() {
    int a = rand() % 10;
    Player::name = "Bot Player " + std::to_string(a);
}

Player::Player(std::string names) {
    Player::name = names;
}

std::string Player::PrintCard() {
    std::string c = Player::name;
    for(CardType a:handCards) {
        c += std::string(" has: ") + Deck::GetColorValue(a.GetColor()) + " " + Deck::GetNumberValue(a.GetValue()) + "\r\n";
    }
    return c;
}

Upvotes: 1

Views: 85

Answers (2)

R Sahu
R Sahu

Reputation: 206567

In this function,

std::vector<CardType> Player::GetHands() {
    return Player::handCards;
}

you are returning a copy of Player::handCard. Change it to return a reference instead:

std::vector<CardType>& Player::GetHands() {
    return handCards;
}

Update

Change

    for each(Player p in pv) {

to

    for each(Player& p in pv) {

Update 2

In response to the latest comment from @Ophitect.

Looks like

   for each(Player p in pv) {

cannot be used get a non-const reference to the objects in pv. I would change that loop to:

    std::vector<Player>::iterator iter = pv.begin();
    std::vector<Player>::iterator end = pv.end();
    for (; iter != end; ++iter ) {
        Player& p = *iter;
        int a = rand() % Deck::deckCards.size();
        CardType card = Deck::deckCards[a];
        p.DrawCard(card, p.GetHands());
        Deck::deckCards.erase(Deck::deckCards.begin()+a);
    }

Upvotes: 2

Remy Lebeau
Remy Lebeau

Reputation: 595712

Try this code instead:

void Deck::GiveCards(std::vector<Player> &pv) {
    for (int i = 0; i < 7; i++) {
        for each(Player& p in pv) {
            int a = rand() % deckCards.size();
            p.GiveCard(deckCards[a]);
            deckCards.erase(deckCards.begin()+a);
        }
    }
}

void Player::GiveCard(const CardType& card) {
    handCards.push_back(card);
}

Or this:

void Deck::GiveCards(std::vector<Player> &pv) {
    for (int i = 0; i < 7; i++) {
        for each(Player& p in pv) {
            p.DrawRandomCard(*this);
        }
    }
}

CardType Deck::DrawRandomCard()
{
    int a = rand() % deckCards.size();
    CardType card = deckCards[a];
    deckCards.erase(deckCards.begin()+a);
    return card;
}

void Player::DrawRandomCard(Deck& deck) {
    handCards.push_back(deck.DrawRandomCard());
}

Upvotes: 0

Related Questions