I have a program which simulates the interaction of many agents in a community. I'm animating the interaction using the Gloss library , the pictures of the agents render correctly, just not the animation. I animate it by generating a simulation, which is a list of list of interactions, which I then take the one corresponding to the second of the animation, where I then render that interaction. The code for simulating works fine when outputting it to terminal. The code:
render :: Int -> History -> Picture -- assume window to be square
render size (History int agents) = Pictures $ map (drawAgent (step`div`2) colors step) agents
where step = size*6 `div` (length agents)
--agents = nub $ concat $ map (\(Interaction a1 a2 _ ) -> [a1,a2]) int
nubNames = nub $ map (getName . name) agents --ignore the first two letters of name
colors = Map.fromList $ zipWith (\name color-> (name, color)) nubNames (cycle colorlist)
colorlist = [red,green,blue,yellow,cyan,magenta,rose,violet,azure,aquamarine,chartreuse,orange]
drawAgent :: Int -> Map.Map String Color -> Int -> Agent -> Picture
drawAgent size colors step agent =
color aColor (Polygon [(posA,posB),(posA,negB),(negA,negB),(negA,posB)])
where aColor = fromMaybe black $ Map.lookup (getName $ name agent ) colors
a = (fst $ position agent) * step
b = (snd $ position agent) * step
posA = fromIntegral $ a+size
negA = fromIntegral $ a-size
posB = fromIntegral $ b+size
negB = fromIntegral $ b-size
simulate :: Int -> [Agent] -> [History]
simulate len agents = trace ("simulation"
(playRound agents len) :
simulate len (reproduce (playRound agents len))
main = do
a <- getStdGen
G.animate (G.InWindow "My Window" (400, 400) (0,0)) G.white
(\time ->(render 400) $ ((simulate 5 (agent a))!!(floor time)))
where agent a = generate a 9
sim a = simulate 40 (agent a)
When I execute this, it will say the simulation is running, but only render the first interaction.
$ ghc -O2 -threaded main.hs && ./main
[6 of 8] Compiling Prisoners ( Prisoners.hs, Prisoners.o )
Linking main ...
simulation
simulation
simulation
It will continue like this until I stop it, rendering the same picture each time. What am I doing wrong?
(SO Comment box won't let me paste code)
Your doesn't compile for me. What version of Gloss are you using, the API has changed from v1.0 to v1.7.x. What version of GHC? What OS?
Does this simple example work for you?
{- left click to create a circle; escape to quit -}
import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
initial _ = [(0.0,0.0) :: Point]
event (EventMotion (x,y)) world = world --(x,y)
event (EventKey (MouseButton LeftButton) Up mods (x,y)) world = (x,y):world
event _ world = world
step time world = world
draw pts = Pictures $ map f pts
where f (x,y) = translate x y (circle 10)
m = play (InWindow "Hi" (600,600) (200,200)) white 1 (initial 0) draw event step
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.