CardSimEngine/cardsim/card.go

94 lines
3.1 KiB
Go
Raw Normal View History

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