content: import System.Random
  import System.IO
  import System.Exit
  import Control.Monad
  import Text.Read
  import Data.Maybe
  
  promptAgain :: IO Int
  promptAgain = do
    putStrLn "Invalid input - must be a number among 1,2 or 3. Try again."
    playerMove
  
  playerMove :: IO Int
  playerMove = do
    putStr "Your choice(1 to 3):"
    number <- getLine
    when (number == "q") $ do
      exitWith ExitSuccess
    let n = readMaybe number :: Maybe Int
    x <- if isNothing n
               then promptAgain
               else let val = read number
                     in if (val > 3 || val < 1)
                        then promptAgain
                        else return val
    return x
  
  computerMove :: IO Int
  computerMove = do
    x <- randomRIO (1, 3)
    putStrLn $ "Computer move:" ++ (show x)
    return x
  
  gameLoop :: (IO Int, IO Int) -> IO Int
  gameLoop moveorder = loop moveorder 0
    where loop moveorder total = do
          number <- fst moveorder
          let total1 = number + total
          putStrLn $ "Running total:" ++ (show total1)
          if total1 >= 21
             then return 0
             else do
               number <- snd moveorder
               let total2 = number + total1
               putStrLn $ "Running total:" ++ (show total2)
               if total2 >= 21
                  then return 1
                  else loop moveorder total2
  
  main :: IO ()
  main = do
    hSetBuffering stdout $ BlockBuffering $ Just 1
    putStrLn "Enter q to quit at any time"
    x <- randomRIO (0, 1) :: IO Int
    let (moveorder, names) = if x == 0
                   then ((playerMove, computerMove), ("Player", "Computer"))
                   else ((computerMove, playerMove), ("Computer", "Player"))
    when (x == 1) $ do
      putStrLn "Computer will start the game"
    y <- gameLoop moveorder
    when (y == 0) $ do
      putStrLn $ (fst names) ++ " has won the game"
    when (y == 1) $ do
      putStrLn $ (snd names) ++ " has won the game"
  