patternpythonMinor
Simple Hangman in Python
Viewed 0 times
simplepythonhangman
Problem
I decided to code a simple Hangman in Python today and wanted some feedback on the code since I only started programming three weeks ago.
I intentionally didn't add a lot of whitespace, it just doesn't make it any more readable for me - but feel free to give me reasons to start doing so.
Any tips and suggestions are appreciated.
The output looks something like this:
Any suggestings for a better output?
I intentionally didn't add a lot of whitespace, it just doesn't make it any more readable for me - but feel free to give me reasons to start doing so.
Any tips and suggestions are appreciated.
import os
words = ["foobar", "gnarf", "fnord"]
current_word = 0
maximum_words = len(words)
maximum_guesses = 10
solved_words = 0
for word in words:
current_word += 1
current_guess = 0
dashes = []
for letter in word:
dashes.append("_")
while current_guess < maximum_guesses:
current_guess += 1
os.system("clear")
print("Word {}/{}".format(current_word, maximum_words))
print("Solved {}/{}".format(solved_words, maximum_words))
print("Guess {}/{}".format(current_guess, maximum_guesses))
print("\n{}\n".format(" ".join(dashes)))
guess = input("Guess: ")
guess = guess.lower()
if not len(guess) == 1 or not guess.isalpha():
current_guess -= 1
for index, letter in enumerate(word):
if letter == guess:
dashes[index] = letter
if not "_" in dashes:
solved_words += 1
breakThe output looks something like this:
Word 1/3
Solved 0/3
Guess 5/10
f o o b a _
Guess: rAny suggestings for a better output?
Solution
I see a couple issues, though nothing too major.
Improper form for 'if not in'
While this works, it's not the proper form for this:
The better form for this is:
Tracking if a value is not equal to something
This works:
But, we can remove one 'not' though, and use an inequality operator instead:
Generation of dashes
You can shorten the creation of 'dashes' to this when you create it, and then get rid of the for loop that generated it previously:
No tracking of guesses already made
Your code does not track guesses already made. Therefore, people can 'waste' guesses.
Let's do two things: first let's move around some things. Secondly, let's add some code to capture this case and not increment the number of guesses made when this happens.
First, let's change where we increment the 'current guess' value, and define a different 'start' value:
Basically, we moved the current_guess incrementer to lower in the code. And initialize the guess counter to
Now let's do some "already guessed" code:
This allows 'repeated' guesses of the same letter to not take effect. That way, if someone enters 'o' as a guess twice, accidentally or intentionally, on the word 'foobar', they aren't penalized for something already guessed. You can choose to not do this, but it helps protect against "What the heck, I shouldn't be penalized for something I already guessed!" complaints.
I don't change much of your program. This is the total program with my above suggestions, plus some whitespace for readability. I don't have any suggestions for improving the output, though, because it seems to be okay as it is, at least to me.
Improper form for 'if not in'
While this works, it's not the proper form for this:
if not "_" in dashes:The better form for this is:
if "_" not in dashes:Tracking if a value is not equal to something
This works:
if not len(guess) == 1 or not guess.isalpha():But, we can remove one 'not' though, and use an inequality operator instead:
if len(guess) != 1 or not guess.isalpha():Generation of dashes
You can shorten the creation of 'dashes' to this when you create it, and then get rid of the for loop that generated it previously:
dashes = ['_'] * len(word)No tracking of guesses already made
Your code does not track guesses already made. Therefore, people can 'waste' guesses.
Let's do two things: first let's move around some things. Secondly, let's add some code to capture this case and not increment the number of guesses made when this happens.
First, let's change where we increment the 'current guess' value, and define a different 'start' value:
for word in words:
current_word += 1
current_guess = 1
dashes = []
....
while current_guess < maximum_guesses:
os.system("clear")
....
guess = guess.lower()
if not len(guess) == 1 or not guess.isalpha():
current_guess += 1
....Basically, we moved the current_guess incrementer to lower in the code. And initialize the guess counter to
1 to begin with.Now let's do some "already guessed" code:
for word in words:
....
guesses = set()
for letter in word:
...
guess = guess.lower()
if guess not in guesses:
guesses.add(guess)
current_guess += 1
if not len(guess) == 1 or not guess.isalpha():
current_guess -= 1
for index, letter in enumerate(word):
if letter == guess:
dashes[index] = letter
if "_" not in dashes:
solved_words += 1
breakThis allows 'repeated' guesses of the same letter to not take effect. That way, if someone enters 'o' as a guess twice, accidentally or intentionally, on the word 'foobar', they aren't penalized for something already guessed. You can choose to not do this, but it helps protect against "What the heck, I shouldn't be penalized for something I already guessed!" complaints.
I don't change much of your program. This is the total program with my above suggestions, plus some whitespace for readability. I don't have any suggestions for improving the output, though, because it seems to be okay as it is, at least to me.
import os
words = ["foobar", "gnarf", "fnord"]
current_word = 0
maximum_words = len(words)
maximum_guesses = 10
solved_words = 0
for word in words:
current_word += 1
current_guess = 1
dashes = ['_'] * len(word)
guesses = set()
while current_guess < maximum_guesses:
os.system("clear")
print("Word {}/{}".format(current_word, maximum_words))
print("Solved {}/{}".format(solved_words, maximum_words))
print("Guess {}/{}".format(current_guess, maximum_guesses))
print("\n{}\n".format(" ".join(dashes)))
guess = input("Guess: ")
guess = guess.lower()
if guess not in guesses:
guesses.add(guess)
current_guess += 1
if len(guess) != 1 or not guess.isalpha():
current_guess -= 1
for index, letter in enumerate(word):
if letter == guess:
dashes[index] = letter
if "_" not in dashes:
solved_words += 1
breakCode Snippets
if not "_" in dashes:if "_" not in dashes:if not len(guess) == 1 or not guess.isalpha():if len(guess) != 1 or not guess.isalpha():dashes = ['_'] * len(word)Context
StackExchange Code Review Q#148741, answer score: 6
Revisions (0)
No revisions yet.