Completando el proyecto con IEx y Mix
Clase 3 de 11 • Curso de Elixir: Modularización, Testing y Estructuras de Datos
Contenido del curso
Clase 3 de 11 • Curso de Elixir: Modularización, Testing y Estructuras de Datos
Contenido del curso
Juan David Gaviria Agudelo
Ernesto Gabriel Mejía Montero
Excelente clase!!!
Les comparto mi solución para aceptar palabras.
El juego considera aciertos y fallos por letra, no por palabra. Es decir, si ingresas una palabra con 5 letras, de las cuales ninguna está en la palabra a adivinar, entonces se te agotarían los intentos y pierdes el juego.
Una mejora sería no incluir letras repetidas en las listas ¨misses¨ y ¨matches¨, que actualmente ocurre cuando ingresas una palabra que tiene letras repetidas, como por ejemplo ¨Cachapa¨.
El código:
defmodule Hangman do @moduledoc """ The famous Hangman game """ @doc """ Starts the game """ def start_game do state = %{word: "hangman", misses: [], matches: [], limit: 5, mask: "_", completed?: false} format_response(state) end @doc """ Lets the user to take a guess """ def take_a_guess( guess_value, %{limit: limit, completed?: false, matches: matches, misses: misses} = state ) when limit > 0 do repeated_values = matches ++ misses guess_as_list = guess_value |> String.downcase() |> String.graphemes() |> Enum.filter(&(&1 not in repeated_values)) case guess_as_list do [] -> format_response(state, :err) _ -> guess_as_list |> guess(state) |> format_response() end end def take_a_guess(_, state), do: format_response(state) ## Helpers defp format_response(%{limit: limit, completed?: false} = state) when limit > 0 do {mask_word(state), state} end defp format_response(%{limit: limit, word: word} = state) when limit > 0 do {"You won, word was: #{word}", state} end defp format_response(%{word: word} = state) do {"Game over, word was: #{word}", state} end defp format_response(state, :err) do {"Please don't use repeated letters", state} end defp mask_word(%{matches: [], word: word, mask: mask} = _state) do String.replace(word, ~r/./, mask) end defp mask_word(%{matches: matches, word: word, mask: mask} = _state) do String.replace(word, ~r/[^#{to_string(matches)}]/, mask) end defp guess(guess_value, state) do Enum.reduce(guess_value, state, fn curr, acc -> %{word: word, matches: matches, misses: misses, limit: limit} = acc if String.contains?(word, curr) do matches = [curr | matches] completed? = word |> String.graphemes() |> Enum.all?(&(&1 in matches)) %{acc | matches: matches, completed?: completed?} else %{acc | misses: [curr | misses], limit: limit - 1} end end) end end quote do end