hs2048-0.1.0: library/Hs2048/Renderer.hs
-- | Functions for pretty-printing games to the console.
module Hs2048.Renderer
( center
, color
, renderBoard
, renderGame
, renderTile
) where
import Data.Monoid ((<>))
import qualified Hs2048.Board as B
import qualified Hs2048.Tile as T
{- |
Centers a string in the given number of characters, using spaces for
padding.
>>> center 3 "x"
" x "
>>> center 2 "x"
" x"
-}
center :: Int -> String -> String
center w s = prefix <> s <> suffix
where
prefix = replicate (ceiling n) ' '
suffix = replicate (floor n) ' '
n = fromIntegral (w - length s) / (2 :: Float)
{- |
Calculates the color code for a tile. See
<http://en.wikipedia.org/wiki/ANSI_escape_code#Colors>.
>>> color Nothing
30
>>> color (Just 2)
31
>>> color (Just 2048)
45
-}
color :: T.Tile -> Int
color t = 30 + x
where
x = if r > 6 then r + 4 else r
r = T.rank t
{- |
Renders a board with colorized, centered tiles. See 'renderTile' and
'center'.
>>> renderBoard [[Nothing, Just 2]]
"\ESC[30m-\ESC[0m \ESC[31m2\ESC[0m\n"
>>> renderBoard [[Nothing, Just 16]]
" \ESC[30m-\ESC[0m \ESC[34m16\ESC[0m\n"
-}
renderBoard :: B.Board -> String
renderBoard b = unlines (fmap unwords vs')
where
vs' = fmap (fmap (center l)) vs
vs = fmap (fmap renderTile) b
l = maximum ls
ls = vs >>= fmap length
{- |
Renders a board along with its score. See 'renderBoard'.
>>> renderGame [[Nothing, Just 2]]
"Score: 0\n\ESC[30m-\ESC[0m \ESC[31m2\ESC[0m\n"
-}
renderGame :: B.Board -> String
renderGame b = concat
[ "Score: "
, show (B.score b)
, "\n"
, renderBoard b
]
{- |
Renders a colorized tile. See 'color'.
>>> renderTile Nothing
"\ESC[30m-\ESC[0m"
>>> renderTile (Just 2)
"\ESC[31m2\ESC[0m"
-}
renderTile :: T.Tile -> String
renderTile t = concat
[ "\ESC["
, show (color t)
, "m"
, T.render t
, "\ESC[0m"
]