you don't need a network of nodes unless you want the AI to be configured at runtime. The more straightforward way of coding a FSM AI into a game is as follows:
enum State
{
WARY,
OFFSENSE,
DEFENSE,
MID_COMBO,
ETC,
}
State currentState;
void aiStep()
{
// Randomly switch states to keep the player on their toes
if(rand() < 0.01)
currentState = rand() < AGGRESSIVENESS_CONSTANT ? OFFENSIVE : DEFENSIVE;
// No matter what state, follow up combos if appropriate
if(isMidCombo())
currentState = MID_COMBO;
switch(currentState)
{
case WARY:
if(opponentIsNear(THRESHOLD_CONSTANT) && !oppenentIsBlocking())
{
currentState = DEFENSIVE;
// Retry in new state
aiStep();
return;
}
case DEFENSIVE:
block();
return;
case OFFENSIVE:
//etc
}
}
No nodes or anything needed. Less flexible, but for a one man shop I think perfectly acceptable.
I've put a lot of non-FSM logic in as well to illustrate how it typically integrates - your textbook won't explain that part probably, but FSMs alone tend to give rather boring AIs. You can customize different characters by adding extra snippets of logic that only apply to them, and the various constants.