Advertisement
Guest User

Untitled

a guest
Dec 20th, 2014
175
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.73 KB | None | 0 0
  1. {-
  2. Curso Haskell para iniciantes
  3.  
  4. Jogo da Velha
  5. -}
  6.  
  7. import Control.Exception
  8. import System.IO
  9. import System.IO.Error
  10. import System.Process
  11. import Data.List
  12.  
  13.  
  14. -- definição dos tipos dos dados
  15. type Jogadores = [Jogador]
  16. type Nome = String
  17. type Pontuacao = Int
  18. type Vez = Int
  19. type Tabela = [Char]
  20. data Jogador = Jogador Nome Pontuacao
  21. deriving (Show, Read)
  22.  
  23.  
  24. -- função que recebe uma String e retorna uma IO String
  25. getString :: String -> IO String
  26. getString str = do
  27. putStr str
  28. res <- getLine
  29. return res
  30.  
  31.  
  32. -- função que inicia o programa
  33. inicio :: IO ()
  34. inicio = do
  35. {catch (ler_arquivo) tratar_erro;}
  36. where
  37. -- tenta ler o arquivo
  38. ler_arquivo = do
  39. {
  40. arq <- openFile "dados.txt" ReadMode; -- abre o arquivo para leitura
  41. dados <- hGetLine arq; -- ler o conteúdo do arquivo
  42. hClose arq; -- fecha o arquivo
  43. menu (read dados); -- passa os dados para a função menu
  44. return ()
  45. }
  46. tratar_erro erro = if isDoesNotExistError erro then do
  47. {
  48. -- se o arquivo NÃO existir, então cria o arquivo
  49. arq <- openFile "dados.txt" WriteMode; -- abre o arquivo para escrita
  50. hPutStrLn arq "[]"; -- escreve uma lista vazia no arquivo
  51. hClose arq; -- fecha o arquivo
  52. menu []; -- passa uma lista vazia para o menu
  53. return ()
  54. }
  55. else
  56. ioError erro
  57.  
  58.  
  59. -- função que exibe o Menu
  60. menu :: Jogadores -> IO Jogadores
  61. menu dados = do
  62. system "cls" -- limpa a tela (windows somente)
  63. putStrLn "-------------------------------- Jogo da Velha --------------------------------"
  64. putStrLn "\nDigite 1 para cadastrar jogador"
  65. putStrLn "Digite 2 para jogar"
  66. putStrLn "Digite 3 para visualizar o ranking"
  67. putStrLn "Digite 0 para sair"
  68. putStr "Opção: "
  69. op <- getChar
  70. getChar -- descarta o Enter
  71. executarOpcao dados op
  72.  
  73.  
  74. -- função para manipular a opção escolhida pelo usuário
  75. executarOpcao :: Jogadores -> Char -> IO Jogadores
  76. executarOpcao dados '1' = cadastrarJogador dados
  77. executarOpcao dados '2' = prepararJogo dados
  78. executarOpcao dados '0' = do
  79. putStrLn ("\nBye! Visite: www.GeeksBR.com ;-)\n")
  80. return dados
  81. executarOpcao dados _ = do
  82. putStrLn ("\nOpção inválida! Tente novamente...")
  83. putStr "\nPressione <Enter> para voltar ao menu..."
  84. getChar
  85. menu dados
  86.  
  87.  
  88. -- função responsável pelo cadastro de jogadores
  89. cadastrarJogador :: Jogadores -> IO Jogadores
  90. cadastrarJogador dados = do
  91. nome <- getString "\nDigite um nome de usuário: "
  92. if (existeJogador dados nome) then do
  93. putStrLn "\nEsse nome já existe, escolha outro."
  94. putStr "\nPressione <Enter> para continuar..."
  95. getChar
  96. menu dados
  97. else do
  98. arq <- openFile "dados.txt" WriteMode -- abre o arquivo para escrita
  99. hPutStrLn arq (show ((Jogador nome 0):dados))
  100. hClose arq -- fecha o arquivo
  101. putStrLn ("\nUsuário " ++ nome ++ " cadastrado com sucesso.")
  102. putStr "\nPressione <Enter> para continuar..."
  103. getChar
  104. menu ((Jogador nome 0):dados) -- retorna a nova lista para o menu
  105.  
  106.  
  107. -- função que verifica se um jogador existe (o nome do jogador é único)
  108. existeJogador :: Jogadores -> Nome -> Bool
  109. existeJogador [] _ = False
  110. existeJogador ((Jogador n p):xs) nome
  111. | (n == nome) = True
  112. | otherwise = existeJogador xs nome
  113.  
  114.  
  115. -- função que prepara o início do jogo
  116. prepararJogo :: Jogadores -> IO Jogadores
  117. prepararJogo dados = do
  118. jogador1 <- getString "\nDigite o nome do primeiro jogador: "
  119. -- testa se o jogador1 existe
  120. if not (existeJogador dados jogador1) then do
  121. putStrLn "\nEsse jogador não existe!"
  122. putStr "\nPressione <Enter> para continuar..."
  123. getChar -- descarta o Enter
  124. menu dados
  125. else do
  126. jogador2 <- getString "\nDigite o nome do segundo jogador: "
  127. if not (existeJogador dados jogador2) then do
  128. putStrLn "\nEsse jogador não existe!"
  129. putStr "\nPressione <Enter> para continuar..."
  130. getChar -- descarta o Enter
  131. menu dados
  132. else do
  133. -- se chegou aqui, é porque os dois jogadores existem
  134. novoJogo dados jogador1 jogador2
  135.  
  136.  
  137. -- função que inicia um novo jogo
  138. novoJogo :: Jogadores -> Nome -> Nome -> IO Jogadores
  139. novoJogo dados jogador1 jogador2 = do
  140. putStrLn ("\nIniciando o jogo \"" ++
  141. jogador1 ++ " vs " ++ jogador2 ++ "\" ... ")
  142. putStrLn ("\nOs quadrados que possuem números NÃO estão marcados.")
  143. putStrLn ("\n" ++ jogador1 ++ " será o \'X\' e " ++ jogador2 ++ " será o \'O\'. Vamos lá!!")
  144. {-
  145. A configuração inicial do tabuleiro é
  146. ['1', '2', '3', '4', '5', '6', '7', '8', '9']
  147. Numeração da esquerda para direita e de cima para baixo
  148. Exemplo:
  149. 1 | 2 | 3
  150. -----------
  151. 4 | 5 | 6
  152. -----------
  153. 7 | 8 | 9
  154. -}
  155. -- passa os dados, a configuração inicial, os jogadores e uma flag que indica de quem é
  156. -- a vez: 0 quer dizer que a vez é do jogador1 e 1 quer dizer que a vez é do jogador2
  157. rodarJogo dados ['1', '2', '3', '4', '5', '6', '7', '8', '9'] jogador1 jogador2 0
  158.  
  159.  
  160. -- função que exibe o tabuleiro do jogo da velha
  161. -- recebe a lista de jogadores, a tabela, o nome do jogador1, do jogador2 e um inteiro indicando de quem é a vez
  162. rodarJogo :: Jogadores -> Tabela -> Nome -> Nome -> Vez -> IO Jogadores
  163. rodarJogo dados tabela jogador1 jogador2 vez = do
  164. -- imprime o tabuleiro
  165. putStrLn ("\n" ++ " " ++
  166. (show (tabela !! 0)) ++ " | " ++ (show (tabela !! 1)) ++ " | " ++ (show (tabela !! 2)) ++
  167. "\n ---------------\n" ++ " " ++
  168. (show (tabela !! 3)) ++ " | " ++ (show (tabela !! 4)) ++ " | " ++ (show (tabela !! 5)) ++
  169. "\n ---------------\n" ++ " " ++
  170. (show (tabela !! 6)) ++ " | " ++ (show (tabela !! 7)) ++ " | " ++ (show (tabela !! 8)) ++
  171. "\n")
  172. -- verifica se o jogador1 venceu
  173. if (venceuJogador1 tabela) then do
  174. putStrLn ("Parábens " ++ jogador1 ++ "! Você venceu!!")
  175.  
  176. -- abre o arquivo para escrita para atualizá-lo
  177. arq_escrita <- openFile "dados.txt" WriteMode
  178. hPutStrLn arq_escrita (show (atualizaPontuacao dados jogador1))
  179. hClose arq_escrita
  180.  
  181. -- abre o arquivo para leitura
  182. arq_leitura <- openFile "dados.txt" ReadMode
  183. dados_atualizados <- hGetLine arq_leitura
  184. hClose arq_leitura
  185.  
  186. putStr "\nPressione <Enter> para voltar ao menu..."
  187. getChar
  188. menu (read dados_atualizados)
  189. else do
  190. -- verifica se o jogador2 venceu
  191. if (venceuJogador2 tabela) then do
  192. putStrLn ("Parábens " ++ jogador2 ++ "! Você venceu!!")
  193.  
  194. -- abre o arquivo para escrita para atualizá-lo
  195. arq_escrita <- openFile "dados.txt" WriteMode
  196. hPutStrLn arq_escrita (show (atualizaPontuacao dados jogador2))
  197. hClose arq_escrita
  198.  
  199. -- abre o arquivo para leitura
  200. arq_leitura <- openFile "dados.txt" ReadMode
  201. dados_atualizados <- hGetLine arq_leitura
  202. hClose arq_leitura
  203.  
  204. putStr "\nPressione <Enter> para voltar ao menu..."
  205. getChar
  206. menu (read dados_atualizados)
  207. else do
  208. -- verifica se houve empate
  209. -- se o tamanho da intersecção entre "123456789" e "tabela" for 0, então deu empate
  210. if ((length (intersect "123456789 tabela")) == 0) then do
  211. putStrLn ("Deu empate!")
  212. putStr "\nPressione <Enter> para voltar ao menu..."
  213. getChar
  214. menu dados
  215. else do
  216. -- verifica se a vez é do jogador1
  217. if (vez == 0) then do
  218. putStr (jogador1 ++ ", é a sua vez! Onde você quer marcar?")
  219. op <- getChar
  220. getChar -- descarta o Enter
  221. -- testa se a opção é válida
  222. if not (elem op "123456789") then do
  223. putStrLn "\nEssa opção NÃO é válida, tente novamente..."
  224. -- como foi opção inválida, então ainda é a vez do jogador1
  225. rodarJogo dados tabela jogador1 jogador2 0
  226. else
  227. -- se caiu aqui, então é uma opção válida
  228. -- testa se a opção já foi marcada
  229. -- se ela não existir na tabela, é porque já foi marcada
  230. if not (elem op tabela) then do
  231. putStrLn "\nEssa opção já foi marcada, escolha outra opção..."
  232. rodarJogo dados tabela jogador1 jogador2 0
  233. else
  234. -- se caiu aqui é porque a opção é válida e ainda NÃO foi marcada
  235. -- passa 1 para indicar que a vez é do jogador2
  236. -- a nova tabela será o retorno da função obterNovoTabuleiro
  237. rodarJogo dados (obterNovoTabuleiro tabela vez op) jogador1 jogador2 1
  238. else do
  239. putStr (jogador2 ++ ", é a sua vez! Onde você quer marcar?")
  240. op <- getChar
  241. getChar -- descarta o Enter
  242. if not (elem op "123456789") then do
  243. putStrLn "\nEssa opção NÃO é válida, tente novamente..."
  244. -- como foi opção inválida, então ainda é a vez do jogador2
  245. rodarJogo dados tabela jogador1 jogador2 1
  246. else
  247. if not (elem op tabela) then do
  248. putStrLn "\nEssa opção já foi marcada, escolha outra opção..."
  249. rodarJogo dados tabela jogador1 jogador2 1
  250. else
  251. -- se caiu aqui é porque a opção é válida e ainda NÃO foi marcada
  252. -- passa 0 para indicar que a vez é do jogador1
  253. -- a nova tabela será o retorno da função obterNovoTabuleiro
  254. rodarJogo dados (obterNovoTabuleiro tabela vez op) jogador1 jogador2 0
  255.  
  256.  
  257. -- essa função recebe uma lista com a configuração do tabuleiro,
  258. -- a vez, um elemento (opção escolhida pelo jogador), retorna uma nova configuração (nova lista)
  259. obterNovoTabuleiro :: Tabela -> Vez -> Char -> Tabela
  260. obterNovoTabuleiro (x:xs) vez e
  261. | ((x == e) && (vez == 0)) = (['X'] ++ xs)
  262. | ((x == e) && (vez == 1)) = (['O'] ++ xs)
  263. | otherwise = x:(obterNovoTabuleiro xs vez e)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement