packages feed

drunken-bishop-0.1.0.0: src/Main.hs

module Main (main) where

import Crypto.Hash.SHA256 (hashlazy)
import qualified Data.ByteString.Lazy as BS
import Data.Digest.DrunkenBishop
import System.Console.GetOpt (ArgDescr (..), ArgOrder (..), OptDescr (..), getOpt)
import System.Environment (getArgs)

readSize :: String -> (Int, Int)
readSize str = case reads str of
  [(x, 'x' : rest)] -> case reads rest of
    [(y, "")] -> (x, y)
    _ -> error msg
  _ -> error msg
  where
    msg = "Unable to parse " ++ str ++ " as an [Int]x[Int] pair"

options :: [OptDescr (DrunkenBishopOptions BS.ByteString -> DrunkenBishopOptions BS.ByteString)]
options =
  [ Option
      ['s']
      ["size"]
      (ReqArg (\o opts -> opts {drunkenBishopBoardSize = readSize o}) "[WIDTH]x[HEIGHT]")
      "The size of the art fingerprint",
    Option
      ['p']
      ["position"]
      (ReqArg (\o opts -> opts {drunkenBishopInitialPosition = Just (readSize o)}) "[X]x[Y]")
      "The initial position of the bishop",
    Option
      []
      ["sha256"]
      (NoArg (\opts -> opts {drunkenBishopHash = hashlazy}))
      "Use SHA256 instead of MD5 for the source hash"
  ]

main :: IO ()
main = do
  argv <- getArgs
  let (opts, files) = case getOpt Permute options argv of
        (fs, args, []) -> (foldr ($) drunkenBishopDefaultOptions fs, args)
        (_, _, errs) -> error (unlines errs)
  f <- case files of
    [] -> BS.getContents
    _ -> mconcat (map BS.readFile files)
  let boardWidth = fst (drunkenBishopBoardSize opts)
      frame = "+" ++ replicate boardWidth '-' ++ "+"
  putStrLn frame
  mapM_
    putStrLn
    [ "|" ++ ln ++ "|"
      | ln <- lines (drunkenBishopWithOptions opts f)
    ]
  putStrLn frame