package cardsim // A Card represents an option available to the player. Its methods may be // called many times per turn as the player considers their options. type Card[C StatsCollection] interface { // Title is the short name of the card displayed in the hand // and at the top of the card output. It receives the current // player as an argument. If it returns an error that is not // a warning, the game crashes. Title(p *Player[C]) (Message, error) // EventText returns the text to display on the card. If it returns an // error that is not a warning, the game crashes. EventText(p *Player[C]) (Message, error) // Options returns the possible actions the player can take for this card. // There must be at least one option. Options(p *Player[C]) ([]CardOption[C], error) } // A CardOption represents a choice a player could make for some card. type CardOption[C StatsCollection] interface { // OptionText returns the text displayed for this option. It may be called // many times within a turn as the player considers their options. If it // returns an error that is not a warning, the game crashes. OptionText(p *Player[C]) (Message, error) // Enact is called exactly once if the player chooses the option. It is // expected to update values in `p`. It returns the text displayed to the // player as a result of their action. If it returns an error that is not // a warning, the game crashes. // // After an option is enacted, the card is deleted. If a card should be // repeatable, Enact must return it to the deck (on every option). Enact(p *Player[C]) (Message, error) } // A BasicCard is a Card with fixed title, text, and options. type BasicCard[C StatsCollection] struct { CardTitle Message CardText Message CardOptions []CardOption[C] } func (b *BasicCard[C]) Title(p *Player[C]) (Message, error) { return b.CardTitle, nil } func (b *BasicCard[C]) EventText(p *Player[C]) (Message, error) { return b.CardText, nil } func (b *BasicCard[C]) Options(_ *Player[C]) ([]CardOption[C], error) { return b.CardOptions, nil } // A BasicOption is a CardOption with fixed text, effects, and output. type BasicOption[C StatsCollection] struct { Text Message Effect func(*Player[C]) error Output Message } // OptionText implements CardOption. func (b *BasicOption[C]) OptionText(p *Player[C]) (Message, error) { return b.Text, nil } // Enact implements CardOption. func (b *BasicOption[C]) Enact(p *Player[C]) (Message, error) { return b.Output, b.Effect(p) } // OptionFunc attaches a fixed prompt to an Enact-like function. Unlike // BasicOption, the enactment function provided to OptionFunc returns // the text that should be output as a result of the action, so it is // possible to dynamically generate this text. func OptionFunc[C StatsCollection](text Message, f func(*Player[C]) (Message, error)) CardOption[C] { return &optionFunc[C]{text, f} } type optionFunc[C StatsCollection] struct { text Message f func(*Player[C]) (Message, error) } func (o *optionFunc[C]) OptionText(p *Player[C]) (Message, error) { return o.text, nil } func (o *optionFunc[C]) Enact(p *Player[C]) (Message, error) { return o.f(p) }