Hej, Jeg skal lave et simpelt generisk state machine framework til at håndtere nogle små tilstandsmaskiner. Er der nogen som har et prej til hvordan dette kunne implementeres på en simpel og elegant måde ?
Mød TrackMan og Veo på Computerworld Cloud & AI Festival og hør, hvordan tech ændrer måden, vi træner og udvikler talent – fra skolebold til The Masters.
Der findes mange former for statemaskiner, og man kan lave dem på mange måder.
Man kan lave det som en 2D array af funktions pointere, hvor den ene dimension er state og den anden event. Hvis en event i en state altid giver samme state kan man lade dette fremgå af array'et.
Man kan også lade state være en funktions pointer der bliver kaldt med den næste event, funktionen kan så returnere den næste state/funktion.
Men til små statemaskiner foretrækker jeg at håndkode en switch(state)/switch(event) funktion. Det finder jeg mest overskueligt.
Så for at hjælpe dig videre må vi nok vide lidt mere om hvad dine statmaskiner skal.
nu ved jeg ikke lige hvor vanvittigt dit quest-system spil er, men til små-tilstandsmaskiner vil jeg nok også gå efter switch/case ala: #include <conio.h>
enum States { state1, state2, state3, state4, };
void UpdateState(States &state) { switch(state) { case state1: state = state2; break; case state2: state = state3; break; case state3: state = state4; break; case state4: state = state1; break; default: break; } }
int _tmain(int argc, _TCHAR* argv[]) { States s = state1; for(int i=0; i<10; i++) { UpdateState(s); } printf("state = %d\n", s); getch(); return 0; }
sovsekoder: Det skal være en del mere generisk fordi det er mere end blot en sekvens. Det skal osse primært arbejde med strenge fordi det skal kunne implementeres i nogle scripts.
hvad mener du præcis med generisk. Vil du opbygge din statemachine løbende under program-kørsel?
i ovenstående er det meningen at de enkelte states implementeres i case-delen: case state1: if(playerGoesNorth == true) state = state 4; return; else { if(playerChoosesNewWeapon) { state = ChooseWeapon(); } } state = state2
hvis din statemachine skal opbygges i et script af en art kuune man måske lave en statemachine-engine i denne stil: StateMachine sm; sm.CreateState("st_start"); sm.CreateState("st_newGame"); sm.CreateState("st_exit");
med en StateMachine klasse der indeholder tilstandsmaskinen. CreateState opretter en tilstand
CreateEvent opretter et event, der senere bruges til at afgøre om man skal gå fra een tilstand til en anden..
CreateTransition opretter en overgange fra een tilstand til en anden.
Transition er en klasse der repræsenterer en overgang.
Transition.AddTriggerEvent tilføjer en betingelse der skal opfyldes for at man går fra een state til en anden.
derudover skal der være noget til at sætte værdierne (true/false) på de forskellige events. (StateMachine.SetEvent / GetState) - og tilsidst noget der får StateMachine til at udføre et deskret skridt, dvs. opdatering af nuværende tilstand
..så i koden i forrige indlæg har jeg prøvet atlave en statemachine der : går fra state:st_start til state:st_newGame hvis eventen ev_start er sat går fra st_newGame til st_exit hvis enten ev_moveSouth eller ev_quitGame er sat
det kræver så at man har styr på sine events i det program der bruger frameworket.
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.