[ create a new paste ] login | about

Link: http://codepad.org/3oEk8lKq    [ raw code | fork ]

asvyazin - Haskell, pasted on Dec 11:
module Main where

import Control.Applicative ((<$>))
import Control.Monad (forever)
import Control.Monad.Trans (lift)
import Control.Monad.State (StateT, evalStateT, get, put)
import System.Random (getStdRandom, randomR)

data Move = Rock | Paper | Scissors deriving (Show, Eq, Enum)
data Result = HumanWins | AIWins | Draw deriving (Show, Eq)

beats :: Move -> Move -> Maybe Bool
Rock `beats` Scissors = Just True
Scissors `beats` Paper = Just True
Paper `beats` Rock = Just True
x `beats` y | x == y = Nothing
            | otherwise = Just False

-- 1 - Rock, 2 - Paper, 3 - Scissors
intToMove :: Int -> Move
intToMove n = toEnum $ n - 1

askHumanMove :: IO Move
askHumanMove = do
  putStr "Enter your move (1 - Rock, 2 - Paper, 3 - Scissors): "
  intToMove <$> (read :: String -> Int) <$> getLine

generateAIMove :: IO Move
generateAIMove = intToMove <$> (getStdRandom $ randomR (1, 3))

doMove :: IO Result
doMove = do
  aiMove <- generateAIMove
  humanMove <- askHumanMove
  putStrLn $ "AI move - " ++ (show aiMove) ++ ", human move - " ++ (show humanMove)
  return $ case aiMove `beats` humanMove of
    Just True -> AIWins
    Just False -> HumanWins
    _ -> Draw

gameStep :: StateT (Int, Int) IO ()
gameStep = do
  s@(aiScore, humanScore) <- get
  result <- lift doMove
  newScore <- case result of
    Draw -> lift (putStrLn "Draw... Once again!") >> return s
    AIWins -> lift (putStrLn "AI wins!") >> return (aiScore + 1, humanScore)
    HumanWins -> lift (putStrLn "Human wins!") >> return (aiScore, humanScore + 1)
  lift $ displayScore newScore
  put newScore

displayScore :: (Int, Int) -> IO ()
displayScore (aiScore, humanScore) = putStrLn $ "SCORE - " ++ (show aiScore) ++ ":" ++ (show humanScore) ++ " (AI:Human)"

main :: IO ()
main = evalStateT (forever gameStep) (0, 0)


Create a new paste based on this one


Comments: