SHARE
TWEET

Untitled

a guest Nov 12th, 2019 74 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Helge Mikael Landro
  2.  
  3. import Data.Char
  4.  
  5. {-
  6. For simplicity the player number is
  7. represented as an integer (1 or 2).
  8. -}
  9.  
  10. next :: Int -> Int
  11. next 1 = 2
  12. next 2 = 1
  13.  
  14. {-
  15. In turn, we represent the board as a list
  16. comprising the number of stars that remain
  17. on each row, with the initial board given by
  18. the list [5,4,3,2,1] and the game being finished
  19. when all rows have no stars left.
  20. -}
  21.  
  22. type Board = [Int]
  23.  
  24. initial :: Int -> Board
  25. initial rows = if rows      == 2 then [1,2]
  26.                else if rows == 3 then [1,2,3]
  27.                else if rows == 4 then [1,2,3,4]
  28.                else if rows == 5 then [1,2,3,4,5]
  29.                else error "wrong input"
  30.  
  31. finished :: Board -> Bool
  32. finished = all (== 0)
  33.  
  34. {-
  35. A move in the game is specified by a row number
  36. and the number of stars to be removed, and is valid
  37. if the row contains at least this many stars.
  38. Example:
  39. -- The first row on the initial board contains at least 3 stars
  40. > valid initial 1 3
  41. True
  42. -- The 4th row contains fewer than 3 stars
  43. > valid inital 4 3
  44. False
  45. -}
  46.  
  47. valid :: Board -> Int -> Int -> Bool
  48. valid board row num = (row - 1) >= num
  49.  
  50. {-
  51. A valid move can then be applied to a board to
  52. give a new board by using a list comprehension
  53. to update the number of stars taht remain in
  54. each row.
  55. Example:
  56. -- 3 stars have been removed in the 1 row
  57. > move inital 1 3
  58. [2,4,3,2,1]
  59. -}
  60.  
  61. move :: Board -> Int -> Int -> Board
  62. move board row num = [update r n | (r, n) <- zip [1..] board]
  63.    where update r n = if r == row then (n - num) else n
  64.  
  65.  
  66. -- IO Utils
  67. putRow :: Int -> Int -> IO ()
  68. putRow row num = do putStr (show num ++ " ")
  69.                     putStrLn (concat (replicate num " * "))
  70.  
  71. putColumn :: Int -> IO()
  72. putColumn num = do putStr "   "
  73.                    putStr (show (num))
  74.  
  75.  
  76. putBoard :: Board -> Int -> IO ()
  77. putBoard board rows = if length board      == 2 then do
  78.                                                    putRow 1 1
  79.                                                    putRow 2 2
  80.                                                    putColumn rows
  81.                       else if length board == 3 then do
  82.                                                    putRow 1 1
  83.                                                    putRow 2 2
  84.                                                    putRow 3 3
  85.                                                    putColumn rows
  86.                       else if length board == 4 then do
  87.                                                    putRow 1 1
  88.                                                    putRow 2 2
  89.                                                    putRow 3 3
  90.                                                    putRow 4 4
  91.                                                    putColumn rows
  92.                       else if length board == 5 then do
  93.                                                    putRow 1 1
  94.                                                    putRow 2 2
  95.                                                    putRow 3 3
  96.                                                    putRow 4 4
  97.                                                    putRow 5 5
  98.                                                    putColumn rows
  99.                       else error "Fix"
  100.  
  101. getDigit :: String -> IO Int
  102. getDigit prompt = do putStr prompt
  103.                      x <- getChar
  104.                      newline
  105.                      if isDigit x then
  106.                         return (digitToInt x)
  107.                      else
  108.                         do putStrLn "ERROR: Invalid digit"
  109.                            getDigit prompt
  110.  
  111. newline :: IO ()
  112. newline = putChar '\n'
  113.  
  114.  
  115. -- Game of nim
  116. play :: Board -> Int -> Int-> IO ()
  117. play board player rows = do
  118.       putStrLn "n(im) x / c(homp) x / q(uit)"
  119.       userInput <- getLine
  120.       if head userInput        == 'n' then putStrLn "Lets play nim bitches!"
  121.       else if head userInput   == 'c' then putStrLn "Chomp"
  122.       else if head userInput   == 'q' then do
  123.                                     putStrLn "Now quitting the game."
  124.                                     return ()
  125.       else error "Invalid input"  
  126.      
  127.       putBoard board rows
  128.       if finished board then
  129.          do newline
  130.             putStr "Player "
  131.             putStr (show (next player))
  132.             putStrLn " wins!"
  133.       else
  134.          do newline
  135.             putStr "Player "
  136.             putStrLn (show player)
  137.             row <- getDigit "Enter a row number: "
  138.             num <- getDigit "Stars to remove: "
  139.             if valid board row num then
  140.                play (move board row num) (next player) rows
  141.             else
  142.                do newline
  143.                   putStrLn "ERROR: Invalid move"
  144.                   play board player rows
  145. nim :: Int -> IO ()
  146. nim num = play (initial num) 1 num
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top