Avatar billede krismort Nybegynder
25. juli 2005 - 16:22 Der er 11 kommentarer

tips til generisk statemachine framework.

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 ?

- Kristian.
Avatar billede bertelbrander Novice
25. juli 2005 - 22:51 #1
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.
Avatar billede krismort Nybegynder
26. juli 2005 - 00:26 #2
de skal bruges til at holde styr på spillogikken i et quest system til et spil
Avatar billede sovsekoder Nybegynder
29. juli 2005 - 15:25 #3
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;
}
Avatar billede krismort Nybegynder
30. juli 2005 - 13:58 #4
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.
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:13 #5
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

  break;
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:15 #6
...dvs du ved hvordan din statemachine ser ud når du starter dit spil, og implementerer de enkelte states som de nu skal være...
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:22 #7
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");

sm.CreateEvent("ev_start");
sm.CreateEvent("ev_moveNorth");
sm.CreateEvent("ev_moveSouth");
sm.CreateEvent("ev_quitGame");

//
Transition trans;
trans = sm.CreateTransition("st_start", "st_newGame");
trans.AddTriggerEvent("ev_start", true);

trans = sm.CreateTransition("st_newGame", "st_exit");
trans.AddTriggerEvent("ev_moveSouth", true);
trans.AddTriggerEvent("ev_quitGame", true);

...
sm.SetEvent("ev_start", true);
sm.GetState();
sm.DescreteStep();
....
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:26 #8
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
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:29 #9
..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.
Avatar billede sovsekoder Nybegynder
31. juli 2005 - 12:29 #10
er det noget i den stil, du skal bruge?
Avatar billede krismort Nybegynder
11. august 2005 - 08:22 #11
ja det er noget i den stil...
Avatar billede Ny bruger Nybegynder

Din løsning...

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester