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

问题描述 投票:0回答:2

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

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

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++ pointers smart-pointers
2个回答
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);是合理的(因为卡的激活逻辑可能需要以某种方式读取和/或更新播放器对象的状态)。


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();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.