import Control.Concurrent import System.Random import Text.Printf import System.IO import System.Timeout import Control.Monad data Msg = C Char | Time main = do hSetBuffering stdout NoBuffering hSetBuffering stdin NoBuffering hSetEcho stdin False m <- newEmptyMVar scorem <- newMVar 0 forkIO $ forever $ do score <- readMVar scorem threadDelay (truncate (fromIntegral 1000000 * (0.9 ^ score))) putMVar m Time forkIO $ forever (do c <- getChar; putMVar m (C c)) loop m scorem "" where update m old new = do putStr (replicate n '\8') putStr (replicate n ' ') putStr (replicate n '\8') putStr new where n = length old loop :: MVar Msg -> MVar Int -> String -> IO () loop m scorem s | length s == 10 = do score <- readMVar scorem printf "\nGAME OVER. SCORE = %d\n" score | otherwise = do x <- takeMVar m case x of C c -> do let new = filter (/= c) s update m s new modifyMVar_ scorem (return . (+ (length s - length new))) loop m scorem new Time -> do c <- randomRIO ('0','9') let new = s ++ [c] update m s new loop m scorem new