【问题标题】:How can I know who owns certain pointer我怎么知道谁拥有某个指针
【发布时间】:2019-03-26 00:23:58
【问题描述】:

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

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

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&amp;) 让我知道是谁激活了这张牌(这看起来很奇怪,因为这张牌是属于玩家的,所以不需要指定)。

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

3) 或者我如何从玩家内部激活卡片,并在卡片的效果中使用该玩家。

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

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

【问题讨论】:

  • 我很想拥有一个player::take_turn() 函数,让玩家可以访问包,以便他们可以抽取、激活和归还自己的卡。
  • 可能比这里更适合Code Review。这看起来相当复杂。想想你的对象代表什么以及它们与其他对象有什么交互。如果“激活”一张卡片改变了卡片本身的属性,那么就这样做。相反,如果它给玩家一些特殊的“效果”,那么可能你错过了一些类(例如effect),这就是你感到困惑的原因。
  • 这更像是一个“代码审查/意见”之类的问题,这并不是真正的 SO 的 MO。但是,IMO,如果卡需要知道其所有者的唯一时间是在激活时,那么选项 1 似乎是最好的。如果不是这样的话……好吧,你知道它们将如何被使用,所以你是最好的判断和决定的人。

标签: c++ pointers smart-pointers


【解决方案1】:

根据现实生活中的直觉,当人类纸牌玩家将牌放回牌组时,您通常会要求玩家打出牌,然后将其放回牌组(而不是更不寻常的情况是卡片在没有玩家参与的情况下将自己放回套牌中——这通常是为魔术而保留的:))

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

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】:

    说实话,这是非常基于意见的。我可能会这样做,当游戏控制器指示take_turn()(本例中为循环)时,让player 负责玩自己的牌。

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

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 2021-09-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多