-- Mark Jones -- 0564129 import LSystem -- 1. join :: [Command] -> Command join x | x == [] = error "No effective command entered!!!" |otherwise = foldr1 (:#) x -- i added the guard in for later in the optimise command when something like (Go 20 :# Go (-20)), where no effective command was entered. So rather than giving an unhelpful error, the program gives an explaination for what has happened -- 2. split :: Command -> [Command] split (x :# x2) = split x ++ split x2 split x = [x] -- 3. copy :: Int -> Command -> Command copy n x = join (replicate n x) -- 4. hexagon :: Distance -> Command hexagon d = copy 6 (join [Go d,Turn 60]) -- 5. polygon :: Distance -> Int-> Command polygon d n = copy (fromIntegral n) (join [Go d, Turn (360/fromIntegral n)]) -- 6. spiral:: Distance -> Int -> Distance -> Angle -> Command spiral max seg decr ang = join (spiral' max seg decr ang ) spiral':: Distance -> Int -> Distance -> Angle -> [Command] spiral' max seg decr ang = [ Go (max - ((fromIntegral i)*decr)) :# Turn ang | i <- [0..seg], i <=seg, (max - ((fromIntegral i)*decr)) >= 0 ] -- The guard prevents the spiral from making a very un-pretty reverse spindly shape when the current length is less than 0, because the spiral starts heading in the opposite direction. In that case, the "leftovers" of the spiral function are scrapped. -- 7. optimise :: Command -> Command optimise command = join ( prune (sub (split command))) sub :: [Command] -> [Command] sub ([]) = [Go 0] sub (x:Sit:xs) = sub (x:xs) sub (x:Go 0:xs) = sub (x:xs) sub (Sit:xs) = Go 0 : sub xs sub (Turn x: Turn x2 : xs) = sub (Turn (x+x2):xs) sub (Go x : Go x2: xs) = sub (Go (x+x2):xs) sub (Go x: xs) = Go x : (sub xs) sub (Turn x:xs) = Turn x : (sub xs) prune :: [Command] -> [Command] prune [] = [] prune (x:xs) | x == Go 0 = prune xs | x == Turn 0 = prune xs |otherwise = x: prune xs -- 8. arrowhead :: Int -> Command arrowhead x = f x where f 0 = GrabPen red :# Go 10 f (x+1) = g x :# p :# f x :# p :# g x g 0 = GrabPen blue :# Go 10 g (x+1) = f x :# n :# g x :# n :# f x n = Turn (60) p = Turn (-60) -- 9. branch :: Int -> Command branch x = g x where g 0 = GrabPen green :# Go 10 g (x+1) = f x :# n :# Branch ( Branch ( g x ) :# p :# g x ) :# p :# f x :# Branch ( p :# f x :# g x ) :# n :# g x f 0 = GrabPen red :# Go 10 f (x+1) = f x :# f x p = Turn (-22.5) n = Turn (22.5) -- 10. hilbert :: Int -> Command hilbert x = l x where l 0 = GrabPen blue :# Go 10 l (x+1) = p :# r x :# f :# n :# l x :# f :# l x :# n :# f :# r x :# p r 0 = GrabPen black :# Go 10 r (x+1) = n :# l x :# f :# p :# r x :# f :# r x :# p :# f :# l x :# n f = GrabPen red :# Go 10 p = Turn (-90) n = Turn (90) -- stuff for when i was bored, count this as my competition entries, view it with : -- >display 0.25 (competition x) -- where x > 4, the greater the value, the bushier it gets. i would suggest around 6, it will take a minute to create.... competition :: Int -> Command competition x = a x where a 0 = Turn 25 a (x+1) = r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x :# p :# r x r 0 = Turn 25 r (x+1) = Branch ( g x :# p :# g x :# p :# g x :# p :# g x :# p :# g x :# p :# g x :# p :# g x :# p :# g x :# p :# g x) g 0 = GrabPen green :# Go 10 g (x+1) = f x :# n :# Branch ( Branch ( g x ) :# p :# g x ) :# p :# f x :# Branch ( p :# f x :# g x ) :# n :# g x f 0 = GrabPen red :# Go 10 f (x+1) = f x :# f x p = Turn (-22.5) n = Turn (22.5)