{-# OPTIONS_HADDOCK hide #-}

{-|
Module      : Graphics.Mars.Walk
Description : Produces random walk data.
Copyright   : (c) Christopher Howard, 2016
License     : GPL-3
Maintainer  : ch.howard@zoho.com

Use the 'walk' function to generate an infinite list of random walk points.
Based on this simple algorithm:

@
step :: RandomGen g => RandomWalk g
step = do (x, y) <- get
          a <- getRandomR (0, 1)
          b <- getRandomR (0, 1)
          c <- ask
          let d = c / 2.0
          put (x + a * c - d, y + b * c - d)
          get
@
-}
module Graphics.Mars.Walk (walk) where

import Prelude(repeat, Float, (/), (+), (*), (-))
import Graphics.Mars.ReaderStateRandom
  (ask, put, get, RandomGen, getRandomR, evalRSR, sequence, ReaderStateRandom)

type RandomWalk g = ReaderStateRandom Float (Float, Float) g (Float, Float)

step :: RandomGen g => RandomWalk g
step = do (x, y) <- get
          a <- getRandomR (0, 1)
          b <- getRandomR (0, 1)
          c <- ask
          let d = c / 2.0
          put (x + a * c - d, y + b * c - d)
          get

-- |Produces an infinite lazy list of random walk points.
walk :: RandomGen g =>
        Float             -- ^ the jitter factor
        -> (Float, Float) -- ^ first (starting) point
        -> g              -- ^ a random number generator
        -> [(Float, Float)]
walk = evalRSR (sequence (repeat step))