我怎么知道谁拥有某些指针

时间:2019-03-26 00:23:59

标签: c++ pointers smart-pointers

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

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

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)将卡归还卡片组的逻辑方式是什么?那应该是发牌,玩家,套牌的方法吗?

我相信情况太复杂了,我很困惑,需要向正确的方向稍作努力。

2 个答案:

答案 0 :(得分:2)

根据现实的直觉,当真人纸牌玩家需要将卡牌放回副牌时,您通常会要求牌手将牌打出然后将其放回副牌中(相对于更常见的情况是,卡片在没有玩家参与的情况下将自己放回卡组中-通常留给魔术使用:))

因此,我会选择类似的东西:

std::unique_ptr<card> player :: activateAndReturnCard()
{
   // code for the player-object to choose a card to
   // remove from his hand, activate it, and then return it
}

...然后套牌类(或任何人)可以在适当的播放器对象上调用上述方法,并将结果返回到套牌中。鉴于以上所述,在卡对象上进行玩家对象调用activate(*this);是合理的(因为卡的激活逻辑可能需要以某种方式读取和/或更新玩家对象的状态)。

答案 1 :(得分:2)

说实话,这是非常基于意见的。我可能会选择类似的方法,在游戏控制器指示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();
    }
}