Consider a card game (something like Magic or Legends of Runeterra) program, with BaseCard
, Deck
and GameState
classes/structs. The way I've conceptualized the relationship between these classes would be something like this:
BaseCard.hpp
struct GameState;
class BaseCard
{
public:
virtual void DoEffect(GameState &gameState) = 0;
};
Deck.hpp
struct Deck
{
public:
std::vector<std::unique_ptr<BaseCard>> drawPile;
std::vector<std::unique_ptr<BaseCard>> discardPile;
std::vector<std::unique_ptr<BaseCard>> hand;
};
GameState.hpp
struct GameState
{
std::unique_ptr<Deck> deck;
};
The idea is that cards might have a variety of different effects that can change the GameState
, like draw cards, alter properties of cards currently in hand, recover player health and so on, which would be implemented in DoEffect
. I want the possibilities of what a card can do to be very flexible and I can't think of a way to that which doesn't involve passing the GameState
to the card, but at the same time the cards are also inherently part of the game state.
Naturally I can get the code to compile by using a forward declaration in BaseCard.hpp
then including GameState.hpp
in the cpp files with the concrete implementations of the classes that inherit BaseCard
, but this feels kinda "hacky" to me...
So my question here is whether this type of pattern is actually ok/normal in C++, and if not, what are possible alternatives.
std::unique_ptr<Deck>
unless you plan subclasses ofDeck