[Qt-interest] question about QStateMachine setTargetStates() - how deterministic is it?

Sean Harmer sean.harmer at maps-technology.com
Mon Apr 12 18:40:35 CEST 2010


Hi,

On Monday 12 April 2010 17:02:16 Alan Ezust wrote:
> I'm trying to understand how QStateMachine works, and whether I can
> use a spontaneous transition to multiple possible states as a
> "randomizer" for a rock-scissors-paper game.

OK. Yes this is possible to do but not with a spontaneous transition.

> I notice that there is some randomness to choosing t's next state when
> t is fired the first time,
> but on repeated firings, t keeps bringing me to the same state it
> picked the first time.
> 
> Is that a bug?

No it is not a bug. I think (without checking the QStatemachine code) that is 
is simply due to the transitions and states being stored in a QSet. So it is 
random as to which transition gets looked at first when your event occurs each 
time you run your application. However, within a single instance of your 
application it is using the same QSet and so it always gets out the same 
transition on subsequent lookups.

Without spending too much time thinking about this, the way I would initially 
try to implement this would be to create a custom event class that holds a 
single float value between 0 and 1. When you wish to trigger the transition 
you need to sample a value from the uniform distribution to obtain the value 
to put into your custom event class. Then post your custom event to the state 
machine.

That is half the story. The other half that is needed is to create a custom 
transition class that checks that the event is of the correct type and also 
checks that the probability value stored in the event is acceptable for that 
particular transition.

For example, if you have 3 possible transitions with probabilities of 0.25, 
0.5 and 0.25 respectively, then your guarded transition class should check 
that the sampled value stored in the event is between:

0 and 0.25 for transition 1;
0.25 and 0.75 for transition 2;
0.75 and 1 for transition 3;

Obviously you would just have one guarded transition class that stores a range 
of acceptable values. If the value in the event is within the range for a 
particular transition then it returns true from its eventTest() function; 
otherwise it should return false.

In the above example I have just assumed the uniform probability density 
function (pdf) so it doesn't matter in which order I specified the ranges, but 
you could imagine using a more complicated pdf and setting the limits on the 
acceptable ranges of the transitions by inverting the cumulative distribution 
function (cdf).

So in summary what you need is:

* Custom event that stores a float between 0 and 1
* Ability to sample from uniform distribution (e.g. qrand())
* Custom transition class that can check value stored in custom event is 
within its range or not within its eventTest() function
* Create a bunch of your custom transition class objects and set appropriate 
cdf ranges on them.

Hope this helps,

Sean



More information about the Qt-interest-old mailing list