While this assignment is past due (I joined the class late unfortunately) I still need to figure it out. I have the following list of words:
abhor:hate
bigot:narrow-minded, prejudiced person
counterfeit:fake; false
enfranchise:give voting rights
hamper:hinder; obstruct
kindle:to start a fire
noxious:harmful; poisonous; lethal
placid:calm; peaceful
remuneration:payment for work done
talisman:lucky charm
abrasive:rough; coarse; harsh
bilk:cheat; defraud
I need to read this file into a dictionary, pick a random key, scramble it, then ask the user to solve it. Unlike other solutions on here, it does not iterate three times, but runs until the user enters 'n'. The code will ask the user after each round if the user wants to continue the game. The user can also type 'hint' to get the definition of the word.
There is a similar question here: (http://www.dreamincode.net/forums/topic/302146-python-school-project-write-a-word-scramble-game-status-complete/) or rather the result of a question, but I am not knowledgeable enough to bridge the gaps and make it work for my purposes. None of the variation on this that I have seen on stack overflow come close enough for me to bridge the gap either, likely because I just don't know enough yet. Before we even start, this code does not yet work at all really, I am pretty lost at this point, so please be gentle. My code so far is below:
import random
from random import shuffle
#Reads the words.txt file into a dictionary with keys and definitions
myfile = open("words.txt", "r")
wordDict = dict([(line[:line.index(":")], line[line.index(":") +1 : -1])
for line in myfile.readlines()])
#print (b)
def intro():
print('Welcome to the scramble game\n')
print('I will show you a scrambled word, and you will have to guess the word\n')
print('If you need a hint, type "Hint"\n')
#Picks a random key from the dictionary b
def shuffle_word():
wordKey = random.choice(list(wordDict.keys()))
return wordKey
#Gives a hint to the user
def giveHint(wordKey):
hint = wordDict[wordKey]
return hint
#Below - Retrieves answer from user, rejects it if the answer is not alpha
def getAnswer():
answer = input('\nEnter your first guess: ')
while True:
if answer.isalpha():
return answer
else:
answer = input('\nPlease enter a letter: ')
def keepPlaying():
iContinue = input("\nWould you like to continue? ")
return iContinue
def scramble():
theList = list(shuffle_word())
random.shuffle(theList)
return(''.join(theList))
#Main Program
if keepPlaying() == 'y':
intro()
shuffle_word()
randomW = shuffle_word()
#scramKey = list(randomW)
thisWord = scramble()
print ("\nThe scrambled word is " +thisWord)
solution = getAnswer()
if solution == thisWord:
print("\nCongratulations")
if solution == 'Hint' or solution == 'hint':
myHint = giveHint(wordKey)
print(myHint)
else:
print("\nThanks for playing")
I have edited this post to ask for new information, though I am not sure if that ishow its properly done. Thanks to the help of those below, I have made progress, but am stuck not on a specific piece.
I have two questions. 1: How can I get the giveHint() function to return the definition of the random key selected by the shuffle_wprd() function. I know what I have above will not work because it is simply returning a string, but it seems like just using a dict.get() function would not get the correct definition for the random word chosen.
2: How can I get the program not to ask the user to continue on the first pass, but to then ask from then on. I thought about using a while loop and redefining the variable during the iteration, but I don't know enough to get it to work properly.
regardless, thank you to those people who have already helped me.
This should help you out a bit, the length seems to be of no benefit as a hint as you can see the length of the scrambled word so I used the definition as the hint,I think you also want to ask the user to guess the word not individual letters:
from random import shuffle, choice
#Reads the words.txt file into a dictionary with keys and definitions
with open("words.txt") as f:
word_dict = {}
for line in f:
# split into two parts, word and description
word, hint = line.split(":")
word_dict[word] = hint
def intro():
print('Welcome to the scramble game\n')
print('I will show you a scrambled word, and you will have to guess the word\n')
#Picks a random key from the dictionary b
def pick_word():
word = choice(list(word_dict.keys()))
return word
#Gives a hint to the user
def give_hint(word):
# return the definition of the word
descrip = word_dict[word]
return descrip
#Below - Retrieves answer from user, rejects it if the answer is not alpha
def get_answer():
while True:
answer = input('Please enter a guess: ')
if answer.isalpha():
return answer
else:
print("Only letters in the word")
def main():
intro()
word = pick_word()
# give user lives/tries
tries = 3
shffled_word = list(word)
# shuffle the word
shuffle(shffled_word)
# rejoin shuffled word
shffled_word = "".join(shffled_word)
# keep going for three tries as most
while tries > 0:
inp = input("Your scrambled word is {}\nEnter h if you want to see your hint or any key to continue".format(shffled_word))
if inp == "h":
print("The word definition is {}".format(give_hint(word)))
ans = get_answer()
if ans == word:
print("Congratulations you win!")
break
tries -= 1
# ask user if they want to play again, restarting main if they do
play_again = input("Press 'y' to play again or any key to exit")
if play_again == "y":
main()
# else the user did not press y so say goodbye
print("Goodbye")
main()
There are a few more bits to be added but I will leave that up to you.
Thank you to all those who helped. For any who come along later, the final product is here. Similar to what Padraic Cunningham put, but without the three answer limit, and without his more elegant solution of wrapping the main program into a called function.
import random
from random import shuffle, choice
#Reads the words.txt file into a dictionary with keys and definitions
with open("words.txt") as f:
wordDict = {}
for line in f:
# split into two parts, word and description
word, hint = line.split(":")
wordDict[word] = hint
#print (b)
def intro():
print('Welcome to the scramble game\n')
print('I will show you a scrambled word, and you will have to guess the word\n')
print('If you need a hint, type "Hint"\n')
#Picks a random key from the dictionary b
def shuffle_word():
wordKey = choice(list(wordDict.keys()))
return wordKey
#Gives a hint to the user
def giveHint(wordKey):
descrip = wordDict[word]
return descrip
#Below - Retrieves answer from user, rejects it if the answer is not alpha
def getAnswer():
answer = input('\nEnter a guess: ')
while True:
if answer.isalpha():
return answer
else:
answer = input('\nPlease enter a letter: ')
def getAnswer2():
answer2 = input('\nEnter another guess: ')
while True:
if answer2.isalpha():
return answer2
else:
answer2 = input('\nPlease enter a letter: ')
def keepPlaying():
iContinue = input("\nWould you like to continue? ")
return iContinue
#def scramble():
# theList = list(shuffle_word())
# random.shuffle(theList)
# return(''.join(theList))
#Main Program
while keepPlaying() == 'y':
intro()
#shuffle_word()
randomW = shuffle_word()
cheatCode = giveHint(randomW)
#scramKey = list(randomW)
thisWord = list(randomW)
print(thisWord)
random.shuffle(thisWord)
print(thisWord)
thisRWord = ''.join(thisWord)
print ("\nThe scrambled word is " +thisRWord)
solution = getAnswer()
loopMe = False
while loopMe == False:
if solution == randomW:
print("\nCongratulations")
loopMe = True
if solution == 'Hint' or solution == 'hint':
print(cheatCode)
if solution != randomW:
loopMe = False
solution = getAnswer2()
Related
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')
finishgame = "n"
counter = 0
#the song randomizer
num = random.randint(0,50)
f = open("songs.txt","r")
lines = f.readlines()
#first letter only system
song = str(lines[num])
firstl = song[0]
print(firstl)
#the artist generator
g = open("artists.txt","r")
line = g.readlines()
print(line[num])
#guess system
while finishgame == "n":
guess = str(input("Enter your guess"))
if guess == song:
counter = counter+5
print("Correct!")
finishgame = "y"
elif counter == 2:
print("Out of guesses, sorry :(")
print("The Correct Answer was:",song)
finishgame = "y"
else:
counter = counter+1
print("Try Again")
First time asking so apologizes for any errors. I have create a song guessing game where it takes a song from an external file, and displays the first letter of the title. It then takes the artist from a separate file (where it is in the same line as the song in the other file) and displays that too. Then you should guess the song. However, my code is having trouble recognizing when a 'guess' is correct, please can anyone tell me why? I've tried using different methods of identification such as the id() function but so far have not got any results. I'm probably missing something simple but any help would be much appreciated.
So I set out to make a simple game of hangman and everything worked fine, the whole code worked but it lacked the ability to allow the user to replay when the game is over. Thus I set out to put all the code I have written in various functions. So that I can call the functions when they are required (I thought it was the most logical way to allow replay-ability). Various problems followed but one stood out.
The main culprit (I think) is that I could not successfully get a value to update globally. I've read similar questions on the site but could not successfully adapt it to my case. I have a sample code to show what exactly I mean:
def GameMode():
choice = input('Play alone or play with friends? A F : ')
choice = choice.upper()
if choice == 'A':
wordslotmachine = ['stand','emerald','splash']
word = random.choice(wordslotmachine)
word = word.upper()
Rules()
elif choice == 'F':
word = input('Enter your word for your friends to guess: ')
word = word.upper()
Rules()
else:
choice = input('Please enter A or F: ')
choice = choice.upper()
I would need the program to remember what the value of "word" is and use this word in another method (this method is ran by another method showed below "Rules()"):
def MainGame():
guesses = ''
turns = 10
underscore = 0
seconds = 1
checker = 0
cheaterchance = 5
while turns > 0: #check if the turns are more than zero
for char in word: # for every character in secret_word
if char in guesses: # see if the character is in the players guess
print(char+' ', end='')
else:
print('_ ', end='')# if not found, print a dash
underscore += 1
if underscore == 0:
print(': You got it!')
Wait()
NewGame()
break
#A block of if's to check for cheating
if guess not in word:
print('Your guesses so far: '+guesses)
turns -= 1
if turns == 0:
break
else:
print('')
print('Try again. You have',turns,'more guesses')
print('Delayed chance to answer by',seconds,'seconds')
counter = 1
print(0,'.. ', end='')
while counter < seconds:
time.sleep(1)
print(counter,'.. ', end='')
counter += 1
if counter == seconds:
time.sleep(1)
print(counter,'.. done!', end='')
print('')
print('')
seconds += 1
underscore = 0
else:
print('Your guesses so far: '+guesses)
underscore = 0
#The else portion of the code to check for cheating
I have tried defining "word" outside of the function. Doing this doesn't fix the problem, GameMode() will not successfully update the value of "word". And whatever the value of "word" defined outside of the function will be called and used by MainGame(). However doing this shows another problem.
That being, the code that previously worked (it successfully read the input and correctly updated the game status) now does not work. Even if the correct letter is entered by the user, the program reads the input as incorrect.
These are the two problems I have faced so far and have yet to find a way to overcome them.
Note: I have successfully created a way to make the game replay-able by putting the entire original code (without the functions) inside a while loop. However I would still very much like to know how I can get the code to work using functions.
Edit: This is the function for Rules():
def Rules():
#Bunch of prints to explain the rules
MainGame()
print('Start guessing...')
Wait() is just a delay function with a countdown.
Global vs. Local variables.
You can reference and use a global variable from within a function, but you cannot change it.
It's bad practice, but you CAN declare a variable within your function to be global and then changes to it inside your function will apply to the variable of the same name globally.
HOWEVER, what I suggest is to return the word at the end of your function.
def whatever_function(thisword):
do some stuff
return word
new_word = whatever_function(thisword)
Functions can, and usually should, return values. Make GameMode() return the word to the caller;
def GameMode():
choice = input('Play alone or play with friends? A F : ')
choice = choice.upper()
if choice == 'A':
wordslotmachine = ['stand','emerald','splash']
word = random.choice(wordslotmachine)
word = word.upper()
Rules() #ignore this
elif choice == 'F':
word = input('Enter your word for your friends to guess: ')
word = word.upper()
Rules() #ignore this
else:
choice = input('Please enter A or F: ')
choice = choice.upper()
return word
From the main call GameMode and save the word;
def MainGame():
guesses = ''
turns = 10
underscore = 0
seconds = 1
checker = 0
cheaterchance = 5
word = GameMode() # add this here
You almost certainly want to use a class with instance variables
Contrived example:
class Hangman:
def __init__(self):
print("Starting hangman")
def mode(self):
# ...
self.word = 'whatever'
def play(self):
print("Look i have access to word", self.word)
if __name__ == '__main__':
hm = Hangman()
hm.mode()
hm.play() # may be what you want to put in a while loop
To access a global variable from inside a function, you have to tell python that it is global:
my_global_var = 1
def some_func():
global my_global_var
You have to use global keyword in every method that the global variable is being used or python will think you are defining/ using a local variable
Having said that, you should avoid globals as a coding practise.
global word #probably define this after imports.
def GameMode():
global word #add this
choice = input('Play alone or play with friends? A F : ')
choice = choice.upper()
if choice == 'A':
wordslotmachine = ['stand','emerald','splash']
word = random.choice(wordslotmachine)
word = word.upper()
Rules() #ignore this
elif choice == 'F':
word = input('Enter your word for your friends to guess: ')
word = word.upper()
Rules() #ignore this
else:
choice = input('Please enter A or F: ')
choice = choice.upper()
def MainGame():
guesses = ''
turns = 10
underscore = 0
seconds = 1
checker = 0
cheaterchance = 5
global word # add this here
use the code
global word
above the def or let the def return the value of word so it is stored in a variable outside the def
I'm building a simple 'quiz-program'. Code here:
import random
wordList1 = []
wordList2 = []
def wordAdd():
wordNew1 = str(input("Add a word to your wordlist: "))
wordNew2 = str(input("Add the translation to this word: "))
if wordNew1 != "exit":
wordList1.append(wordNew1)
wordAdd()
elif wordNew2 != "exit":
wordList2.append(wordNew2)
wordAdd()
else:
exercise()
def exercise():
q = random.choice(wordList1)
a = wordList2
if q[] == a[]:
print("Correct!")
else:
print("Wrong!")
wordAdd()
I'm trying to check the wordList1-number and compare it with the wordList2-number.
Now I didn't expect the def exercise to work but I can't find the solution to let it work...
I know about the dictionary-thing in Python but I would like to know wether such a array-construction is possible in Python.
Could someone help me with this?
Thanks in advance! Sytze
I played with your code a little. I'm not sure I perfectly understand your question, but I made it working the way I thought it needs to work. I added some comments to make it clear what I did.
I tried to stick with your basic concept (except the recursion), but I renamed a lot of things to make the code more readable.
import random
words = []
translations = []
def add_words():
# input word pairs until the user inputs "exit"
print('\nInput word and translation pairs. Type "exit" to finish.')
done = False
while not done:
word = raw_input("Add a word to your wordlist: ")
# only input translation, if the word wasn't exit
if word != "exit":
translation = raw_input("Add the translation to this word: ")
if word != "exit" and translation != "exit":
# append in pairs only
words.append(word)
translations.append(translation)
else:
done = True
def exercise():
# excercising until the user inputs "exit"
print("\nExcercising starts. ")
done = False
while not done:
# get a random index in the words
index = random.randrange(0, len(words))
# get the word and translation for the index
word = words[index]
translation = translations[index]
# ask the user
answer = raw_input('Enter the translation for "%s": ' % word)
if answer == "exit":
done = True
print("\nGoodbye!")
elif answer == translation:
print("Correct!")
else:
print("Wrong!")
add_words()
exercise()
I'm working on a simple text based hangman game in python. I have a rough program running but I've encountered two minor problems:
Why does the welcome message print twice?
When the user inputs a letter not in the word two times in a row, the second time, the "nope, try again"-message does not display and current word does not display. The first time an incorrect letter is input, it works. Why doesn't it work the second time?
from random import randrange
class HangmanApp:
def __init__(self, interface):
self.infile = open("hangman.txt", "r")
self.interface = textInterface()
for line in self.infile:
self.wordlist = line.split()
self.secretword = self.wordlist[randrange(len(self.wordlist))]
self.letter_list = list(self.secretword)
#tests the user's guess
def guess(self):
self.new_list = ["_"]*len(self.secretword)
#keep loop going as long as there are letters in the list
while self.letter_list != ["_"]*len(self.letter_list):
self.guess = self.interface.guess()
if self.guess in self.letter_list:
while self.guess in self.letter_list:
i = self.letter_list.index(self.guess)
#replace that letter from the list with "_"
self.letter_list[self.letter_list.index(self.guess)] = "_"
#add the chosen letter to a new list for display
self.new_list[i] = self.guess
#print list with letter added
self.interface.correct(self.new_list)
else:
self.interface.incorrect(self.new_list)
self.guess = self.interface.guess()
class textInterface:
def __init__(self):
print("Welcome to Hangman!")
def guess(self):
guess = input("Guess a letter! ")
return guess
def display (self, word):
string = ' '.join(word)
print(string)
def incorrect(self, word):
print("Nope, try again")
self.display(word)
def correct(self, word):
print("Correct")
self.display(word)
def main():
inter = textInterface()
app = HangmanApp(inter)
app.guess()
The welcome message is printed twice because you're creating two instances of textInterface: one in main() and another inside HangmanApp.__init__(). I think you meant to do:
self.interface = interface
instead of
self.interface = textInterface()
Inside HangmanApp.guess(), after receiving an incorrect guess (reaching the else: clause) you have an extra guess prompt that is not needed---one that doesn't pass through your checking code. I think this is probably causing the issue with it not working the second time around.