Terminei meu aplicativo Python Hangman com um código muito básico.
import random import sys # lets set some variables wordList = [ "lion", "umbrella", "window", "computer", "glass", "juice", "chair", "desktop", "laptop", "dog", "cat", "lemon", "cabel", "mirror", "hat" ] guess_word = [] secretWord = random.choice(wordList) # lets randomize single word from the list length_word = len(secretWord) alphabet = "abcdefghijklmnopqrstuvwxyz" letter_storage = [] def beginning(): print("Hello Mate!\n") while True: name = input("Please enter Your name\n").strip() if name == "": print("You can"t do that! No blank lines") else: break beginning() def newFunc(): print("Well, that"s perfect moment to play some Hangman!\n") while True: gameChoice = input("Would You?\n").upper() if gameChoice == "YES" or gameChoice == "Y": break elif gameChoice == "NO" or gameChoice == "N": sys.exit("That"s a shame! Have a nice day") else: print("Please Answer only Yes or No") continue newFunc() def change(): for character in secretWord: # printing blanks for each letter in secret word guess_word.append("-") print("Ok, so the word You need to guess has", length_word, "characters") print("Be aware that You can enter only 1 letter from a-z\n\n") print(guess_word) def guessing(): guess_taken = 1 while guess_taken < 10: guess = input("Pick a letter\n").lower() if not guess in alphabet: #checking input print("Enter a letter from a-z alphabet") elif guess in letter_storage: #checking if letter has been already used print("You have already guessed that letter!") else: letter_storage.append(guess) if guess in secretWord: print("You guessed correctly!") for x in range(0, length_word): #This Part I just don"t get it if secretWord[x] == guess: guess_word[x] = guess print(guess_word) if not "-" in guess_word: print("You won!") break else: print("The letter is not in the word. Try Again!") guess_taken += 1 if guess_taken == 10: print(" Sorry Mate, You lost :<! The secret word was", secretWord) change() guessing() print("Game Over!")
Então, eu tenho algumas perguntas sobre meu código:
-
Eu comecei a aprender algumas coisas sobre classes em Python e pensei “Ei, vamos escrever este Hangman with Classes ” s tudo. Existe algum bom motivo para usar as classes em um jogo Hangman?
-
Sei que o código é muito básico e, no meu nível, não deveria me importar exatamente com a eficácia de o código, mas ainda – qual parte deve ser melhorada (não o código em si, mas minha lógica lá)? Quero escrever de uma maneira “adequada”, mas meu código ainda parece super básico.
Resposta
Jogabilidade
Executei seu jogo para testá-lo primeiro e notei algo estranho quando uma letra está encontrado duas vezes na mesma palavra, como ” vidro ” aqui:
Pick a letter A You guessed correctly! ["-", "-", "a", "-", "-"] Pick a letter s You guessed correctly! ["-", "-", "a", "s", "-"] ["-", "-", "a", "s", "s"]
Não tenho certeza se é intencional, mas como jogador acho estranho que “é exibido duas vezes. Encontrei sua origem no código:
for x in range(0, length_word): #This Part I just don"t get it if secretWord[x] == guess: guess_word[x] = guess print(guess_word)
Se você apenas desfazer o recuo print(guess_word)
por dois níveis, você evitará esse comportamento, uma vez que não será executado em um loop:
for i in range(0, length_word): if secretWord[i] == guess: guess_word[i] = guess print(guess_word)
Imprimir uma matriz bruta como ["-", "-", "a", "s", "s"]
é um pouco confuso, a princípio eu não sabia o que era pois até adivinhar um certo e ver os resultados. Portanto, vamos imprimir algo mais amigável:
print("Word to guess: {0}".format(" ".join(guess_word)))
Pick a letter o You guessed correctly! Word to guess: - o -
Muito melhor! Mas ficará um pouco complicado digitar tudo isso a cada vez, então vamos criar uma função de utilidade para isso e podemos usá-la para o print(guess_word)
no início de um jogo também.
def print_word_to_guess(letters): """Utility function to print the current word to guess""" print("Word to guess: {0}".format(" ".join(guess_word)))
Então nós apenas print_word_to_guess(guess_word)
sempre que precisarmos. Também seria possível fazer uma mensagem opcional diferente, mas o padrão para , mas deixarei isso para você como um desafio.
O jogo também nunca me diz nada sobre quantas chances ainda tenho, então fico adivinhando (literalmente) até descobrir. É muito fácil fazer uma pequena função de utilidade:
def print_guesses_taken(current, total): """Prints how many chances the player has used""" print("You are on guess {0}/{1}.".format(current, total))
Em seguida, algumas adições de código:
def guessing(): guess_taken = 1 MAX_GUESS = 10 print_guesses_taken(guess_taken, MAX_GUESS) while guess_taken < MAX_GUESS:
E:
for i in range(0, length_word): if secretWord[i] == guess: guess_word[i] = guess print_word_to_guess(guess_word) print_guesses_taken(guess_taken, MAX_GUESS)
Sua lista de palavras é bastante limitada, no futuro, considere procurar um arquivo de texto online com um monte de palavras e apenas ler um aleatório dele, que traria mais variedade!
Melhorias de código
main
função
Você executa todo o seu jogo funciona assim que você os faz. Faria mais sentido colocá-los dentro da função __main__
:
if __name__ == "__main__": beginning() newFunc() change() guessing()
A propósito, newFunc()
não funciona bem como nome, pois não diz nada sobre o que faz. Algo como ask_user_to_play()
seria muito melhor.
Nomenclatura de constantes
Python não tem constantes reais, mas, no entanto, é uma boa prática nomear variáveis que não devem ser alteradas (por alteração, quero dizer reatribuídas a valores diferentes) em ALL_CAPS_WITH_UNDERSCORES. Um simples localizar & substituir em um IDE ou editor de texto resolve todo o seu script.
GUESS_WORD = [] SECRET_WORD = random.choice(wordList) # lets randomize single word from the list LENGTH_WORD = len(SECRET_WORD) ALPHABET = "abcdefghijklmnopqrstuvwxyz" letter_storage = []
Docstring
É “um bom hábito adicionar um docstring a todas as funções, classes e módulos, para descrever para outros programadores para que serve o código em questão. Eu fiz isso para a função de utilidade 2 acima.
Dicas de tipo
Desde o Python 3, agora você pode usar digite dicas para suas assinaturas de função e método e use ferramentas de análise de código estático. Isso também torna o código mais fácil de ler para humanos.
Código aprimorado
Aqui está o que eu criei, aplicando todos os itens acima e melhorando o espaçamento ( o seu tinha muitas linhas em branco em todos os lugares). Provavelmente, há outras coisas que poderiam ser melhoradas, mas este deve ser um bom começo.
import random, sys from typing import List # TODO try to load these from a text file WORD_LIST = [ "lion", "umbrella", "window", "computer", "glass", "juice", "chair", "desktop", "laptop", "dog", "cat", "lemon", "cabel", "mirror", "hat" ] GUESS_WORD = [] SECRET_WORD = random.choice(WORD_LIST) # lets randomize single word from the list LENGTH_WORD = len(SECRET_WORD) ALPHABET = "abcdefghijklmnopqrstuvwxyz" letter_storage = [] # Utility functions def print_word_to_guess(letters: List) -> None: """Utility function to print the current word to guess""" print("Word to guess: {0}".format(" ".join(letters))) def print_guesses_taken(current: int, total: int) -> None: """Prints how many chances the player has used""" print("You are on guess {0}/{1}.".format(current, total)) # Game functions def beginning() -> None: """Starts the game""" print("Hello Mate!\n") while True: name = input("Please enter Your name\n").strip() if name == "": print("You can"t do that! No blank lines") else: break def ask_user_to_play() -> None: """Ask user if they want to play""" print("Well, that"s perfect moment to play some Hangman!\n") while True: gameChoice = input("Would You?\n").upper() if gameChoice == "YES" or gameChoice == "Y": break elif gameChoice == "NO" or gameChoice == "N": sys.exit("That"s a shame! Have a nice day") else: print("Please Answer only Yes or No") continue def prepare_secret_word() -> None: """Prepare secret word and inform user of it""" for character in SECRET_WORD: # printing blanks for each letter in secret word GUESS_WORD.append("-") print("Ok, so the word You need to guess has", LENGTH_WORD, "characters") print("Be aware that You can enter only 1 letter from a-z\n\n") print_word_to_guess(GUESS_WORD) def guessing() -> None: """ Main game loop to have user guess letters and inform them of the results """ guess_taken = 1 MAX_GUESS = 10 print_guesses_taken(guess_taken, MAX_GUESS) while guess_taken < MAX_GUESS: guess = input("Pick a letter\n").lower() if not guess in ALPHABET: #checking input print("Enter a letter from a-z ALPHABET") elif guess in letter_storage: #checking if letter has been already used print("You have already guessed that letter!") else: letter_storage.append(guess) if guess in SECRET_WORD: print("You guessed correctly!") for i in range(0, LENGTH_WORD): if SECRET_WORD[i] == guess: GUESS_WORD[i] = guess print_word_to_guess(GUESS_WORD) print_guesses_taken(guess_taken, MAX_GUESS) if not "-" in GUESS_WORD: print("You won!") print("Game Over!") break else: print("The letter is not in the word. Try Again!") guess_taken += 1 print_guesses_taken(guess_taken, MAX_GUESS) if guess_taken == 10: print(" Sorry Mate, You lost :<! The secret word was {0}".format(SECRET_WORD)) if __name__ == "__main__": beginning() ask_user_to_play() prepare_secret_word() guessing()
Comentários
- Não posso ‘ dizer o quanto agradeço sua resposta! Vou analisar todas as suas dicas e me desafiar com elas, obrigado novamente 🙂
- Sem problemas, também me diverti revisando! Espero que você poste mais no futuro =)