Code: Select all
;;;**** Miner.pb
;;;**** Yewklid December 2009
;;;**** Inspired by Mat Buckland
;-******* Locations *****
Enumeration
#Shack
#Goldmine
#Saloon
#Bank
EndEnumeration
;-*** Constants ****
#ScreenWidth = 500
#ScreenHeight = 768
Global LatestID.w = -1
;Global Nextline.w = 1
;-**** Structures *****
Structure State
*Exit.l
*Execute.l
*Enter.l
Location.b
EndStructure
Structure BaseGameEntity
ID.w
EndStructure
Structure GameEntity Extends BaseGameEntity
*CurrentState.State
*PreviousState.State
*GlobalState.State
Location.b
EndStructure
Structure Miner Extends GameEntity
Tiredness.b
GoldCarried.b
TotalWealth.b
Thirst.b
EndStructure
Structure Wife Extends GameEntity
EndStructure
;-**** Declarations ****
Declare EnterMineAndDig_Enter(*Miner.Miner)
Declare EnterMineAndDig_Execute(*Miner.Miner)
Declare EnterMineAndDig_Exit(*Miner.Miner)
Declare GoHomeAndSleep_Exit(*Miner.Miner)
Declare GoHomeAndSleep_Execute(*Miner.Miner)
Declare GoHomeAndSleep_Enter(*Miner.Miner)
Declare GoToBank_Exit(*Miner.Miner)
Declare GoToBank_Execute(*Miner.Miner)
Declare GoToBank_Enter(*Miner.Miner)
Declare QuenchThirst_Exit(*Miner.Miner)
Declare QuenchThirst_Execute(*Miner.Miner)
Declare QuenchThirst_Enter(*Miner.Miner)
Declare WorkatHome_Exit(*W.Wife)
Declare WorkatHome_Execute(*W.Wife)
Declare WorkatHome_Enter(*W.Wife)
Declare ChangeState(*M.GameEntity,*NewState.State)
Declare RevertToPreviousState(*M.GameEntity)
Declare.w GetLatestID()
Declare.s GetEntityName(*GE.GameEntity)
Declare InitMiner(*M.Miner,Loc.b,*InitState.State)
Declare Update_Miner(*M.Miner)
Declare Update_State(*GE.GameEntity)
Declare InitWife(*M.Wife,Loc.b,*InitState.State,*GlobalState.State)
Declare Update_Wife(*W.Wife)
Declare Write (Txt.s)
Declare VisitBathroom_Exit(*W.Wife)
Declare VisitBathroom_Execute(*W.Wife)
Declare VisitBathroom_Enter(*W.Wife)
Declare WifeGlobalState_Execute(*W.Wife)
Global EnterMineAndDig.State
EnterMineAndDig\Exit = @EnterMineAndDig_Exit()
EnterMineAndDig\Execute = @EnterMineAndDig_Execute()
EnterMineAndDig\Enter = @EnterMineAndDig_Enter()
EnterMineAndDig\Location = #Goldmine
Global GoHomeAndSleep.State
GoHomeAndSleep\Exit = @GoHomeAndSleep_Exit()
GoHomeAndSleep\Execute = @GoHomeAndSleep_Execute()
GoHomeAndSleep\Enter = @GoHomeAndSleep_Enter()
GoHomeAndSleep\Location = #Shack
Global GoToBank.State
GoToBank\Exit = @GoToBank_Exit()
GoToBank\Execute = @GoToBank_Execute()
GoToBank\Enter = @GoToBank_Enter()
GoToBank\Location = #Bank
Global QuenchThirst.State
QuenchThirst\Exit = @QuenchThirst_Exit()
QuenchThirst\Execute = @QuenchThirst_Execute()
QuenchThirst\Enter = @QuenchThirst_Enter()
QuenchThirst\Location = #Saloon
Global WorkatHome.State
WorkatHome\Exit = @WorkatHome_Exit()
WorkatHome\Execute = @WorkatHome_Execute()
WorkatHome\Enter = @WorkatHome_Enter()
WorkatHome\Location = #Shack
Global VisitBathroom.State
VisitBathroom\Exit = @VisitBathroom_Exit()
VisitBathroom\Execute = @VisitBathroom_Execute()
VisitBathroom\Enter = @VisitBathroom_Enter()
VisitBathroom\Location = #Shack
Global WifeGlobalState.State
WifeGlobalState\Execute = @WifeGlobalState_Execute()
;-****** Main bit ******
Bob.Miner
InitMiner(@Bob,#Goldmine,@EnterMineAndDig)
Elsa.Wife
InitWife(@Elsa,#Shack,@WorkAtHome,@WifeGlobalState)
For i = 1 To 25
Update_Miner(@Bob)
Update_Wife(@Elsa)
Next
;-***** Miner States ******
Procedure EnterMineAndDig_Enter(*Miner.Miner)
If *Miner\Location <> #Goldmine
Write (GetEntityName(*Miner) + "Entering the mine")
EndIf
EndProcedure
Procedure EnterMineAndDig_Execute(*Miner.Miner)
If *Miner\Location = #Goldmine
Write (GetEntityName(*Miner) + "Picking up a nugget")
*Miner\GoldCarried = *Miner\GoldCarried + 1
*Miner\Tiredness = *Miner\Tiredness + 1
If *Miner\GoldCarried >= 3
Changestate(*Miner,@GoToBank)
ElseIf *Miner\Tiredness >= 5
Changestate(*Miner,@GoHomeAndSleep)
ElseIf *Miner\Thirst >= 5
Changestate(*Miner,@QuenchThirst)
EndIf
EndIf
EndProcedure
Procedure EnterMineAndDig_Exit(*Miner.Miner)
If *Miner\Location = #Goldmine
Write (GetEntityName(*Miner) + "Leaving the mine")
EndIf
EndProcedure
Procedure GoHomeAndSleep_Exit(*Miner.Miner)
If *Miner\Location = #Shack
Write (GetEntityName(*Miner) + "Leaving the Shack")
EndIf
EndProcedure
Procedure GoHomeAndSleep_Execute(*Miner.Miner)
If *Miner\Location = #Shack
If *Miner\Tiredness <= 0
Write (GetEntityName(*Miner) + "Gosh, what a good sleep")
Changestate(*Miner,@EnterMineAndDig)
Else
Write (GetEntityName(*Miner) + "zzzzz")
*Miner\Tiredness = *Miner\Tiredness - 1
EndIf
EndIf
EndProcedure
Procedure GoHomeAndSleep_Enter(*Miner.Miner)
If *Miner\Location <> #Shack
Write (GetEntityName(*Miner) + "I'm mighty tired. Walking Home")
EndIf
EndProcedure
Procedure GoToBank_Exit(*Miner.Miner)
If *Miner\Location = #Bank
Write (GetEntityName(*Miner) + "Leaving the Bank")
EndIf
EndProcedure
Procedure GoToBank_Execute(*Miner.Miner)
If *Miner\Location = #Bank
*Miner\TotalWealth = *Miner\TotalWealth + *Miner\GoldCarried
Write (GetEntityName(*Miner) + "Banking My Gold Total Wealth: " + Str(*Miner\TotalWealth))
*Miner\GoldCarried = 0
Changestate(*Miner,@EnterMineAndDig)
EndIf
EndProcedure
Procedure GoToBank_Enter(*Miner.Miner)
If *Miner\Location <> #Bank
Write (GetEntityName(*Miner) + "Entering the bank")
EndIf
EndProcedure
Procedure QuenchThirst_Exit(*Miner.Miner)
If *Miner\Location = #Saloon
Write (GetEntityName(*Miner) + "Leaving Saloon. That was mighty fine likker")
EndIf
EndProcedure
Procedure QuenchThirst_Execute(*Miner.Miner)
If *Miner\Location = #Saloon
Write ( GetEntityName(*Miner) + "Sipping my likker")
*Miner\Thirst = 0
Changestate(*Miner,@EnterMineAndDig)
EndIf
EndProcedure
Procedure QuenchThirst_Enter(*Miner.Miner)
If *Miner\Location <> #Saloon
Write ( GetEntityName(*Miner) + "I'm durn thirsty. Walking to the saloon")
EndIf
EndProcedure
;- ****** Wife States
Procedure WorkatHome_Exit(*W.Wife)
EndProcedure
Procedure WorkatHome_Execute(*W.Wife)
If *W\Location = #Shack
Select Random(2)
Case 0
Write ( GetEntityName(*W) + "Mopping the floor")
Case 1
Write ( GetEntityName(*W) + "Cleaning the kitchen")
Case 2
Write ( GetEntityName(*W) + "Making the bed")
EndSelect
EndIf
EndProcedure
Procedure WorkatHome_Enter(*W.Wife)
EndProcedure
Procedure WifeGlobalState_Execute(*W.Wife)
If Random(10) < 2
ChangeState (*W, @VisitBathroom)
EndIf
EndProcedure
Procedure VisitBathroom_Exit(*W.Wife)
Write ( GetEntityName(*W) + "Leaving the john")
EndProcedure
Procedure VisitBathroom_Execute(*W.Wife)
Write ( GetEntityName(*W) + "Aaaah Sweet relief")
ReverttoPreviousState(*W.Wife)
EndProcedure
Procedure VisitBathroom_Enter(*W.Wife)
Write ( GetEntityName(*W) + "Walking to the can")
EndProcedure
;- **** General Procedures
Procedure ChangeState(*M.GameEntity,*NewState.State)
;Procedure ChangeState(*M.miner,*NewState.State)
*M\PreviousState = *M\CurrentState
CallFunctionFast(*M\CurrentState\Exit,*M)
*M\CurrentState = *NewState
CallFunctionFast(*M\CurrentState\Enter,*M)
*M\Location = *NewState\Location
EndProcedure
Procedure RevertToPreviousState(*M.GameEntity)
ChangeState(*M,*M\PreviousState)
EndProcedure
Procedure.w GetLatestID()
LatestID = LatestID + 1
ProcedureReturn LatestID
EndProcedure
Procedure.s GetEntityName(*GE.GameEntity)
Select *GE\ID
Case 0
ProcedureReturn "Bob: "
Case 1
ProcedureReturn " Elsa: "
EndSelect
EndProcedure
Procedure InitMiner(*M.Miner,Loc.b,*InitState.State)
*M\ID = GetLatestID()
*M\Tiredness = 0
*M\GoldCarried = 0
*M\Location = Loc
*M\TotalWealth = 0
*M\CurrentState = *InitState
*M\Thirst = 0
EndProcedure
Procedure InitWife(*M.Wife,Loc.b,*InitState.State,*GlobalState.State)
*M\ID = GetLatestID()
*M\CurrentState = *InitState
*M\GlobalState = *GlobalState
EndProcedure
Procedure Update_Miner(*M.Miner)
*M\Thirst = *M\Thirst + 1
Update_State(*M)
EndProcedure
Procedure Update_Wife(*W.Wife)
Update_State(*W)
EndProcedure
Procedure Update_State(*GE.GameEntity)
If *GE\GlobalState <> #Null
CallFunctionFast(*GE\GlobalState\Execute,*GE)
EndIf
CallFunctionFast(*GE\CurrentState\Execute,*GE)
EndProcedure
Procedure Write (Txt.s)
Debug Txt
EndProcedure
