On Fri, May 27, 2011 at 2:06 PM, Yves Parès <limestr...@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@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe > > _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe