Advertisement
Guest User

Untitled

a guest
Feb 25th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.50 KB | None | 0 0
  1. import Data.List
  2. import Data.Either
  3.  
  4. data Being = Wolf | Goat | Cabbage deriving (Eq, Show)
  5. data Direction = Leftward | Rightward
  6. type Boat = Maybe Being
  7. type Coast = [Being]
  8. type River = (Coast, Coast)
  9. type Gamestate = (River, Direction)
  10.  
  11. instance Show Direction where
  12. show Rightward = ".......(boat)"
  13. show Leftward = "(boat)......."
  14.  
  15. -- initial state
  16. start :: Gamestate
  17. start = (([], [Wolf, Goat, Cabbage]), Rightward)
  18.  
  19. -- take a being on the boat
  20. takeit :: Being -> Coast -> Either String Coast
  21. takeit being coast = if elem being coast
  22. then Right (delete being coast)
  23. else Left $ show being ++ " is not here"
  24.  
  25. -- if Goat ate Cabbage or Wolf ate Goat - game is over
  26. eaten :: Coast -> Either String Coast
  27. eaten coast
  28. | elem Goat coast && elem Cabbage coast = Left "* Goat ate cabbage! Try again! *"
  29. | elem Goat coast && elem Wolf coast = Left "* Wolf ate goat! Try again! *"
  30. | otherwise = Right coast
  31.  
  32. -- moving between coasts on the river
  33. shipping :: River -> Boat -> Direction -> Either String River
  34. shipping river@(lc, rc) boat Leftward = case boat of
  35. Just being -> takeit being rc >>= eaten >>= \rcoast -> Right (being:lc, rcoast)
  36. Nothing -> eaten rc >> Right river
  37. shipping river@(lc, rc) boat Rightward = case boat of
  38. Just being -> takeit being lc >>= eaten >>= \lcoast -> Right (lcoast, being:rc)
  39. Nothing -> eaten lc >> Right river
  40.  
  41. -- interpretation of user's input
  42. input :: IO Boat
  43. input = getLine >>= \choice -> case choice of
  44. "0" -> return Nothing
  45. "1" -> return $ Just Wolf
  46. "2" -> return $ Just Goat
  47. "3" -> return $ Just Cabbage
  48. _ -> print "Wrong, try again" >> input
  49.  
  50. display :: Gamestate -> IO ()
  51. display ((lc, rc), dir) = print $ "River: " ++ show lc ++ " " ++ show dir ++ " " ++ show rc
  52.  
  53. gretings :: IO ()
  54. gretings = print "* Welcome to the WGC! *"
  55.  
  56. prompt :: IO ()
  57. prompt = print "[0 - empty, 1 - Wolf, 2 - Goat, 3 - Gabbage]"
  58.  
  59. invert :: Direction -> Direction
  60. invert Leftward = Rightward
  61. invert Rightward = Leftward
  62.  
  63. -- after each turn we got new state of river and last direction
  64. turn :: Gamestate -> Boat -> IO Gamestate
  65. turn (river, dir) boat = case shipping river boat (invert dir) of
  66. Left err -> print err >> return (river, dir)
  67. Right newriver -> return (newriver, invert dir)
  68.  
  69. -- if right coast is empty - victory
  70. check :: River -> Either String River
  71. check river@(_, rc) = if null rc then Left "* Congratulations! You win! *" else Right river
  72.  
  73. main = gretings >> prompt >> loop start
  74. where loop (r,d) = case check r of
  75. Left err -> print err
  76. Right _ -> display (r,d) >> input >>= turn (r,d) >>= \st -> loop st
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement