diff options
| author | pb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157> | 2009-11-22 09:26:32 +0000 |
|---|---|---|
| committer | pb <pb@9f8f72e9-4bf4-416e-b76e-7d4203597157> | 2009-11-22 09:26:32 +0000 |
| commit | 9e4882a1c017a88a7b79149206f8a0ea83bcb0e1 (patch) | |
| tree | a78a47d1e92c1ca688e15f954315123d919fde47 /Main.hs | |
git-svn-id: https://ssl.buetow.org/repos/hsbot/trunk@1 9f8f72e9-4bf4-416e-b76e-7d4203597157
Diffstat (limited to 'Main.hs')
| -rw-r--r-- | Main.hs | 157 |
1 files changed, 157 insertions, 0 deletions
@@ -0,0 +1,157 @@ +-- Karmabot By Paul C. Buetow + +module Main (main) where + +import Control.Monad (forM) +import Control.Monad.State +import IO +import Monad +import Random +import System + + +version :: String +version = "0.0" + +data Karma = Karma { karmaName :: String, minPts :: Int, minPerc :: Float } deriving (Show, Read) + +instance Eq Karma where x == y = (minPerc x) == (minPerc y) && (minPts x == minPts y) + +instance Ord Karma where + x > y | (minPerc x) > (minPerc y) = True + | otherwise = (minPts x) > (minPts y) + x < y | (minPerc x) < (minPerc y) = True + | otherwise = (minPts x) < (minPts y) + x >= y = not (x < y) + x <= y = not (x > y) + +data Conf = Conf { users :: [User], karmas :: [Karma] } deriving (Show, Read) + +type StateTrans st = s -> (t, s) + + + +data User = User { userName :: String, userPts :: Int } deriving (Show, Read) + +instance Eq User where x == y = (userPts x) == (userPts y) + +instance Ord User where + x < y = (userPts x) < (userPts y) + x > y = (userPts x) > (userPts y) + x >= y = not (x < y) + x <= y = not (x > y) + +class Render a where render :: a -> String + +instance Render User where + render user = + userName user ++ + ": " ++ (userKarma user) ++ + " (rank " ++ (show $ userRank user) ++ "/" ++ (show numUsers) ++ "; " ++ + (show $ userPts user) ++ "pts; " ++ (show $ userPerc user) ++ "%)" + +makeDefaultConf :: Conf +makeDefaultConf = Conf { + users = [ + User "thunder" 100, + User "otto" 1, + User "rantanplan" 3, + User "rantanplan2" 3, + User "icefox2" 11, + User "icefox" 10, + User "foobar" 5, + User "foobar1" 5, + User "foobar2" 5, + User "foobar3" 5, + User "foobar4" 5, + User "foobar5" 5, + User "foobar6" 5, + User "openfire" 2 + ], + karmas = [ + Karma "God" 20 90, + Karma "Guru" 10 80, + Karma "Nerd" 10 70, + Karma "Expert" 5 60, + Karma "Geek" 3 40, + Karma "Advanced" 0 20, + Karma "Cool dude" 0 0 + ] } + +makeConf :: Conf +makeConf = makeDefaultConf + +numUsers :: Int +numUsers = length $ users makeConf + +sortedUsers :: [User] +sortedUsers = sort $ users makeConf + +userEquals :: User -> User -> Bool +userEquals x y = (userName x) == (userName y) + +userRank :: User -> Int +userRank = userRank' 1 sortedUsers + where userRank' rank (x:xs) user + | userEquals x user = rank + | otherwise = userRank' (rank+1) xs user + +userPerc :: User -> Float +userPerc user = + let rank = userRank user + userPerc' + | rank == 1 = 100 -- 1st always has 100% + | rank == numUsers = 0 -- last always has 0% + | otherwise = + let userWeight = 100 / (fromIntegral numUsers) + in 100 - userWeight * (fromIntegral rank) + in userPerc' + +userKarma :: User -> String +userKarma user = userKarma' (userPts user) (userPerc user) + where userKarma' pts perc = + let cands = sort $ filter (\x -> minPts x <= pts && minPerc x <= perc) (karmas makeConf) + in karmaName $ cands !! 0 -- Best posible karma + +sort :: (Ord a) => [a] -> [a] +sort [] = [] +sort (x:xs) = sort (filter (>= x) xs) ++ [x] ++ sort (filter (< x) xs) + +readline :: IO () +readline = do + line <- getLine + case line of + "q" -> do { putStrLn "Good bye"; exitWith ExitSuccess } + _ -> putStrLn "" + + +data MyType = MT Int Bool Char Int deriving Show + +{- Using the State monad, we can define a function that returns + a random value and updates the random generator state at + the same time. +-} +getAny :: (Random a) => State StdGen a +getAny = do g <- get + (x,g') <- return $ random g + put g' + return x + +-- similar to getAny, but it bounds the random value returned +getOne :: (Random a) => (a,a) -> State StdGen a +getOne bounds = do g <- get + (x,g') <- return $ randomR bounds g + put g' + return x + +{- Using the State monad with StdGen as the state, we can build + random complex types without manually threading the + random generator states through the code. +-} +makeRandomValueST :: StdGen -> (MyType, StdGen) +makeRandomValueST = runState (do n <- getOne (1,100) + b <- getAny + c <- getOne ('a','z') + m <- getOne (-n,n) + return (MT n b c m)) + |
