Guest User

Untitled

a guest
Jan 2nd, 2023
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.32 KB | None | 0 0
  1. import System.IO
  2.  
  3. data Player = X | O deriving (Eq, Show)
  4. type Grid = [[Maybe Player]]
  5.  
  6. initialGrid :: Grid
  7. initialGrid = [[Nothing, Nothing, Nothing],
  8. [Nothing, Nothing, Nothing],
  9. [Nothing, Nothing, Nothing]]
  10.  
  11. next :: Player -> Player
  12. next X = O
  13. next O = X
  14.  
  15. diagonal1 :: Grid -> [Maybe Player]
  16. diagonal1 g = [head (head g), g !! 1 !! 1, g !! 2 !! 2]
  17.  
  18. diagonal2 :: Grid -> [Maybe Player]
  19. diagonal2 g = [head g !! 2, g !! 1 !! 1, head (g !! 2)]
  20.  
  21. rows :: Grid -> [[Maybe Player]]
  22. rows g = g
  23.  
  24. columns :: Grid -> [[Maybe Player]]
  25. columns = transpose
  26.  
  27. transpose :: Grid -> Grid
  28. transpose g = [[g !! j !! i | j <- [0..2]] | i <- [0..2]]
  29.  
  30. wonBy :: Grid -> Maybe Player
  31. wonBy g = case filter (all (== Just X)) (rows g ++ columns g ++ [diagonal1 g, diagonal2 g]) of
  32. [_] -> Just X
  33. _ -> case filter (all (== Just O)) (rows g ++ columns g ++ [diagonal1 g, diagonal2 g]) of
  34. [_] -> Just O
  35. _ -> Nothing
  36.  
  37. play :: Grid -> Player -> IO ()
  38. play g p = do putStrLn (render g)
  39. if wonBy g == Just X then putStrLn "X won!"
  40. else if wonBy g == Just O then putStrLn "O won!"
  41. else if all (all isJust) g then putStrLn "It's a draw!"
  42. else do putStr "Enter row: "
  43. hFlush stdout
  44. row <- readLn
  45. putStr "Enter column: "
  46. hFlush stdout
  47. col <- readLn
  48. let g' = update g row col p
  49. if g' == g then do
  50. putStrLn "Invalid move, try again."
  51. play g p
  52. else play g' (next p)
  53.  
  54. update :: Grid -> Int -> Int -> Player -> Grid
  55. update g row col p =
  56. let (before, this:after) = splitAt row g
  57. (before', _:after') = splitAt col this
  58. in before ++ [before' ++ [Just p] ++ after'] ++ after
  59.  
  60. isJust :: Maybe a -> Bool
  61. isJust (Just _) = True
  62. isJust _ = False
  63.  
  64. render :: Grid -> String
  65. render g = unlines [[case g !! i !! j of
  66. Just X -> 'X'
  67. Just O -> 'O'
  68. Nothing -> ' ' | j <- [0..2]] | i <- [0..2]]
  69.  
  70. main :: IO ()
  71. main = do putStrLn "Tic Tac Toe!"
  72. play initialGrid X
  73.  
  74.  
Add Comment
Please, Sign In to add comment