Closed jkomoros closed 4 years ago
PlayerIndexes are used in a LOT of places, e.g StatePropertyRef, etc. If they're an interface, then you'd be passing around the actual copy a lot, and it could be modified--which probably isn't what you want, because you pass the PlayerIndex to lots of other code and who knows what it'll do it with it. ... I guess you'd do the same ImmutablePlayerIndex/PlayerIndex split. But that... seems needlessly complicated.
There could be another type, a ValidPlayerIndex, which is just type ValidPlayerIndex PlayerIndex
, which communicates to the system, please validate that player index. Or do a struct tag that tells the system, this player index is one that needs to be kept valid.
The reasoning behind having it be a struct is 1) you can mix in the state pointer so you don't have to pass in state to all of the methods, and 2) you can make it so that arithmetic on it is prevented, to make it less likely that someone in userland accidentally trips themselves up.
The first seems kind of like an anti-pattern, because in many cases they're not in the context of a given State, and you wouldn't want others to modify it. It seems like there are easier ways to avoid the second.
Actually, this is unneccesary. Just mark clearly in the type documentation to not do arithmetic on them directly, and have a ValidOrNext() that everything uses to verify that the index is in a good place whenever it needs to get an index that might not be valid.
Originally captured in #755. Copying the reasoning here:
Another option: make PlayerIndex an opaque type, that's actually a struct. When serialized to/from JSON it would pretend to be just an int, but in the actual live structs it would be a struct that has a pointer to the (possibly nil) state it's in. That would disallow arithmetic on it naturally, and also let things like Next / Prev operate in place. We use playerIndex for a LOT of things in other packages, how much would need to change?
Other interesting things: AdminPlayerIndex and ObserverPlayerIndex would become pointers (that serialize to -1 and -2 in JSON)