packages feed

scroll-1.20150313: Level/Random.hs

module Level.Random where

import System.Random

import Types
import Rand

data Chunk
	= Chunk String
	| ParaBreak

type Stream = [Chunk]

targetwidth :: Int
targetwidth = 70

formatLevel :: ([String] -> [String]) -> Int -> Stream -> Level
formatLevel f = go 0 [] [] 
  where
	go :: Int -> [String] -> [String] -> Int -> Stream -> [String]
	go _ currline ls _ [] = f (unwords currline:ls)
	go _ currline ls 0 _ = f (unwords currline:ls)
	go _ currline ls n (ParaBreak:ws) = go 0 [] (unwords currline:ls) (n-1) ws
	go currwidth currline ls n (c@(Chunk w):ws)
		| newwidth > targetwidth = go 0 [] (unwords currline:ls) (n-1) (c:ws)
		| otherwise = go newwidth (w:currline) ls n ws
		where
			newwidth = currwidth + length w + 1

data Feature
	= NoFeature
	| ElipsesFeature
	| EOLFeature
	| NewParaFeature Int
	| CorridorFeature Int
	deriving (Ord, Eq)

instance Random Feature where
	randomR _ g = random g
	random = go . randomR (1,100 :: Int)
	  where
		go (n, g)
			| n < 5 = (ElipsesFeature, g)
			| n < 8 = 
				let (l, g') = randomR (2,4) g
				in (NewParaFeature l, g')
			| n < 10 = (EOLFeature, g)
			| n < 12 =
				let (l, g') = randomR (10, targetwidth `div` 3) g
				in (CorridorFeature l, g')
			| otherwise = (NoFeature, g)

featureStream :: Rand -> [Feature]
featureStream r = withStdGen r (repeat NoFeature) randoms

addFeatures :: [(String, Feature)] -> Stream
addFeatures [] = []
addFeatures ((w, f):rest) = case f of
	NoFeature -> Chunk w : addFeatures rest
	ElipsesFeature -> Chunk ".." : cont
	NewParaFeature n -> ParaBreak : Chunk (replicate n ' ') : cont
	EOLFeature -> ParaBreak : cont
	CorridorFeature n -> Chunk (replicate n ' ') : cont
  where
	cont = addFeatures ((w, NoFeature):rest)