feat: westworldwithwoman. add elsa

This commit is contained in:
jonas committed 2026-09-03 21:28:28 +02:00
1 parent 2764849943
commit 0e7482e04c
28 files changed
+1946

No files matched your search

@@ -0,0 +1,50 @@
package westworldwithwoman
import (
"math/rand"
"sync"
)
// wifesGlobalState is Elsa's global state - its Execute runs on
// every single tick of her state machine, in addition to whatever
// her current state is doing (see StateMachine.Update). That's what
// makes it the right place for "does nature call right now" logic:
// the book says that can happen "during any state and at any time,"
// which is exactly what a global state is for.
type wifesGlobalState struct{}
var (
wifesGlobalStateInstance *wifesGlobalState
wifesGlobalStateOnce sync.Once
)
// WifesGlobalState is the Go stand-in for
// "WifesGlobalState::Instance()".
func WifesGlobalState() *wifesGlobalState {
wifesGlobalStateOnce.Do(func() {
wifesGlobalStateInstance = &wifesGlobalState{}
})
return wifesGlobalStateInstance
}
var _ State[Elsa] = (*wifesGlobalState)(nil)
// Enter and Exit do nothing - a global state is set once, in
// NewElsa, and never changed, so these never actually get called.
// They only exist to satisfy the State[Elsa] interface.
func (s *wifesGlobalState) Enter(e *Elsa) {}
func (s *wifesGlobalState) Exit(e *Elsa) {}
// bathroomCallChance is a 1-in-N chance, per the chapter's "1 in 10
// chance to change to VisitBathroom state."
const bathroomCallChance = 10
// Execute rolls the dice every tick. If it comes up, and Elsa isn't
// already in the bathroom (checked with IsInState, so this can't
// interrupt a bathroom trip that's already happening), she breaks
// off into VisitBathroom.
func (s *wifesGlobalState) Execute(e *Elsa) {
if !e.FSM().IsInState(VisitBathroom()) && rand.Intn(bathroomCallChance) == 0 {
e.ChangeState(VisitBathroom())
}
}