星期六, 3月 30, 2013

Guessing Number using Haskell

今天利用一點時間寫出來的簡單版(困難版我也不會 XD),明天有空再補心得 XD。如果有什麼可以加強或改寫的的地方還請指教,我會很開心的,謝謝 :)。

import System.Random

checkNum :: [Integer] -> [Integer] -> (Integer, Integer)
checkNum input ans = (posNum input ans, correctNum input ans) 
    where posNum input ans = sum $ zipWith (boolValue (x==y)) input ans 
          correctNum input ans = foldr (\x y -> y + boolValue (any (== x) ans)) 0 input
          boolValue a = if a == True then 1 else 0

game :: [Integer] -> IO ()
game ans = do
    input <- fmap (fmap (\x -> read [x])) getLine
    
    let (rpn, rn) = checkNum input ans
    if rpn == 4 then
        do putStrLn "Win"
           return () 
    else
        do putStrLn $ show rpn ++ "A" ++ show rn ++ "B"
           game ans

main = do
    gen <- getStdGen
    let ans = take 4 (randomRs (1,9) gen)
    game ans

---
繼續前進。


T55555的回應給了許多寶貴的意見,真的很謝謝他每次都給予很好的建議(至於我這麼晚回的原因是因為仍在當兵中...Orz),我也做出了回應,現在把整個修完的 code 再貼一次如下。


import System.Random

-- Wrong game logic
-- checkNum :: [Int] -> [Int] -> (Int, Int)
-- checkNum input ans = (posNum input ans, correctNum input ans) 
--    where posNum input ans = foldr (\x y -> y + fromEnum x) 0 $ zipWith (==) input ans 
--          correctNum input ans = foldr (\x y -> y + (fromEnum (any (==x) ans))) 0 input 

checkNum' :: [Int] -> [Int] -> (Int, Int)
checkNum' input ans = foldr (check ans) (0, 0) $ zip input ans 
    where check ans (x,y) (p,c) = 
            if x == y then (p+1,c)
            else
                if (any (==x) ans) then (p,c+1)
                else (p,c)

game :: [Int] -> IO ()
game ans = do
    input <- fmap (fmap (\x -> read [x])) getLine
    
    let (rpn, rn) = checkNum' input ans
    if rpn == 4 then
        do putStrLn "Win"
           return () 
    else
        do putStrLn $ show rpn ++ "A" ++ show rn ++ "B"
           game ans

main = do
    gen <- getStdGen
    let ans = take 4 (randomRs (1,9) gen)
    putStrLn $ show ans
    game ans

張貼留言