{"id":5256,"date":"2016-01-08T16:54:16","date_gmt":"2016-01-08T15:54:16","guid":{"rendered":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/?p=5256"},"modified":"2016-01-09T11:57:57","modified_gmt":"2016-01-09T10:57:57","slug":"i1m2015-el-juego-del-nim-y-las-funciones-de-entradasalida","status":"publish","type":"post","link":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/i1m2015-el-juego-del-nim-y-las-funciones-de-entradasalida\/","title":{"rendered":"I1M2015: El juego del Nim y las funciones de entrada\/salida"},"content":{"rendered":"<p>En la segunda parte de la clase de hoy de <a href=\"http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\">Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas<\/a> hemos comentado las soluciones a los ejercicios de la relaci\u00f3n 15 sobre el uso de acciones de entrada y salida en el juego del Nim.<\/p>\n<p>Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<br \/>\n<!--more--><\/p>\n<pre lang=\"haskell\">\n------------------------------------------------------------------------\n-- \u00a7 Introducci\u00f3n                                                     --\n------------------------------------------------------------------------\n\n-- En el juego del nim el tablero tiene 5 filas numeradas de estrellas,\n-- cuyo contenido inicial es el siguiente \n--    1: \u2217\u2217\u2217\u2217\u2217\n--    2: \u2217\u2217\u2217\u2217\n--    3: \u2217\u2217\u2217\n--    4: \u2217\u2217\n--    5: \u2217\n-- Dos jugadores retiran por turno una o m\u00e1s estrellas de una fila. El\n-- ganador es el jugador que retire la \u00faltima estrella. En este\n-- ejercicio se va implementar el juego del Nim para practicar con las\n-- funciones de entrada y salida estudiadas en el tema 13 cuyas\n-- transparencias se encuentran en\n--    http:\/\/www.cs.us.es\/~jalonso\/cursos\/i1m-15\/temas\/tema-13.html\n--\n-- Nota: El juego debe de ejecutarse en una consola, no en la shell de\n-- emacs. \n\n-- ---------------------------------------------------------------------\n-- \u00a7 Librer\u00edas auxiliares                                             --\n-- ---------------------------------------------------------------------\n\nimport Data.Char\n\n-- ---------------------------------------------------------------------\n-- \u00a7 Representaci\u00f3n                                                   --\n-- ---------------------------------------------------------------------\n \n-- El tablero se representar\u00e1 como una lista de n\u00fameros indicando el\n-- n\u00famero de estrellas de cada fila. Con esta representaci\u00f3n, el tablero\n-- inicial es [5,4,3,2,1]. \n\n-- Representaci\u00f3n del tablero.\ntype Tablero = [Int]\n\n-- inicial es el tablero al principio del juego.\ninicial ::  Tablero\ninicial = [5,4,3,2,1]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 1. Definir la funci\u00f3n\n--    finalizado :: Tablero -> Bool\n-- tal que (finalizado t) se verifica si t es el tablero de un juego\n-- finalizado; es decir, sin estrellas. Por ejemplo,\n--    finalizado [0,0,0,0,0]  ==  True\n--    finalizado [1,3,0,0,1]  ==  False\n-- ---------------------------------------------------------------------\n\nfinalizado :: Tablero -> Bool\nfinalizado = all (== 0)\n\n-- ---------------------------------------------------------------------\n-- Ejecicio 2.2. Definir la funci\u00f3n\n--    valida :: Tablero -> Int -> Int -> Bool\n-- tal que (valida t f n) se verifica si se puede coger n estrellas en\n-- la fila f del tablero t y n es mayor o igual que 1. Por ejemplo,\n--    valida [4,3,2,1,0] 2 3  ==  True\n--    valida [4,3,2,1,0] 2 4  ==  False\n--    valida [4,3,2,1,0] 2 2  ==  True\n--    valida [4,3,2,1,0] 2 0  ==  False\n-- ---------------------------------------------------------------------\n\nvalida :: Tablero -> Int -> Int -> Bool\nvalida t f n = (n >= 1) && (t !! (f-1) >= n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 3. Definir la funci\u00f3n\n--    jugada :: Tablero -> Int -> Int -> Tablero\n-- tal que (jugada t f n) es el tablero obtenido a partir de t\n-- eliminando n estrellas de la fila f. Por ejemplo,\n--    jugada [4,3,2,1,0] 2 1  ==  [4,2,2,1,0]\n-- ---------------------------------------------------------------------\n\njugada :: Tablero -> Int -> Int -> Tablero\njugada t f n = [if x == f then y-n else y | (x,y) <- zip [1..5] t]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 4. Definir la acci\u00f3n\n--    nuevaLinea :: IO ()\n-- que consiste en escribir una nueva l\u00ednea. Por ejemplo,\n--    ghci> nuevaLinea\n--    \n--    ghci> \n-- ---------------------------------------------------------------------\n\nnuevaLinea :: IO ()\nnuevaLinea = putChar '\\n'\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 5. Definir la funci\u00f3n\n--    estrellas :: Int -> String\n-- tal que (estrellas n) es la cadena formada con n estrellas. Por\n-- ejemplo, \n--    ghci> estrellas 3\n--    \"* * * \"\n-- ---------------------------------------------------------------------\n\nestrellas :: Int -> String\nestrellas n = concat (replicate n \"* \")\n                              \n-- ---------------------------------------------------------------------\n-- Ejercicio 6. Definir la acci\u00f3n\n--    escribeFila :: Int -> Int -> IO ()\n-- tal que (escribeFila f n) escribe en la fila f n estrellas. Por\n-- ejemplo, \n--    ghci> escribeFila 2 3\n--    2: * * *\n-- ---------------------------------------------------------------------\n \nescribeFila :: Int -> Int -> IO ()\nescribeFila f n = do putStr (show f)\n                     putStr \": \"\n                     putStrLn (estrellas n)\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 7. Definir la acci\u00f3n\n--    escribeTablero :: Tablero -> IO ()\n-- tal que (escribeTablero t) escribe el tablero t. Por\n-- ejemplo,\n--    ghci> escribeTablero [3,4,1,0,1]\n--    1: * * * \n--    2: * * * * \n--    3: * \n--    4: \n--    5: * \n-- ---------------------------------------------------------------------\n\nescribeTablero :: Tablero -> IO ()\nescribeTablero t = \n    sequence_ [escribeFila n (t!!(n-1)) | n <- [1..length t]]\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 8. Definir la acci\u00f3n\n--    leeDigito :: String -> IO Int\n-- tal que (leeDigito c) escribe una nueva l\u00ednea con la cadena \"prueba\",\n-- lee un car\u00e1cter y comprueba que es un d\u00edgito. Adem\u00e1s, si el car\u00e1cter\n-- leido es un d\u00edgito entonces devuelve el entero correspondiente y si\n-- no lo es entonces escribe el mensaje \"Entrada incorrecta\" y vuelve a\n-- leer otro car\u00e1cter. Por ejemplo,  \n--    ghci> leeDigito \"prueba \"\n--    prueba 3\n--    3\n--    ghci> leeDigito \"prueba \"\n--    prueba c\n--    ERROR: Entrada incorrecta\n--    prueba 3\n--    3\n-- ---------------------------------------------------------------------\n\nleeDigito :: String -> IO Int\nleeDigito c = do putStr c\n                 x <- getChar\n                 nuevaLinea\n                 if isDigit x\n                    then return (digitToInt x)\n                    else do putStrLn \"ERROR: Entrada incorrecta\"\n                            leeDigito c\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 9. Los jugadores se representan por los n\u00fameros 1 y 2.\n-- Definir la funci\u00f3n \n--    siguiente :: Int -> Int\n-- tal que (siguiente j) es el jugador siguiente de j. \n-- ---------------------------------------------------------------------\n\nsiguiente :: Int -> Int\nsiguiente 1 = 2\nsiguiente 2 = 1\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 10. Definir la acci\u00f3n\n--    juego :: Tablero -> Int -> IO ()\n-- tal que (juego t j) es el juego a partir del tablero t y el turno del\n-- jugador j. Por ejemplo,\n--    ghci> juego [0,1,0,1,0] 2\n--    \n--    1: \n--    2: * \n--    3: \n--    4: * \n--    5: \n--    \n--    J 2\n--    Elige una fila: 2\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: \n--    2: \n--    3: \n--    4: * \n--    5: \n--    \n--    J 1\n--    Elige una fila: 4\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: \n--    2: \n--    3: \n--    4: \n--    5: \n--    \n--    J 1 He ganado\n-- ---------------------------------------------------------------------\n\njuego :: Tablero -> Int -> IO ()\njuego t j = do nuevaLinea\n               escribeTablero t\n               if finalizado t \n                then do nuevaLinea\n                        putStr \"J \"\n                        putStr (show (siguiente j))\n                        putStrLn \" He ganado\"\n                else do nuevaLinea\n                        putStr \"J \"\n                        putStrLn (show j)\n                        f <- leeDigito \"Elige una fila: \"\n                        n <- leeDigito \"Elige cuantas estrellas retiras: \"\n                        if valida t f n \n                         then juego (jugada t f n) (siguiente j)\n                         else do nuevaLinea\n                                 putStrLn \"ERROR: jugada incorrecta\"\n                                 juego t j\n\n-- ---------------------------------------------------------------------\n-- Ejercicio 11. Definir la acci\u00f3n\n--    nim :: IO ()\n-- consistente en una partida del nim. Por ejemplo (en una consola no en\n-- la shell de emacs),\n--    ghci> nim\n--    \n--    1: * * * * * \n--    2: * * * * \n--    3: * * * \n--    4: * * \n--    5: * \n--    \n--    J 1\n--    Elige una fila: 1\n--    Elige cuantas estrellas retiras: 4\n--    \n--    1: * \n--    2: * * * * \n--    3: * * * \n--    4: * * \n--    5: * \n--    \n--    J 2\n--    Elige una fila: 3\n--    Elige cuantas estrellas retiras: 3\n--    \n--    1: * \n--    2: * * * * \n--    3: \n--    4: * * \n--    5: * \n--    \n--    J 1\n--    Elige una fila: 2\n--    Elige cuantas estrellas retiras: 4\n--    \n--    1: * \n--    2: \n--    3: \n--    4: * * \n--    5: * \n--    \n--    J 2\n--    Elige una fila: 4\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: * \n--    2: \n--    3: \n--    4: * \n--    5: * \n--    \n--    J 1\n--    Elige una fila: 1\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: \n--    2: \n--    3: \n--    4: * \n--    5: * \n--    \n--    J 2\n--    Elige una fila: 4\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: \n--    2: \n--    3: \n--    4: \n--    5: * \n--    \n--    J 1\n--    Elige una fila: 5\n--    Elige cuantas estrellas retiras: 1\n--    \n--    1: \n--    2: \n--    3: \n--    4: \n--    5: \n--    \n--    J 1 He ganado\n-- ---------------------------------------------------------------------\n\nnim :: IO ()\nnim = juego inicial 1\n<\/pre>\n<p>El c\u00f3digo anterior se encuentra tambi\u00e9n en <a href=\"https:\/\/github.com\/jaalonso\/I1M-Ejercicios\/blob\/master\/Ejercicios\/Rel_15_sol.hs\">GitHub<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la segunda parte de la clase de hoy de Inform\u00e1tica de 1\u00ba del Grado en Matem\u00e1ticas hemos comentado las soluciones a los ejercicios de la relaci\u00f3n 15 sobre el uso de acciones de entrada y salida en el juego del Nim. Los ejercicios y su soluci\u00f3n se muestran a continuaci\u00f3n<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false},"categories":[250],"tags":[270,310],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":false,"_links":{"self":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5256"}],"collection":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/comments?post=5256"}],"version-history":[{"count":2,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5256\/revisions"}],"predecessor-version":[{"id":5258,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/posts\/5256\/revisions\/5258"}],"wp:attachment":[{"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/media?parent=5256"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/categories?post=5256"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.glc.us.es\/~jalonso\/vestigium\/wp-json\/wp\/v2\/tags?post=5256"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}