-
Simple FSM advice
So, the FSM is kinda cool when you get the whole idea. I only started with the coin unlock to test out, and I would like you guys could give me more advice if i'm not on the right track.
so this is the states.h file:
Code:
class State
{
public:
State(){}
~State(){}
char sName[50];
int sType, sOrder;
//Dont mind the 'sType'. it's not doing anything
void setupState(int type, int order, char* name);
};
void State::setupState(int type, int order, char *name)
{
sType = type;
sOrder = order;
strcpy(sName, name);
}
and this is the FSM.h
Code:
#ifndef fsm_h
#define fsm_h
#include <vector>
#include <iostream>
#include "states.h"
class FSM
{
public:
int CurrentStateNumber;
FSM()
{ CurrentStateNumber = 0; }
~FSM(){}
std::vector<State>CurrentState;
void addState(State state)
{
CurrentState.push_back(state);
}
void getAction(char* actionName)
{
int nextStateNumber = 0;
if(CurrentStateNumber == 2)
{
nextStateNumber = 0;
}else
nextStateNumber = CurrentStateNumber+1;
if( strcmp(CurrentState[CurrentStateNumber].sName, actionName) == 0 ||
strcmp(CurrentState[nextStateNumber].sName, actionName) != 0)
{
std::cout<<"You've entered an invalid state";
std::cout<<"\nYou're on '"<<CurrentState[CurrentStateNumber].sName<<"' state"<<std::endl;
return;
}else
{
CurrentStateNumber = nextStateNumber;
std::cout<<"You're on the '"<<CurrentState[CurrentStateNumber].sName<<"' state"<<std::endl;
}
}
};
#endif
and finally, the main CPP
Code:
#include <iostream>
#include "states.h"
#include "FSM.h"
using namespace std;
FSM fsm;
State cState[3];
char command;
void Init()
{
//Dont worry about the Order number (0, 1, 2). I did not do anything with them.
cState[0].setupState(0, 0, "lock");
cState[1].setupState(0, 1, "coin");
cState[2].setupState(0, 2, "unlock");
for(int j=0; j< 3; j++)
{
fsm.addState(cState[j]);
}
}
int main(int argc, char* argv[])
{
Init();
do{
cout<<"\nEnter the command (l, c, u) or q to quit: ";
cin>>command;
switch(command)
{
case 'l':
fsm.getAction("lock");
break;
case 'c':
fsm.getAction("coin");
break;
case 'u':
fsm.getAction("unlock");
break;
case 'q':
break;
default:
break;
}
}while(command != 'q');
std::cout<<'\n';
return 0;
}
So what do u guys think? Do u think the process of the code is ok for FSM. I appreciate for any advice. thanks
-
It is cool isn't it? I like FSMs. It's the poor man's AI.
I suggest you start considering moving some of your function member definitions outside the class definition. Your void getAction(char*) function member is most likely be rejected by your compiler as an inline function.
Also, I suggest you capitalize your header guards. There is no particular reason to do so other than the fact it's considered a better practice. If you only have defines fully upper case and all your variables lower case, there is little chance of a name conflict.
I didn't take a good look at the code, sorry. Still too green at C++ to diagnose other people's code quickly enough and not get bored :)
But keep on reading about this AI implementation on other websites. There's a lot more to it. Have fun.
-
It is better practice only if it is used incorrectly. I generally write my header guards all capitalized because that's what I'm used to, but I could very well write them in lower caps because the format I use I know I will never use it for any other defines. Here's what I do:
#define filename_h_included
I have seen others exagerate (sp?) and define their header guards like this:
#define filename_h_year-month-day-hour-minutes-seconds // without '-' between each
#define engine_h_060622201840 // for example, which would be if I created it now
I find it a bit long, but it's pretty much safe for name collision.
-
Thanks mario, i have the class function definition outside but i just put together when posting the code in here, it shorten the whole thing. But sure, FSM is really cool and it is really easy to get lost in those states and transitions
-
just as an FYI, you might want to have a look at boost.statechart
it automates a lot of the state-transition code management, leaving you free to just design your FSM. It's quite high-level C++, but it's easy to use, and really cool.