首页 > 解决方案 > 我怎么知道谁拥有某个指针

问题描述

我正在编写一个个人项目,让玩家从牌组中抽牌。然后玩家激活卡片(有不同类型的卡片,每种都有不同的效果),最后他将卡片放回卡组底部。

到目前为止,我已经设法从牌组中抽出卡片并将其存储在我的播放器中。假设我只有两种类型的卡片:

class card
{
public:
    virtual void activate() = 0;
};

class moveAnywhere : public card
{
public:
    virtual void activate();
};

class bonusQuestion : public card
{
public:
    virtual void activate();
};

然后我有我的牌组(玩家是朋友):

class deck
{
private:
    std::queue<std::unique_ptr<card>> cards;
public:
    friend class player;
};

最后是我的播放器:

class player
{
private:
    std::list<std::unique_ptr<card>> usableCards;
public:
    void drawCard(deck&);
};


void player::drawCard(deck& theDeck)
{
    usableCards.push_back(std::unique_ptr<card>(std::move(theDeck.cards.front())));
    theDeck.cards.pop();
}

通过这种方式,我设法从牌库中取出第一张牌,并将其存放在玩家手中。但我的问题是如何激活和返回牌组。

1)最好card::activate(player&)让我知道是谁激活了这张牌(这看起来很奇怪,因为这张牌属于玩家,所以不需要指定)。

2) 给卡片添加一个私人成员会更好吗?例如player owner;,每次有人抽一张卡片时,它都会为卡片分配一个所有者。

3)或者我怎样才能从玩家内部激活卡,并在卡的效果中使用该玩家。

4) 将卡片放回牌组的逻辑方式是什么?那应该是卡牌、玩家、套牌的方法吗?

我相信我把情况复杂化了,我只是感到困惑,需要一点点朝着正确的方向前进。

标签: c++pointerssmart-pointers

解决方案


老实说,这是非常基于意见的。我可能会选择这样的东西,当游戏控制器(本例中的循环)player指示时,让他们负责玩自己的手。take_turn()

class card
{
public:
    virtual void activate() {}
};

class deck
{
private:
    std::queue<std::unique_ptr<card>> cards;

public:

    std::unique_ptr<card> draw()
    {
        auto c = std::move(cards.front());
        cards.pop();
        return c;
    }

    void put_back(std::unique_ptr<card> c)
    {
        cards.push(std::move(c));
    }
};

class player
{
private:
    deck& cards;
    std::list<std::unique_ptr<card>> hand;

    std::unique_ptr<card> select_card()
    {
        // select the best card from the hand
        // and return it

        auto c = std::move(hand.front()); // something cleverer than this!
        hand.pop_front();
        return c;
    }

public:
    player(deck& cards): cards(cards) {}


    void take_turn()
    {
        // draw a card from the deck
        auto c = cards.draw();
        hand.push_back(std::move(c));

        // select the best card to activate
        c = select_card();
        c->activate();

        // return card to deck
        cards.put_back(std::move(c));
    }
};

int main()
{
    deck cards;
    player wendy(cards);
    player bob(cards);

    while(true)
    {
        wendy.take_turn();
        bob.take_turn();
    }
}

推荐阅读