【问题标题】:Vector not getting inserted未插入向量
【发布时间】:2014-05-18 05:54:07
【问题描述】:

我有两个类,即 Player 和 Deck。 Player 和 Deck 都有一个 Card 类型的向量。我正在尝试从牌组中抽牌,然后从牌组牌矢量中删除牌,然后将其添加到玩家牌矢量中。但是,卡组中的卡已成功移除,但我的播放器中的卡未添加。 Player中卡片的向量大小保持为0。

代码:

(甲板)

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);
        }
    }
}

(玩家)

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

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

我确信 Deck 中的代码运行良好。它在 Deck 中执行整个代码。但是,由于某种原因,它没有将值推送到 Player 类中的向量中。

完整代码:

(甲板)

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);
        }
    }
}

(玩家)

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;
}

【问题讨论】:

  • 您通过复制而不是通过引用获取pv。所以当玩家的DrawCard()函数被调用时,只是玩家的副本,而不是原来的玩家被修改。
  • 除非你有一些奇怪的宏,否则这不是有效的 C++。
  • jogojapan: void DeckType::GiveCards(std::vector& pv) ?克里斯:我是 C++ 新手。
  • 是的,完全正确。相当于这里描述的问题:stackoverflow.com/questions/10959694/…
  • @Ophitect,我不明白 C++ 的新手有什么意义。这不应该在没有晦涩的宏的情况下编译,但是您描述了运行时行为。

标签: c++ vector


【解决方案1】:

在这个函数中,

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

您将返回Player::handCard 的副本。将其更改为返回引用:

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

更新

改变

    for each(Player p in pv) {

到

    for each(Player& p in pv) {

更新 2

回应@Ophitect 的最新评论。

看起来像

   for each(Player p in pv) {

不能用于获取对pv 中对象的非常量引用。我会将该循环更改为:

    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);
    }

【讨论】:

  • 修改为返回引用,但似乎仍然无法将值推回向量中。
  • @Ophitect,你有一行for each(Player p in pv) {。那不是 C++ 代码。您可以发布您正在使用的代码吗?您可能还有另一种使用副本而不是参考问题的情况。
  • 在 Visual C++ 中有效。假设使用的 Visual C++ 版本支持它,基于范围的循环会更好,并且可移植。
  • Error 28 error C2440: 'initializing' : cannot convert from 'const Player' to 'Player &'
  • 是的。有效。 C++ 比我预期的要困难得多。所以我还需要在循环中使用引用?
【解决方案2】:

试试这个代码:

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);
}

或者这个:

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());
}

【讨论】:

    猜你喜欢
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 2019-09-14
    相关资源
    最近更新 更多