FuncPolicy: function pointer policy
For when you don't want to go to the trouble of writing a type, but do need actual functions.
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user