[Haskell-cafe] State Machine and the Abstractions

Antoine Latter aslatter at gmail.com
Fri May 27 21:29:57 CEST 2011


On Fri, May 27, 2011 at 2:06 PM, Yves Parès <limestrael at gmail.com> wrote:
> Hello,
>
> For the purposes of a simple strategy game, I'd like to build an EDSL that
> expresses missions. A mission could be represented as a state machine.
> With basic bricks such as actions (MoveTo, ShootAt...) or tests
> (EnemiesAround, LowHealth...), I could (ideally dynamically) build some
> strategic behaviors for the units.
> I will take the example of a patrol. Applied to a unit (or a group of
> units), it dictates : go from point 1 to point 2 and then go back and
> repeat. But when you detect an enemy near, leave the patrol path, destroy it
> and then resume your patrol where you left it.
>
> So if I consider my mission as a monad:
> data Mission = MoveTo Point | ShootAt Unit
>
> patrol = do
>     MoveTo point1
>     MoveTo point2
>     patrol
>
> So far so good, but there, the only advantage to use a monad instead of a
> list of MoveTo's is the do-notation.
> And I lack the expression of tests. Using a GADT it could be:
>
> data Mission a where
>     MoveTo :: Point -> Mission ()
>     ShootAt :: Unit -> Mission Bool  -- If we have destroyed it or not
>     EnemiesAround :: Mission [Unit]  -- The enemies that are maybe in sight
>     LowHealth :: Mission Bool -- If I should retreat
>     ...
>
> -- (Monad Mission could be nicely expressed using Heinrich Apfelmus'
> operational package)
>
> patrol = do
>     MoveTo point1
>     MoveTo point2
>     enemies <- EnemiesAround
>     mapM_ ShootAt enemies
>     patrol
>
> Aaaaaaaand... here comes the trouble: the actions are done sequentially. My
> units will move and then look at enemies, they will not monitor their
> environment while they move.
> So I need a way to say: A is your action of patrolling. B is your action of
> surveillance. Do both in parallel, but B is preponderant, as if it successes
> (if enemies are there) it takes over A. So, it is as if I was running two
> state machines in parallel.
> Moreover, the last line (the recursive call to patrol) is wrong, as it will
> restart the patrol from the beginning, and not from where it has been left.
> But this could be corrected by addind a test like "which point is the
> closest".
>

Could this be expressed using a new verb in your language?

> data Mission a where
>     MoveTo :: Point -> Mission ()
>     ShootAt :: Unit -> Mission Bool  -- If we have destroyed it or not
>     EnemiesAround :: Mission [Unit]  -- The enemies that are maybe in sight
>     LowHealth :: Mission Bool -- If I should retreat
>     . . .
>     Tasks :: [Mission ()] -> Mission () -- goals to be achieved concurrently
>     Options :: [Mission ()] -> Mission () -- pick one of these

You'd then need to analysis and interpretation tools to correctly do
the right thing with it. If the game is state-machine driven, you
would need sub state-machines for each possibility under 'Tasks' or
'Options'.

Antoine

> So I thought about Arrows, as they can express sequential and parallel
> actions, but I don't know if it would be a right way to model the
> interruptions/recoveries.
> What do you think about it? Do you know of similar situations and of the way
> they've been solved?
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>
>



More information about the Haskell-Cafe mailing list