diff --git a/koboldsim/cardtypes.go b/koboldsim/cardtypes.go index d6108de..a01de74 100644 --- a/koboldsim/cardtypes.go +++ b/koboldsim/cardtypes.go @@ -285,7 +285,7 @@ func (v *VerbosePolicy) Enact(p *Player) (cardsim.Message, error) { msg, err = v.Variants[v.lastIdx].Enact(p) } if errors.Is(err, ErrUnimplemented) { - msg, err = v.Default.Enact() + msg, err = v.Default.Enact(p) } return msg, err } @@ -339,6 +339,61 @@ func (v *VerbosePolicy) Enabled(p *Player) (result bool) { return } +// FuncPolicy implements Policy by calling specified functions. If they're +// missing, it returns ErrUnimplemented. It handles Is itself. It also tracks +// LastEnacted data (last index, which policy, is policy self) itself. +type FuncPolicy struct { + OptionTextFunc func(*Player) (cardsim.Message, error) + EnactFunc func(*Player) (cardsim.Message, error) + EnabledFunc func(*Player) bool + UnenactFunc func(*Player) error + + // These three fields are assigned by LastEnacted and typically should not + // be set in the initializer. + LastEnactedIdx int + LastEnactedPolicy Policy + WasEnactedLast bool +} + +func (f *FuncPolicy) OptionText(p *Player) (cardsim.Message, error) { + if f.OptionTextFunc == nil { + return nil, ErrUnimplemented + } + return f.OptionTextFunc(p) +} + +func (f *FuncPolicy) Enact(p *Player) (cardsim.Message, error) { + if f.EnactFunc == nil { + return nil, ErrUnimplemented + } + return f.EnactFunc(p) +} + +func (f *FuncPolicy) Enabled(p *Player) bool { + if f.EnabledFunc == nil { + panic(ErrUnimplemented) + } + return f.EnabledFunc(p) +} + +func (f *FuncPolicy) Unenact(p *Player) error { + if f.UnenactFunc == nil { + return ErrUnimplemented + } + return f.UnenactFunc(p) +} + +func (f *FuncPolicy) LastEnacted(i int, p Policy) { + f.LastEnactedIdx = i + f.LastEnactedPolicy = p + f.WasEnactedLast = f.Is(p) +} + +func (f *FuncPolicy) Is(p Policy) bool { + fp, ok := p.(*FuncPolicy) + return ok && (f == fp) +} + // ShuffleIntoBottomHalf is a common "what to do with the card after?" behavior. func ShuffleIntoBottomHalf(c Card, p *Player, _ CardOption) error { p.Deck.InsertRandomBottom(0.5, c)