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:
defmoduleHangmando@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
"""deftake_a_guess( guess_value,%{limit: limit,completed?:false,matches: matches,misses: misses}= state
)when limit >0do repeated_values = matches ++ misses
guess_as_list = guess_value
|>String.downcase()|>String.graphemes()|>Enum.filter(&(&1notin repeated_values))case guess_as_list do[]->format_response(state,:err) _ -> guess_as_list
|>guess(state)|>format_response()endenddeftake_a_guess(_, state),do:format_response(state)## Helpersdefpformat_response(%{limit: limit,completed?:false}= state)when limit >0do{mask_word(state), state}enddefpformat_response(%{limit: limit,word: word}= state)when limit >0do{"You won, word was: #{word}", state}enddefpformat_response(%{word: word}= state)do{"Game over, word was: #{word}", state}enddefpformat_response(state,:err)do{"Please don't use repeated letters", state}enddefpmask_word(%{matches:[],word: word,mask: mask}= _state)doString.replace(word,~r/./, mask)enddefpmask_word(%{matches: matches,word: word,mask: mask}= _state)doString.replace(word,~r/[^#{to_string(matches)}]/, mask)enddefpguess(guess_value, state)doEnum.reduce(guess_value, state,fn curr, acc ->%{word: word,matches: matches,misses: misses,limit: limit}= acc
ifString.contains?(word, curr)do matches =[curr | matches] completed? = word |>String.graphemes()|>Enum.all?(&(&1in matches))%{acc |matches: matches,completed?: completed?}else%{acc |misses:[curr | misses],limit: limit -1}endend)endendquotedoend