import random
words=["cat", "dog", "animal", "something", "whale", "crocodile", "lion", "summer", "boston", "seattle"]
the_word=random.choice(words)
#print(the_word)
a=len(the_word) #number of letter in the word
c=['_'for i in range(a)]#blanks seperated
blanks=" ".join(c)
print("This is a word with",a,"letter")
print("\t", blanks)
guess=0
while guess<3:
answer=input("Please enter a letter: ")
if answer in the_word:
the_index=the_word.index(answer)#find the index
c[the_index]=answer
blanks=" ".join(c)
print(blanks)
else:
guess=guess+1
print("There is no",answer,"in the word.")
I have two problems:
1st I can't reveal 2 words, summer for example, if a user input 'm' it will reveal only the first letter 'm'
2nd when the user input more than one word the program still consider right answer. For example: The user input "nm" for the word "something" the program still consider it right, and the word turn out like this "somethinmg"
You can check the length of answer via something like
if len(answer) != 1:
print "Please enter just one letter"
Or you can simply take only the first letter of what they enter
letter = answer[0]
See How to find all occurrences of an element in a list? on how to find multiple indexes that match.
Okay first of all to do the display I would take the word, split it up into letters and then create a list with the same length containing all '_'. This way you could display the _ _ _ _ etc by calling ' '.join(substitutelist)....
To get multiple letter responses:
each guess call
for letter in range(len(word)):
if word[letter]==guess.lower():
substitutelist[letter]=guess.lower()
Then every time a letter was called I would add it to a list titled something like "USED" and check each guess to make sure its not in zip(word, used) and if it is return a message error.
Here is an example hangman code I wrote to show the different functions...
import re, sys
from random import choice
def showmap(hangmanpic):
"""Will show the hangman pic after subtracting any
characters holding the place of a future body part"""
tempmap=''
x=str(range(7))
for i in hangmanpic:
if i in x:
tempmap+=' '
else:
tempmap+=i
return tempmap
def addbodypart(remaining, hangmanmap):
"""takes the hangman map and substitutes in a body
part when a wrong answer is chosen. Returns the new
hangmanmap"""
bodyparts={'6':'(_)',
'5':'|',
'3':'\\\\',
'2':'\\\\',
'4':'/',
'1':'/'
}
return re.sub(str(remaining), bodyparts[str(remaining)], hangmanmap)
def StartGame(hangmanmap, word):
"""Starts the game"""
dashword, wrong=[], []
remaining=6
for i in word:
dashword.append('_')
while remaining>0:
if '_' not in dashword:
remaining=0
continue
for i in range(5):
print ""
print "Guesses Left = %d" %(remaining)
print showmap(hangmanmap)
print ""
print "Used Letters: %s" %(', '.join(wrong))
print "Word: %s"%(' '.join(dashword))
guess=str(raw_input('Guess a letter:')).lower()
if guess in str(wrong)+str(dashword):
print ""
print "Sorry but you have already guessed that letter. Please guess again."
print ""
continue
if guess not in word:
hangmanmap=addbodypart(remaining, hangmanmap)
remaining-=1
wrong.append(guess)
else:
for i in range(0, len(word)):
if word[i]==guess:
dashword[i]=guess
if '_' not in dashword:
for i in range(5):
print ""
print "You WIN! Congrats"
print "The word was %s" %(word)
print showmap(hangmanmap)
print "Used Letters: %s" %(', '.join(wrong))
print "Word: %s"%(' '.join(dashword))
else:
for i in range(5):
print ""
print showmap(hangmanmap)
print "Word: %s" %(word)
print "Sorry but you've ran out of guesses! You Lose! The correct word was %s" %(word)
def main():
word=str(choice([line.strip() for line in open(sys.argv[1])])).lower()
hangmanmap=""" _________
|/ |
| 6
| 354
| 5
| 1 2
|
___|___"""
print "Welcome to AmazingReds Hangman Game!"
print "6 wrong answers and YOU LOSE! Good Luck."
StartGame(hangmanmap, word)
if __name__ == '__main__':
main()
Related
Hi I'm trying to make a word game, where the user guesses a word from a word in a given list, and the program tells the user what words they got wrong. The problem I'm having is that my program does not check for the words that the user inputs, but instead checks the validity of the word from the word list. How do I check each letter in the string to see whether it matches to the corresponding letter in the word from the given list?
def checkLetters(secretWord, userWord):
print ("The word is " + secretWord)
for i in range(0,len(secretWord)):
while secretWord[0] == userWord[0].lower():
print(str(i) + "is Correct")
break
for i in secretWord:
if secretWord[0] != userWord[0].lower():
print(str(userWord[i]) + " is false")
import random
validWords = ["could", "smile", "ultra", "extra","beacon", "hearts", "cap","computing", "python"]
wordPosition = random.randint(0,len(validWords)-1)
guess = input("Enter Your guess for the word: ")
checkLetters(validWords[wordPosition], guess)
This code will check letter by letter to see if user input matches random word from a given list:
def checkLetters(secretWord, userWord):
print(f'Secret word: {secretWord}, user word: {userWord}')
if len(secretWord) != len(userWord):
return False
for i, letter in enumerate(secretWord):
if letter != userWord[i]:
return False
return True
import random
validWords = ["could", "smile", "ultra", "extra","beacon", "hearts", "cap","computing", "python"]
wordPosition = random.randint(0,len(validWords)-1)
guess = input("Enter Your guess for the word: ")
result = checkLetters(validWords[wordPosition], guess)
print(result)
I am building hangman in python.
The first two functions I have generates random word and its definition from the API which is working just perfectly.
import requests
import json
def generate_random_word():
random_word_url = 'https://random-word-form.herokuapp.com/random/adjective'
random_word_url_response = requests.get(random_word_url)
return json.loads(random_word_url_response.text)[0]
def get_random_word_definition():
random_word = generate_random_word()
definition_api_url = 'https://api.dictionaryapi.dev/api/v2/entries/en/' + random_word
definition_api_url_response = requests.get(definition_api_url)
return json.loads(definition_api_url_response.text)[0]['meanings'][0]['definitions'][0]['definition'],random_word
My next function is this:
def modify_word(word):
new_word = list(word)
for i in range(len(new_word)):
new_word[i] = '_'
return "".join(new_word)
As you see it iterates other listed word and changes its characters to "_".
Now to the issue:
def validate_word(original,guess,hidden_word):
listify_original = list(original)
listify_hidden = list(hidden_word)
for char_place,char in enumerate(listify_original):
if(char == guess):
listify_hidden[char_place] = char
print('found it',"".join(listify_hidden))
This function is accepting 3 parameters: 1.Original word which was generated 2.Players guess 3.Hidden word which is generated through modify_word function above
Whenever user gets correct guess the hidden latter in string is replaced with this letter as expected so if the word is "colour" and user types c the function will print out string like this c_____ as it should. But issue comes when user guesses another latter. in this case whole string is being re-generated and letter guessed before last one just disappears. so for example if user guessed "l" function will print out __l___ instead of c__l___.
This is the main function in which I call validate_word:
def hang_man_guess_game():
generate_word = get_random_word_definition()
definition = generate_word[0]
word = generate_word[1]
amount_of_tries = 6
print('Welcome to the hang man game!')
print('The length of the word is: ',len(word))
print('The defition of word is: ',definition)
print('Amount of health: ',amount_of_tries)
print('Health gets lesser on each wrong guess!')
print('You can write as many latters as you want!')
print('Good luck player!')
hidden_word = modify_word(word)
while(amount_of_tries != 0):
print('Word: ', hidden_word)
user_guess = input('Enter your guess: ')
validate_word(word,user_guess,hidden_word)
# print('Good job')
hang_man_guess_game()
Sample input for word is: hopeful
Any suggestions please?
You are not updating hidden_word as the user guesses a letter right. You can do this by returning the updated value in validate_word()
def validate_word(original,guess,hidden_word):
listify_original = list(original)
listify_hidden = list(hidden_word)
current_word = hidden_word
for char_place,char in enumerate(listify_original):
if(char == guess):
listify_hidden[char_place] = char
current_word = "".join(listify_hidden)
print('Found it', current_word)
return current_word
Similarly in the while loop in hang_man_guess_game(), the returned value now becomes the updated hidden_word
while(amount_of_tries != 0):
print('Word: ', hidden_word)
user_guess = input('Enter your guess: ')
hidden_word = validate_word(word,user_guess,hidden_word)
Output
Enter your guess: q
Word: _____
Enter your guess: c
Found it c____
Word: c____
Enter your guess: r
Found it c___r
Word: c___r
Enter your guess: o
Found it co__r
Found it co_or
Word: co_or
Enter your guess: l
Found it color
Word: color
You should update your hidden_word with based on the function validate_word. You should return "".join(listify_hidden). You can then move you print function in the main, this is in my opinion good practice to make sure each function only has one task (i.e. validate the word and printing is another task).
In your validate_word function, the hidden_word variable is never modified. At the beginning, you create a new list, called listify_hidden, but when you change a letter in this variable, it does not propagate to the original hidden_word string, outside of the function.
One way to fix this would be to make your validate_word return the new hidden string, with the discovered letters.
So you'll have to make the function return the updated hidden word:
def validate_word(original,guess,hidden_word):
listify_original = list(original)
listify_hidden = list(hidden_word)
for char_place,char in enumerate(listify_original):
if(char == guess):
listify_hidden[char_place] = char
print('found it',"".join(listify_hidden)
)
return "".join(listify_hidden)
And then in your while loop:
while(amount_of_tries != 0):
print('Word: ', hidden_word)
user_guess = input('Enter your guess: ')
hidden_word = validate_word(word,user_guess,hidden_word) <-- update the hidden word
# print('Good job')
No global please.
Here is my current code:
import random
def getSecretPhrase():
secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
x = random.randint(1,10)
correctPhrase = secretPhrase[x-1]
print("Please guess a letter.")
correctLetters = input().lower()
return correctPhrase
def createPhrase():
blanks = '_' * len(correctPhrase)
print(blanks)
print(correctPhrase)
def main():
getSecretPhrase()
createPhrase()
for i in range(len(secretPhrase)):
if correctPhrase[i] in correctLetters:
blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
for letter in blanks:
print(letter, end = ' ')
main()
The intended output should be:
Please guess a letter.
>>> e
#assuming the phrase is I like trains
_ - _ _ _ e - _ _ _ _ _ _
However, I get
Traceback (most recent call last):
File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 27, in <module>
main()
File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 21, in main
createPhrase()
File "C:\Documents and Settings\Alex\My Documents\Downloads\az_wheeloffortune12.py", line 16, in createPhrase
blanks = '_' * len(correctPhrase)
NameError: name 'correctPhrase' is not defined
I am trying to use the variable correctPhrase in multiple places. This may be a scope issue.
I made alot of comments here, hopefully you can follow:
import random
def get_secret_phrase():
# Instead of using one long string and creating a list from it, just make a list!
phrases = ["I like trains","Drop the bass","YouTube is funny","Ebola is dangerous","Python is cool","PHS is 116 years old","I am a person","Sleep is overrated","Programming is fun"]
# We have a list, we can get its length by using `len()` so there is no need to hardcode a value of 10
# We also know that lists are 0-indexed, so we can tell `randint()` to get an int between 0 and the length of the list - 1
index = random.randint(0, len(phrases) - 1)
# Now we get the phrase at the random `index` we just created
secret_phrase = phrases[index]
# An alternative, more pythonic way to do the previous 2 lines is to use `random.choice()` which does the same logic
#secret_phrase = random.choice(phrases)
# Finally, return `secret_phrase` and make it lowercase so we can use it in another method
return secret_phrase.lower()
def get_user_guess():
# We want to make this separate from `get_secret_phrase()` because this will be called every time we want the user to guess
print("What is your guess? ")
# Assign the user input to a variable
guess = input().lower()
print("You guessed: {}".format(guess))
return guess
def get_phrase_progress(secret_phrase, guessed_letters):
# We want to generate a string that will represent how many letters the user has gotten correctly
# We will call this every time so that it is always accurate based on what was guessed
blanks = ''
for letter in secret_phrase:
if letter == ' ' or letter in guessed_letters:
blanks = blanks + letter
else:
blanks = blanks + '_'
return blanks
def get_phrase_progress_pythonic(secret_phrase, guessed_letters):
# Here's a really pythonic way to do this
return ''.join(letter if letter == ' ' or letter in guessed_letters else '_' for letter in secret_phrase)
def main():
guessed_letters = list() # First, create a `list` to store the guessed letters
secret_phrase = get_secret_phrase() # Next, call `get_secret_phrase()` and assign it's value to a variable in the scope of `main()`
# Uncomment the following to see that the pythonic version returns the same thing
# print(get_phrase_progress(secret_phrase, guessed_letters))
# print(get_phrase_progress_pythonic(secret_phrase, guessed_letters))
guessed_phrase = get_phrase_progress(secret_phrase, guessed_letters)
# We want to loop until the user guesses the whole phrase
while guessed_phrase != secret_phrase:
print(guessed_phrase)
# We call `get_user_guess()` to prompt the user to enter a letter
letter = get_user_guess()
# Next we want to make sure they entered just 1 letter
# We can use the built in `str.isalpha()` to check if the string entered by the user is alphabetical and at least 1 character long
if not letter.isalpha():
# However, we only want them to guess a single letter, so we also check that the length == 1
if len(letter) != 1:
print('You need to guess something...')
else:
print('You can only guess a single letter, you tried to guess: {}'.format(letter))
# Next we check if the user already guessed the letter, if so, tell them!
elif letter in guessed_letters:
print('You already guessed {}'.format(letter))
else:
guessed_letters.append(letter)
# Here we calculate `guessed_phrase` every loop to make sure it always takes into account what letters have been guessed
guessed_phrase = get_phrase_progress(secret_phrase, guessed_letters)
# If the user escapes the while loop, they won, they guessed the secret phrase
# We can calculate a score based on how many letters they guessed, this isn't great but it works for a simple scoring method
print('You won! It took you {} guesses to guess {}'.format(len(guessed_letters), secret_phrase))
main()
I made a few assumptions writing this. The first is that you want to make this some sort of hangman like game where they keep guessing until they get it. To that end I've made a class that does it for you. The code is commented with explanations
import random
import string
class WordGuesser(object):
## We store the possible secret phrases as a class variable and make sure they're lower case
secretPhrase = map(string.lower, ['I like trains', 'Drop the bass',
'YouTube is funny', 'Ebola is dangerous',
'Python is cool', 'PHS is 116 years old',
'I am a person', 'Sleep is overrated',
'Programming is fun'])
def __init__(self):
## We pick a secret phrase
self.correctPhrase = WordGuesser.secretPhrase[random.randint(1,10)-1]
self.length = len(self.correctPhrase)
## We pick our 'blank' phrase
self.blankPhrase = ''.join(('_' if letter != ' ' else ' ')
for letter in self.correctPhrase)
def gameLoop(self):
print self.blankPhrase
## as long as our blank phrase is wrong we continue
while self.blankPhrase != self.correctPhrase:
guess = raw_input("Please guess a letter.").lower() ## Their guess
temp = ""
for i in range(self.length): ## we fill in the word
if self.correctPhrase[i] == guess:
temp += guess
else:
temp += self.blankPhrase[i]
self.blankPhrase = temp
print self.blankPhrase ## display what they have so far
def main():
game = WordGuesser()
game.gameLoop()
if __name__ == '__main__':
main()
When run it'll look like this
>>>
___________ __ ___
Please guess a letter.a
_____a_____ __ ___
Please guess a letter.e
_____a_____ __ ___
Please guess a letter.i
_____a__i__ i_ ___
Please guess a letter.o
__o__a__i__ i_ ___
Please guess a letter.u
__o__a__i__ i_ _u_
Please guess a letter.p
p_o__a__i__ i_ _u_
Please guess a letter.m
p_o__ammi__ i_ _u_
Please guess a letter.y
p_o__ammi__ i_ _u_
Please guess a letter.e
p_o__ammi__ i_ _u_
Please guess a letter.l
p_o__ammi__ i_ _u_
Please guess a letter.s
p_o__ammi__ is _u_
Please guess a letter.r
pro_rammi__ is _u_
Please guess a letter.g
programmi_g is _u_
Please guess a letter.n
programming is _un
Please guess a letter.f
programming is fun
>>>
Since this is clearly homework, I decided to try and implement it in as few lines of code as possible, just for fun. Got it down to 4...
import random
phrase, board, guesses, tries = random.choice(["I like trains", "Drop the bass", "YouTube is funny", "Ebola is dangerous", "Python is cool", "PHS is 116 years old", "I am a person", "Sleep is overrated", "Programming is fun"]).lower(), lambda guesses: ' '.join(letter if letter in guesses else "-" if letter == " " else "_" for letter in phrase), set(), 0
while board(guesses) != board(phrase.replace(" ", "-")): print board(guesses); guesses.add(raw_input("What is your guess? ").lower()); tries += 1
print "YOU WIN! It took you {} tries and {} unique guesses to guess {}".format(tries, len(guesses), board(guesses))
You can try it out here: http://repl.it/4cg
So to answer your original question...
import random
def getSecretPhrase():
secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
x = random.randint(1,10)
correctPhrase = secretPhrase[x-1]
print("Please guess a letter.")
correctLetters = input().lower()
return correctPhrase
def createPhrase(correctPhraseArgument): # this method accepts an argument and stores it in a variable named `correctPhraseArgument`
blanks = '_' * len(correctPhraseArgument)
print(blanks)
print(correctPhraseArgument)
def main():
secretPhrase = getSecretPhrase() # assign the returned value to a variable in this scope
createPhrase(secretPhrase) # pass the variable to this method
for i in range(len(secretPhrase)):
if correctPhrase[i] in correctLetters:
blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
for letter in blanks:
print(letter, end = ' ')
main()
This will still have issues, but I want to show you what is causing the error you mentioned...
The variables that are declared inside of your methods live inside those methods. To access them from other methods WITHOUT using global variables, you need to pass them as parameters and return the values. Then, you need to assign those returned values to new variables.
how about:
import random
def getSecretPhrase():
secretPhrase = "I like trains,Drop the bass,YouTube is funny,Ebola is dangerous,Python is cool,PHS is 116 years old,I am a person,Sleep is overrated,Programming is fun".split(",")
x = random.randint(1,10)
correctPhrase = secretPhrase[x-1]
print("Please guess a letter.")
correctLetters = input().lower()
return correctPhrase
def createPhrase(correctPhrase):
blanks = '_' * len(correctPhrase)
print(blanks)
print(correctPhrase)
def main():
secretPhrase = getSecretPhrase()
createPhrase(secretPhrase)
for i in range(len(secretPhrase)):
if correctPhrase[i] in correctLetters:
blanks = blanks[:i]+correctPhrase[i] + blanks[i+1:]
for letter in blanks:
print(letter, end = ' ')
main()
Well, not only "correctLetters", there are a lot of variable scope issue in your code.
correctLetters is defined in getSecretPhrase() and only alive in this method. So, the method() doesn't know what is correctLetters, that's why you see this exception.
There are a lot of ways to solve this issue
First is define the "correctLetters" outside the method, and using keyword global
Second you can return the variable, such as:
def createPhrase():
blanks = '_' * len(correctPhrase)
return blanks
so in main(), you can get the return value as:
blanks = createPhrase()
OK so what I need to do is make my code only allow the user to enter one letter and then one symbol at a time. The example below shows what I want in a better view.
At the moment my code allows the user to enter more than one character at a time which I don't want.
What letter would you like to add? hello
What symbol would you like to pair with hello
The pairing has been added
['A#', 'M*', 'N', 'HELLOhello']
What I want is a message to be displayed like this and the pairing not to be added to the list.
What letter would you like to add? hello
What symbol would you like to pair with hello
You have entered more than one character, the pairing was not added
['A#', 'M*', 'N',].
So far my code for this section is as follows...
It would also be great for when the user enters a number in the letter section, an error message to be printed.
def add_pairing(clues):
addClue = False
letter=input("What letter would you like to add? ").upper()
symbol=input("\nWhat symbol would you like to pair with ")
userInput= letter + symbol
if userInput in clues:
print("The letter either doesn't exist or has already been entered ")
elif len(userInput) ==1:
print("You can only enter one character")
else:
newClue = letter + symbol
addClue = True
if addClue == True:
clues.append(newClue)
print("The pairing has been added")
print (clues)
return clues
The easiest way to ensure user input is with a loop:
while True:
something = raw_input(prompt)
if condition: break
Something set up like this will continue to ask prompt until condition is met. You can make condition anything you want to test for, so for you, it would be len(something) != 1
Your method can be simplified to the following if you let the user enter a letter and symbol pair:
def add_pairing(clues):
pairing = input("Please enter your letter and symbol pairs, separated by a space: ")
clues = pairing.upper().split()
print('Your pairings are: {}'.format(clues))
return clues
Not exactly sure what you want to return but this will check all the entries:
def add_pairing(clues):
addClue = False
while True:
inp = input("Enter a letter followed by a symbol, separated by a space? ").upper().split()
if len(inp) != 2: # make sure we only have two entries
print ("Incorrect amount of characters")
continue
if not inp[0].isalpha() or len(inp[0]) > 1: # must be a letter and have a length of 1
print ("Invalid letter input")
continue
if inp[1].isalpha() or inp[1].isdigit(): # must be anything except a digit of a letter
print ("Invalid character input")
continue
userInput = inp[0] + inp[1] # all good add letter to symbol
if userInput in clues:
print("The letter either doesn't exist or has already been entered ")
else:
newClue = userInput
addClue = True
if addClue:
clues.append(newClue)
print("The pairing has been added")
print (clues)
return clues
I am fan of raising and catching exceptions in similar cases. Might be shocking for people with 'C-ish' background (sloooow), but it is perfectly pythonic and quite readable and flexibile in my opinion.
Also, you should add check for characters outside of set you are expecting:
import string
def read_paring():
letters = string.ascii_uppercase
symbols = '*##$%^&*' # whatever you want to allow
letter = input("What letter would you like to add? ").upper()
if (len(letter) != 1) or (letter not in letters):
raise ValueError("Only a single letter is allowed")
msg = "What symbol would you like to pair with '{}'? ".format(letter)
symbol = input(msg).upper()
if (len(symbol) != 1) or (symbol not in symbols):
raise ValueError("Only one of '{}' is allowed".format(symbols))
return (letter, symbol)
def add_pairing(clues):
while True:
try:
letter, symbol = read_paring()
new_clue = letter + symbol
if new_clue in clues:
raise ValueError("This pairing already exists")
break # everything is ok
except ValueError as err:
print(err.message)
print("Try again:")
continue
# do whatever you want with letter and symbol
clues.append(new_clue)
print(new_clue)
return clues
I am trying to create a hangman game.
Python keeps telling me that get_word is not defined, but I'm not sure really as to why it says that.
get_word():
dictionary = ["number","one","hyper","active","knuckle","head","ninja"]
import random
process_guess():
while keep_playing:
dictionary=["number","one","hyper","active","knuckle","head","ninja"]
word=choice(dictionary)
word_len=len(word)
guesses=word_len * ['_']
max_incorrect=7
alphabet="abcdefghijklmnopqrstuvxyz"
letters_tried=""
number_guesses=0
letters_correct=0
incorrect_guesses=0
print_game_rules(max_incorrect,word_len)
while (incorrect_guesses != max_incorrect) and (letters_correct != word_len):
clues()
letter=get_letter()
if len(letter)==1 and letter.isalpha():
if letters_tried.find(letter) != -1:
print ("letter has already been used", letter)
else:
letters_tried = letters_tried + letter
first_index=word.find(letter)
if first_index == -1:
incorrect_guesses= incorrect_guesses +1
print ("The",letter,"is not the unknown word.")
else:
print("The",letter,"is in the unknown word.")
letters_correct=letters_correct+1
for i in range(word_len):
if letter == word[i]:
guesses[i] = letter
else:
print ("Please guess a single letter in the alphabet.")
print("victory:",no guesses ')
play():
1 = yes
0 = no
print(("play again? (1-yes, 0-no")):
print("get the current guess letter:", current)
main()
In Python, new functions are defined using the def keyword. So do:
def get_word():
and everywhere else you want to define a function.