diff --git a/cardsim/rules.go b/cardsim/rules.go index 9b9953a..1291d94 100644 --- a/cardsim/rules.go +++ b/cardsim/rules.go @@ -7,6 +7,27 @@ import ( ) // A Rule implements an operation run on every game turn. +// +// Rule[C] is a generic interface. Like any other generic type, it describes a +// family of related types: each different kind of StatsCollection that Rule +// could pertain to is the basis of a distinct type of Rule. +// +// When implementing a generic interface, you do not need to implement a +// generic type. In the case of Rule, you are likely to be writing rules for a +// specific simulation. That simulation will have some associated +// StatsCollection type. The rules you write will only need to implement the +// variation of Rule that pertains specifically to that type. +// +// For example, if your `StatsCollection` type is `KoboldMineData`, then rules +// for the simulation referring to it would implement `Rule[KoboldMineData]` +// only. So the `Enact` function you implment would take an argument of type +// `*Player[KoboldMineData]`, not some undefined type `C` that could be any +// StatsCollection. Since it takes a `*Player[KoboldMineData]` as an argument, +// you then know that the player's `Stats` field is not just any +// StatsCollection, it is KoboldMineData specifically. The compiler won't +// require you to convert from "some `StatsCollection`" to "`KoboldMineData` +// specifically" when using the `Player[KoboldMineData].Stats` field, +// because the type of that field is already `KoboldMineData`. type Rule[C StatsCollection] interface { // Label is an internal name the rule can be recognized by. // Some things may be easier if it is unique, but it does not have to be.