Skip to content

Instantly share code, notes, and snippets.

@skalahonza
Created May 17, 2018 20:19
Show Gist options
  • Save skalahonza/ceb37fb58d85a0392bf12a146e37022c to your computer and use it in GitHub Desktop.
Save skalahonza/ceb37fb58d85a0392bf12a146e37022c to your computer and use it in GitHub Desktop.
NIM game (5,4,3,2,1)
-- board type definition for game board
type Board = [Int]
initBoard :: Board
initBoard = [5,4,3,2,1]
-- player tpye definition
data Player = P1 | P2 deriving Show
nextP :: Player -> Player
nextP P1 = P2
nextP P2 = P1
-- check if hte game is over
is_finished ::Board -> Bool
is_finished b = all (==0) b
-- make a move and return chaned game state
move :: Board -> Int -> Int -> Board
move (x:xs) p o | p == 0 = ((x-o):xs)
| otherwise = x:(move xs (p-1) o)
-- print a row with sticks
putRow :: Int -> Int -> IO()
putRow row sticks = do
putStr ((show row) ++ ") ")
putStrLn (map (\_ -> '|') [1..sticks])
-- print entire game board
putBoard :: Board -> IO()
putBoard b = printBoard b 1 where
printBoard (x:xs) row = do
putRow row x
printBoard xs (row + 1)
printBoard [] _ = do return ()
-- helper function for etting row number
getRowNum :: String -> IO Int
getRowNum prompt = do
putStrLn prompt
rows <- getLine
return (read rows)
-- play the current game, using given board
play :: Board -> Player -> IO()
play board player | is_finished(board) = putStrLn ((show player) ++ " won")
| otherwise = do
putBoard board
putStrLn ("Player " ++ (show player) ++ " is playing")
row <- getRowNum "Enter row"
sticks <- getRowNum "Enter count of sticks to remove"
play (move board (row-1) sticks) (nextP player)
startGame = play initBoard P1
main = do
startGame
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment