Как я могу узнать, кому принадлежит определенный указатель - PullRequest
0 голосов
/ 26 марта 2019

Я пишу персональный проект, в котором игроки рисуют карты из колоды. Затем игрок активирует карту (есть разные типы карт, каждый с разным эффектом), и, наконец, он возвращает карту в низ колоды.

Пока мне удалось вытащить карту из колоды и сохранить ее в моем плеере. Давайте представим, что у меня есть только два типа карт:

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 ]

2 голосов
/ 26 марта 2019

Это очень мнение, если честно.Возможно, я бы пошел на что-то вроде этого, дав 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();
    }
}
2 голосов
/ 26 марта 2019

Рисуя из реальной интуиции, когда игроку, играющему в карты, приходит время вернуть карту в колоду, вы, как правило, просите игрока сыграть карту и затем положить ее обратно в колоду (в отличие отболее необычный сценарий, когда карта помещается обратно в колоду без участия игрока - это обычно зарезервировано для фокусов:))

Поэтому я бы выбрал что-то вроде:

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); для объекта-карты (поскольку логике активации карты, вероятно, потребуется каким-то образом считывать и / или обновлять состояние объекта-игрока).

...