Fuzzy VS Finite

Hi all,

I was reading some articles mainly in Game Programming Gems 1 and 2. And ive found a comparable difference between the two types of give AI, Finite State Machine (FSM), and Fuzzy State Machine (FuSM):



Finite Logic

Either ON or OFF. So the player is either MAD, HAPPY, CRYING…etc. Rapid changes in the state of the player. Hence Finite State Machines.



Fuzzy Logic

Each state has 2 variables, ON or OFF. However, the difference between finite and fuzzy is that fuzzy can be semi-on and semi-off at the same time. We can represent this in a scale ranging from 0 to 1. 0 being OFF, 1 being ON. In a game situation the AI enemy can have a range of MAD. So he can be not angry, angry, v. angry. In a Finite State Machine, those three would have to be different variables which are mutually exclusive.



Now for the question. Which do you prefer? Or do you want both implementations?



DP

makes alot of sense to me. However, I was thinking instead of determining "speed", we determine the output state.



So we have 4 classes:

    FSMClass (Finite/Fuzzy State Machine)
    FSClass (Finite/Fuzzy State)
    Behaviour (This has many FSClass to represent the type of states a NPC can show)
    Outputstate (Includues the FSClass as an output and a float to represt the amount of saturation of that state)
    [/list:u]

Start with FSM simply because it is something that can be accomplished quickly. Don’t bite off so much you choke yourself.

Ok. FuzzySM is almost finished, with one minor/major bug (can’t figure out what!)



0.5 - 0.2 == 0.3
1 - 0.3/0.5 == 0.4


Then you input 0.6:

0.5 - (0.2 + 0.6) = -0.3;
1 - -0.3/0.6 = 1.6

Say you input 0.6 again. The state should remain at 1.6 correct?

0.5 - (1.6 + 0.6) = -1.7
1 - - 1.7/0.5 = 5.4

Is it supposed to stay at 1.6 or go up to 4.4?

DP

In the example I wrote up a while ago, the idea was that the ‘anger level’ was in a range of 0 to 1… Ie: You can’t go below 0 or above 1, even if the math would cause you to do that.



So… in short, you should never get above ‘2’ as the result.



This was really just an example, though… I don’t know that I put enough thought into the math there to turn it into a whole system without any further refinement! :slight_smile:



But… if you want to stick with what I had…



Your “1.6 + 0.6” isn’t right… You should be adding to the ‘anger level’, not the output of the FSM. So… because the anger level was previously ‘0.8’, you would add 0.6 to that:





Starting at 0.2, adding 0.6:



0.5 - (0.2 + 0.6 == 0.8) = -0.3

1 - (-0.3/0.5 == -0.6) = 1.6





Adding 0.6 again:



0.5 - (0.8 + 0.6 == 1.4 == 1.0) == -0.5

1 - (-0.5/0.5 == -1) == 2





Adding 0.6 again:



0.5 - (1.0 + 0.6 == 1.6 == 1.0) == -.05

1 - (-0.5/0.5 == -1) == 2







Make sense?



Again, I’m really not sure this is what you want to use for a full system… I think I was really just explaining how fuzzy logic works.



We can talk about this more and flesh out something more concrete if you want, though. (I’ve gotta go right now, so can’t post any ideas ATM… Sorry 'bout that.)





–K

yeah Id like that. I can’t find anything decent on the net. It explains what they are, but no equations or code for this matter.



So if you can remeber some of the finer details of the FuSM that you learnt way back, id appreciate it :slight_smile:



DP

Ive been reading a Gem titled "A Generic Fuzzy State Machine in C++" in Game Programming Gems 2. And this is a quote:



Status in a FuSM is typically represented internally using a range of real numbers from 0.0 to 1.0.


But then it goes on to say that that range is not the only way to represent fuzzy logic, but any range can be used.

Also, I just had an idea. Tell me what you think of it.

Basically, each state can have multiple "feelings" inside. E.g. Happy, Depressed, and Sad. As you can see, they are related.

What happens is that you add those states in a list. Now no matter what the size of the list is, it will always have a lenght of "1". So in our example, 0.5 is depressed, but 0.35 is more depressed than happy.

You can think of this like the Electromagnetic spectrum. The neighbours blend into each other.

Those three "feelings" can be combined into an overall state called "euphoria" or something like that. Similar can be done with Annoyed, Threatened, Angry, Mad, Raging.

This is good because the user wont need to do if (someValue > 0.35) then the monster is mad...

It can be used if (euphoriaState.getState().equals("Happy") { monster.setSpeedMotion(euphoria.getState().getValue();
}

or something similar, what do you think?

DP

My idea extends Fuzzy State Machines, but implements a clear division line between various fuzzy states so that behavioural switching can be accomplished easily.



Let me try and explain:



<


0 - 20 Sad
>
         <
15 - 55 depressed
>
                                     <--- 50 - 100 happy ---->



Right, thats 1 state. What happens is that the user (in an XML file probably sets those ranges and their names.

Now what this special machine does is it sorts the inner states (like above) into ascending order (using bubble/shuttle or some other type of sorting). And resizes the inner state values so that they correspond from 0 - 2.

Now what happens is when you obtain an output, you get 3 values back.

The first value is *exactly* like a Fuzzy State Machine's output, the Second is which state that value corresponds to. And the third is how deep are you in that state (Ofcourse you can have multiple inner states to be returned).

Now I can forsee a very good use as it can switch states (e.g from roaming to angry) automatically whilst still keeping this fuzzy values (ie not crisp).

Ok, situation where this can prove useful (from my favourite game, metal gear solid :D):

You are snake (a stealth infiltrator) and only 1 enemy sees you, automatically, he will switch to attack behaviour. But he is extremely aggressive and shoots as many rounds at you as possible. Now if three or four see you at a time, they will all switch behaviours, but they wont be as aggressive, because you will have 4x the amounts of bullets in you and thats just a waste. So they dont shoot as much, but enough to kill you just as fast as 1 person shooting very very fast. Ofcourse to preserve ammo.

Without my combination of fuzzy/finite situation, you would need to imploy a FiniteSM for behavioural switching and regulate their behaviour using a FuSM so they aren't so aggressive. Both having the same states, but one being fuzzy, the other finite. With mine, you can keep everything together.

I personally think that this is a good idea, but what do you think?

DP

I don’t want to discourage you from trying to come up with new and different ways of doing things. That’s how lots of cool stuff gets created. :smiley:



But… I’m not sure how well your idea is going to work. (Maybe it will… I just think it’s not quite as straightforward as you think it is. :slight_smile: )



In your example… what happens when the state is ‘18’? Both ‘sad’ and ‘depressed’? Which action do you pick? (Incidentally… I know it was just an example, but I’d probably put depressed at the bottom of the range and sad in the middle. :slight_smile: )



Also… I’m not sure this would work with your example from Metal Gear Solid… At that point, you’re talking about the current state of AIs affecting other AIs… That’s kind of a different problem.



Maybe what we should do before we go any further is define what the goals of the system are… Starting at a pretty high level, then working down into the details to figure out how to accomplish it?



Trying to summarize the high level goal:



Provide a way for an AI to decide what to do based on its current situation, mood, likes, and dislikes, and to provide ways to change those things.





Is that about right? If so… some brainstorming on a slightly lower level:

    * Decide what reaction is appropriate for that AI in that situation
    * Allow for different 'strengths' of reactions, not just on or off, but do not require this.
    * Allow AI moods to affect other AI moods (eg, a 'mob' mentality), but do not require this.
    * Provide ways to use the system but not alter the next use of the system. (Eg, a quick reaction and then revert to normal)
    * Possibly provide 'scalable' inputs to define how 'entrenched' the AI is in its mood. (Eg, a depressed AI won't just become significantly less depressed because it finds a $20 bill, but if it's already happy, it might be significantly more happy.)
    * Must be easy to setup and use
    [/list:u]

    What other goals are there? Are these okay?

    What I'm really getting at is this is about more than finite state machines and fuzzy logic machines. Those are great tools, and we should probably provide them.. But we might want to provide standard versions of them, and then USE those tools to create the more complex AI behavior.

    Otherwise, I think we'll end up with a very rigid system that can only handle a small range of problems because everything is so specific and entrenched. People will have to roll their own fuzzy logic implementation because ours can only be used in this one specific way.

    Basically, fuzzy logic is just one small part of what we're trying to accomplish, but I think designing it is getting in the way of accomplishing the larger goal.

    What do you think, DP?


    --K


    PS: If anybody else is out there and has some input, feel free to chime in. This isn't a private discussion. :)

your goals are just about right. But the "mob" thing is not included on my current goals.



Yes, ofcourse im going to create a FiniteSM and a FuzzySM for people who just want them. But im also providing a CombinedSM too.



For your example, about sad and depressed are both at 18, can you please clarify their ranges? What happens is that each inner state has a range at which it operates at. And yes, you can have overlap, it just means that the output will return an Array instead of a single object. So depending on the distance away from that inner state’s mean is, you set the characters speed/accuracy.



In your example.. what happens when the state is '18'? Both 'sad' and 'depressed'? Which action do you pick?


Say instead of sad and depressed you have accuracy and speed. The accuracy increases slowly and before reaching its maximum, speed will also kick in with it's own distance from the mean. That means before reaching maximum accuracy, the NPC can feel confident at shooting at the same accuracy but faster. Hence comes learning.

DP

PS, yeah, i would like people's input on this, because this is an API, so I want it to be used by as a larger audience as possible. :)

Heh… okay, more questions for you. :slight_smile:


For your example, about sad and depressed are both at 18, can you please clarify their ranges?


I was going off of your example, where sad went from 0-20, and depressed went from 15 - 55. There is overlap from 15-20, so my question was.. what state is the bot in when it's in that overlap?


What happens is that each inner state has a range at which it operates at. And yes, you can have overlap, it just means that the output will return an Array instead of a single object.


By output.. you mean the output states? So instead of being a single finite state, the bot is in two states? What's the point of the states, then? I thought the states were to decide on what course of action to take (the difference between, say, shouting at somebody and attacking somebody).


So depending on the distance away from that inner state's mean is, you set the characters speed/accuracy.


Which 'inner' state are you referring to? I'm not sure I follow that. Do you mean for each state (sad and depressed)? How would that work? I don't think you really need the states to do this.. just the number.. So I'll hazzard a guess that you mean from the middle of all states? Like '50' in your example of 0-100?


Say instead of sad and depressed you have accuracy and speed. The accuracy increases slowly and before reaching its maximum, speed will also kick in with it's own distance from the mean.


I don't understand (I think we may be misunderstanding each other, actually. :) ).. The 'sad' and 'depressed' were from your state example.. These are the things that define the bot's current 'state of mind' or 'mood'. Speed and accuracy are affected by these, but probably can't replace them..?

The point of using general moods instead of specific behaviors in the machine is that they can affect a wide variety of things.. including speed and accuracy. Ie, if a bot is going very fast (high speed), is he going to charge at a person to attack them, or is he charging at a person to hug them?

I'm coming from the perspective that the AI system isn't all about combat.. it's about defining a bot's personality in whatever situation a game might need. In lots of games, there will be conflicts.. but in others, it might be a purely social thing. Sure, this is all configurable, but if the mentality of the system is to define specific skills rather than things that affect the bots skills, I think you're going to run into problems in the future.


your goals are just about right. But the "mob" thing is not included on my current goals.


I added the 'mob mentality' thing because of what you were talking about with Metal Gear Solid.. It looked like the state of an AI was affecting the states of other AIs. A 'mob mentality' is just an example of that.. where multiple bots are intensifying the others' moods. There could be other ways of AIs altering AIs.. The point is just that it is one of the goals. If it's not, that's no problem with me.. I was just trying to cover what I thought you wanted. :)


--K

right, FuzzySM is simple a CombinedSM with only 1 super state:


<combinedMachine initialState="monster">
<state name="monster">




</state>
</combinedMachine>

[code]

Thats the XML for loading that kind of an FuSM. Turning this into a CombinedSM simply means adding more "state" tags and inner states.

Is that OK? or would you rather have a seperate FuzzySM class instead?

DP[code]

<combinedMachine initialState="monster">

<state name="monster">









</state>

</combinedMachine>

Thats the XML for loading that kind of an FuSM. Turning this into a CombinedSM simply means adding more "state" tags and inner states.

Is that OK? or would you rather have a seperate FuzzySM class instead?

DP[code]



Thats the XML for loading that kind of an FuSM. Turning this into a CombinedSM simply means adding more "state" tags and inner states.



Is that OK? or would you rather have a seperate FuzzySM class instead?



DP

It’s probably okay like that from a functional standpoint as long as there’s not any (or at least very much) additional overhead under the covers for treating it like a combined-state machine.



I don’t know how clear it is that you can do that, though.



Hmm… How about this for an idea. Create an independent fuzzy-state-machine XML file, then allow your combined-state machine to import XML files for the individual states? I know that’s extra work, but that could help keep the combined-state-machine really easy to read, and also gives a clear fuzzy-machine format. Any thoughts on that?



Now that you’re on to the XML format… Do you already have something working with this? (Ie, an example?)



Should we talk about the XML format for the system and what features it needs? Or even the API?



If you’d just like to hammer on it for a while, no problem on my end. Just if you want to talk about it.





–K