unscramble-0.2: Unscramble/Output.hs
module Unscramble.Output (
display
) where
import Control.Lens
import qualified Data.HashMap as H
import Text.Printf
import Unscramble.Types
-- words are already sorted by score
display :: [(Score, String, [Coordinate])]
-> Grid
-> Multiplier
-> ScrambleOpts
-> IO ()
display xs g m (ScrambleOpts _ _ ds)
| ds == OneLine = (showTotal >>) $ mapM_ (\x -> putStr ((_2 ^$ x) ++ " ")) xs
| ds == Chunked = (showTotal >>) $ mapM_ (\ns -> do
mapM_ (displayGrid g m) ns
putStrLn "\nPress enter for more, or ctrl-c to quit."
getLine) $ chunk xs
where
showTotal = do
let points = sum . map (_1 ^$) $ xs
printf "%d total words for %d points.\n" (length xs) points
chunk (a:b:c:es) = [a,b,c]:chunk es
chunk x = [x]
display _ _ _ (ScrambleOpts _ _ _) = error "what?"
displayGrid :: Grid
-> Multiplier
-> (Score, String, [Coordinate])
-> IO ()
displayGrid (Grid _ gs) (Multiplier dl dw tl tw) (sc, word, cs)
= (putStrLn ("\n\27[1m" ++ word ++ "\27[0m: " ++ show sc) >>)
. mapM_ (putStr . render) $ idxs
where
idxs = [(a,b) | a <- [0..3], b <- [0..3]]
render n
| head cs == n = "\27[44m" ++ pad letter n True ++ "\27[49m" ++ nl
| n `elem` cs = "\27[107m" ++ pad letter n True ++ "\27[49m" ++ nl
| otherwise = pad letter n False ++ nl
where
letter = H.findWithDefault undefined n gs
nl = if snd n == 3 then "\n" else ""
pad [x] n t = " " ++ highlight [x] n t ++ " "
pad x n t = ' ':highlight x n t
highlight x n t
| n `elem` dl = "\27[36;1m" ++ x ++ "\27[39;22m"
| Just n == dw = "\27[31;1m" ++ x ++ "\27[39;22m"
| n `elem` tl = "\27[32;1m" ++ x ++ "\27[39;22m"
| Just n == tw = "\27[33;1m" ++ x ++ "\27[39;22m"
| t = "\27[30m" ++ x ++ "\27[39;22m"
| otherwise = x