feat: add Chapter 2 gold miner FSM example in Go
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.
This commit is contained in:
1 parent
f09fa6d548
commit
2764849943
11 files changed
+787
No files matched your search
@@ -0,0 +1,53 @@
|
||||
package westworld
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// quenchThirst is the Go version of the (not yet pasted) singleton
|
||||
// class QuenchThirst from the book. Same pattern as
|
||||
// enterMineAndDigForNugget: unexported type, one shared instance,
|
||||
// reached only through the function below.
|
||||
type quenchThirst struct{}
|
||||
|
||||
var (
|
||||
quenchThirstInstance *quenchThirst
|
||||
quenchThirstOnce sync.Once
|
||||
)
|
||||
|
||||
// QuenchThirst is the Go stand-in for "QuenchThirst::Instance()".
|
||||
func QuenchThirst() *quenchThirst {
|
||||
quenchThirstOnce.Do(func() {
|
||||
quenchThirstInstance = &quenchThirst{}
|
||||
})
|
||||
return quenchThirstInstance
|
||||
}
|
||||
|
||||
var _ State[Miner] = (*quenchThirst)(nil)
|
||||
|
||||
// The book hasn't shown us this state's real code, so this is our
|
||||
// own implementation based purely on its written description: "he
|
||||
// visits the saloon in order to buy a whiskey. When his thirst is
|
||||
// quenched, he changes state to EnterMineAndDigForNugget."
|
||||
|
||||
// Enter sends the miner to the saloon, if he isn't there already.
|
||||
func (s *quenchThirst) Enter(m *Miner) {
|
||||
if m.Location() != saloon {
|
||||
fmt.Printf("\n%s: Headin' to the saloon for a whiskey", GetNameOfEntity(m.ID()))
|
||||
m.ChangeLocation(saloon)
|
||||
}
|
||||
}
|
||||
|
||||
// Execute buys and drinks one whiskey, which is all it takes to
|
||||
// quench the thirst, then goes straight back to digging.
|
||||
func (s *quenchThirst) Execute(m *Miner) {
|
||||
fmt.Printf("\n%s: That's mighty fine sippin' liquor", GetNameOfEntity(m.ID()))
|
||||
m.BuyAndDrinkAWhiskey()
|
||||
m.ChangeState(EnterMineAndDigForNugget())
|
||||
}
|
||||
|
||||
// Exit announces that the miner is leaving the saloon.
|
||||
func (s *quenchThirst) Exit(m *Miner) {
|
||||
fmt.Printf("\n%s: Leavin' the saloon, feelin' good", GetNameOfEntity(m.ID()))
|
||||
}
|
||||
Reference in new issue
Block a user