2023-03-27 06:40:44 +00:00
|
|
|
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)
|
|
|
|
|
2023-04-01 19:02:14 +00:00
|
|
|
// Urgent reports whether the card is considered urgent. If
|
|
|
|
// the player hasa any
|
|
|
|
Urgent(p *Player[C]) bool
|
|
|
|
|
2023-03-27 06:40:44 +00:00
|
|
|
// 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)
|
2023-03-28 03:21:57 +00:00
|
|
|
|
|
|
|
// Then is invoked after an option is selected and executed. The selected
|
|
|
|
// option is provided as an argument. This allows cards to do certain
|
|
|
|
// cleanup for every action -- for example, returning to the deck.
|
|
|
|
Then(p *Player[C], option CardOption[C]) error
|
2023-03-27 06:40:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2023-03-28 03:21:57 +00:00
|
|
|
// A BasicCard is a Card with fixed title, text, options, and optional post-option callback.
|
2023-03-27 06:40:44 +00:00
|
|
|
type BasicCard[C StatsCollection] struct {
|
|
|
|
CardTitle Message
|
2023-04-01 19:02:14 +00:00
|
|
|
IsUrgent bool
|
2023-03-27 06:40:44 +00:00
|
|
|
CardText Message
|
|
|
|
CardOptions []CardOption[C]
|
2023-03-28 03:21:57 +00:00
|
|
|
AfterOption func(p *Player[C], option CardOption[C]) error
|
2023-03-27 06:40:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (b *BasicCard[C]) Title(p *Player[C]) (Message, error) {
|
|
|
|
return b.CardTitle, nil
|
|
|
|
}
|
|
|
|
|
2023-04-01 19:02:14 +00:00
|
|
|
func (b *BasicCard[C]) Urgent(_ *Player[C]) bool {
|
|
|
|
return b.IsUrgent
|
|
|
|
}
|
|
|
|
|
2023-03-27 06:40:44 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2023-03-28 03:21:57 +00:00
|
|
|
func (b *BasicCard[C]) Then(p *Player[C], option CardOption[C]) error {
|
|
|
|
if b.AfterOption == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return b.AfterOption(p, option)
|
|
|
|
}
|
|
|
|
|
2023-03-27 06:40:44 +00:00
|
|
|
// 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)
|
|
|
|
}
|