Port the finite state machine from "Programming Game AI by Example" chapter 2: BaseGameEntity, a generic State[T]/StateMachine[T] pair (Go generics standing in for the book's C++ templates), and a Miner that cycles through digging, banking, sleeping, and drinking states. VisitBankAndDepositGold, GoHomeAndSleepTilRested, and QuenchThirst are original implementations based on the book's written behavior description, since their C++ source wasn't available. Includes a runnable demo in main.go.
44 lines
1.3 KiB
Go
44 lines
1.3 KiB
Go
package westworld
|
|
|
|
import "sync"
|
|
|
|
// minerGlobalState is the Go version of the (not yet pasted)
|
|
// singleton class MinerGlobalState from the book. Same pattern as
|
|
// enterMineAndDigForNugget: unexported type, one shared instance,
|
|
// reached only through the function below. This is the state whose
|
|
// Execute runs on every single tick, regardless of whatever else
|
|
// the miner is currently doing (see StateMachine.Update).
|
|
type minerGlobalState struct{}
|
|
|
|
var (
|
|
minerGlobalStateInstance *minerGlobalState
|
|
minerGlobalStateOnce sync.Once
|
|
)
|
|
|
|
// MinerGlobalState is the Go stand-in for
|
|
// "MinerGlobalState::Instance()".
|
|
func MinerGlobalState() *minerGlobalState {
|
|
minerGlobalStateOnce.Do(func() {
|
|
minerGlobalStateInstance = &minerGlobalState{}
|
|
})
|
|
return minerGlobalStateInstance
|
|
}
|
|
|
|
var _ State[Miner] = (*minerGlobalState)(nil)
|
|
|
|
// Enter, Execute and Exit are placeholders - the book hasn't shown
|
|
// us this state's real methods yet. This stub exists only so
|
|
// NewMiner can set it as the miner's global state and compile.
|
|
|
|
func (s *minerGlobalState) Enter(m *Miner) {
|
|
// TODO: fill in once the book shows this method's body.
|
|
}
|
|
|
|
func (s *minerGlobalState) Execute(m *Miner) {
|
|
// TODO: fill in once the book shows this method's body.
|
|
}
|
|
|
|
func (s *minerGlobalState) Exit(m *Miner) {
|
|
// TODO: fill in once the book shows this method's body.
|
|
}
|