Skip to content

Instantly share code, notes, and snippets.

@fstiffo
Last active September 28, 2017 21:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fstiffo/2c8b38e17a20fe2034716f749aff4c17 to your computer and use it in GitHub Desktop.
Save fstiffo/2c8b38e17a20fe2034716f749aff4c17 to your computer and use it in GitHub Desktop.
import System.Random
{-
A little more generic version of the Bulls and Cows
guessing game.
To reproduce the original game simply call:
bullandcows 4 "123456789"
For a detailed description of the game look at:
https://en.wikipedia.org/wiki/Bulls_and_Cows
-}
delete :: Int -> [a] -> [a]
delete n xs =
let (ys, zs) = splitAt n xs
in ys ++ (tail zs)
randompick :: Int -> String -> IO String
randompick n digits = randompick' n digits []
where
randompick' :: Int -> String -> String -> IO String
randompick' n' digits' secret = do
index <- randomRIO (0, length digits' - 1)
let digit = digits' !! index
let digits'' = delete index digits'
if n' > 0
then randompick' (n' - 1) digits'' (digit : secret)
else return (secret)
check :: String -> String -> (Int, Int)
check secret guess =
if length secret /= length guess
then (0, 0)
else let pairs = zip secret guess
bulls = length (filter (\(x, y) -> x == y) pairs)
cows = length (filter (\x -> x `elem` secret) guess) - bulls
in (bulls, cows)
turn :: String -> String -> IO ()
turn secret guess = do
if secret == guess
then putStrLn "You win!"
else mkguess secret
mkguess :: String -> IO ()
mkguess secret = do
putStr " Enter your guess: "
guess <- getLine
let (bulls, cows) = check secret guess
putStrLn $ "Bulls: " ++ show bulls ++ " Cows: " ++ show cows
turn secret guess
bullsandcows :: Int -> String -> IO ()
bullsandcows secretlen symbols = do
secret <- randompick secretlen symbols
turn secret ""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment