module Pictures
( Picture
, horse
, flipV
, flipH
, above
, beside
, superimpose
, invertColour
, scale
, black
, white
)
where
import Test.SmallCheck
import Test.SmallCheck.Series
import Data.List
import Control.Monad
newtype Picture = Picture [[Char]]
deriving Eq
horse :: Picture
horse = Picture
[" ## ",
" ## # ",
" ## # ",
" # # ",
" # # # ",
" # ### # ",
" # # ## ",
" # # ",
" # # ",
" # # ",
" # # ",
" ## "]
white :: Picture
white = Picture [" "]
black = Picture ["#"]
instance Show Picture where
show (Picture p) = "\n" ++ concatMap (\x -> "|" ++ x ++ "|\n") p
instance Serial Picture where
series d = do
size <- [0..d]
map (fromList size) $ replicateM (size^2) [' ', '#']
coseries = error "Picture.coseries"
fromList :: Int -> [Char] -> Picture
fromList size cs = Picture $ unfoldr f cs
where
f [] = Nothing
f xs = Just $ splitAt size xs
pic :: ([[Char]] -> [[Char]]) -> Picture -> Picture
pic f (Picture p) = Picture $ f p
pic2 :: ([[Char]] -> [[Char]] -> [[Char]]) -> Picture -> Picture -> Picture
pic2 f (Picture p1) (Picture p2) = Picture $ f p1 p2
flipV :: Picture -> Picture
flipV = pic $ map reverse
flipH :: Picture -> Picture
flipH = pic reverse
rotate :: Picture -> Picture
rotate = flipH . flipV
above :: Picture -> Picture -> Picture
above = pic2 (++)
beside :: Picture -> Picture -> Picture
beside = pic2 $ zipWith (++)
superimpose :: Picture -> Picture -> Picture
superimpose = pic2 $ zipWith (zipWith combine)
combine :: Char -> Char -> Char
combine topCh bottomCh
= if (topCh == ' ' && bottomCh == ' ')
then ' '
else '#'
invertColour :: Picture -> Picture
invertColour = pic $ map (map invert)
invert :: Char -> Char
invert ch = if ch == ' ' then '#' else ' '
scale :: Int -> Picture -> Picture
scale n = pic $ \ls ->
map (>>= replicate n) ls >>= replicate n