Jeg har afsluttet min Python Hangman-app med meget grundlæggende kode.
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!")
Så jeg har nogle spørgsmål til min kode:
-
Jeg er begyndt at læne nogle ting om klasser i Python, og jeg tænkte “Hej, lad os skrive denne Hangman med klasser ) “Men efter nogle kodninger indså jeg, jeg lavede bare klasser med 1 funk og i stedet for
func()
kaldte jeg dem bareclass.func()
og det” s alle. Er der nogen god grund til, hvorfor og hvordan jeg skal bruge klasser i et Hangman-spil? -
Jeg ved, at koden er meget grundlæggende, og på mit niveau skal jeg ikke nøjagtigt tænke på effektiviteten af koden men stadig – Hvilken del skal forbedres (ikke selve koden men min logik der)? Jeg vil skrive på en “ordentlig” måde, men min kode ser stadig super grundlæggende ud.
Svar
Spilbarhed
Jeg kørte dit spil for at teste det først og bemærkede noget underligt, når et bogstav er fundet to gange i det samme ord, såsom ” glas ” her:
Pick a letter A You guessed correctly! ["-", "-", "a", "-", "-"] Pick a letter s You guessed correctly! ["-", "-", "a", "s", "-"] ["-", "-", "a", "s", "s"]
Jeg er ikke sikker på, om det er designet, men som spiller finder jeg det underligt, at det “vises to gange. Jeg fandt, hvor den stammer fra koden:
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)
Hvis du bare fjerner print(guess_word)
ved to niveauer, undgår du denne adfærd, da den ikke løber i en løkke:
for i in range(0, length_word): if secretWord[i] == guess: guess_word[i] = guess print(guess_word)
At udskrive en rå matrix som ["-", "-", "a", "s", "s"]
er lidt forvirrende, først vidste jeg ikke, hvad det var for indtil jeg gættede en ret og så resultaterne. Så lad os få det til at udskrive noget mere venligt:
print("Word to guess: {0}".format(" ".join(guess_word)))
Pick a letter o You guessed correctly! Word to guess: - o -
Meget bedre! Men det bliver lidt klodset at skrive alt det hver gang, så lad os lave en hjælpefunktion til det, og vi kan bruge det til print(guess_word)
også i begyndelsen af et spil.
def print_word_to_guess(letters): """Utility function to print the current word to guess""" print("Word to guess: {0}".format(" ".join(guess_word)))
Så skal vi bare print_word_to_guess(guess_word)
når vi har brug for det. Det ville også være muligt at lave en valgfri anden besked, men som standard er Word to guess:
, men jeg overlader det til dig som en udfordring.
Spillet fortæller mig aldrig nogensinde om, hvor mange chancer jeg har tilbage, så jeg gætter (bogstaveligt talt), indtil jeg finder ud af det. Det er meget nemt at lave en lille hjælpefunktion til at gøre:
def print_guesses_taken(current, total): """Prints how many chances the player has used""" print("You are on guess {0}/{1}.".format(current, total))
Så et par kodetilføjelser:
def guessing(): guess_taken = 1 MAX_GUESS = 10 print_guesses_taken(guess_taken, MAX_GUESS) while guess_taken < MAX_GUESS:
Og:
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)
Din ordliste er ret begrænset, til fremtidig overveje måske at lede efter en tekstfil online med en hel flok ord og bare læse en tilfældig fra den, at ville give mere variation!
Kodeforbedringer
main
-funktion
Du kører hele dit spil fungerer, så snart du opretter dem. Det ville være mere fornuftigt at placere dem i funktionen __main__
:
if __name__ == "__main__": beginning() newFunc() change() guessing()
Forresten fungerer newFunc()
ikke godt som et navn, da det ikke siger noget om, hvad det gør. Noget som ask_user_to_play()
ville være meget bedre.
Konstant navngivning
Python har ikke rigtige konstanter, men alligevel er det god praksis at nævne variabler, der ikke skulle ændre sig (ved ændring mener jeg, at de tildeles forskellige værdier) i ALL_CAPS_WITH_UNDERSCORES. Et simpelt fund & udskiftes i en IDE eller teksteditor gør tricket for at rette hele scriptet.
GUESS_WORD = [] SECRET_WORD = random.choice(wordList) # lets randomize single word from the list LENGTH_WORD = len(SECRET_WORD) ALPHABET = "abcdefghijklmnopqrstuvwxyz" letter_storage = []
Docstring
Det er en god vane at tilføje en docstring til alle funktioner, klasser og moduler for at beskrive for andre programmører, hvad den pågældende kode er til. Jeg har gjort det for ovenstående funktion 2.
Skriv tip
Siden Python 3 kan du nu bruge skriv tip til dine funktions- og metodesignaturer, og brug værktøjer til analyse af statisk kode. Dette gør koden også lettere at læse for mennesker.
Forbedret kode
Her er hvad jeg kom på, anvendte alle ovenstående og forbedrede afstanden ( din havde for mange tomme linjer overalt). Der er sandsynligvis andre ting, der kunne forbedres, men dette skulle være en god start.
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()
Kommentarer
- Jeg kan ‘ ikke fortælle, hvor meget jeg sætter pris på dit svar! Jeg vil gennemse alle dine tip og udfordre mig selv med dem, tak igen 🙂
- Intet problem, jeg havde også sjovt at gennemgå det! Håber du skriver noget mere i fremtiden =)