Reputation: 123
I am in the process of making a Hangman type game. So far, I have written the CLI version which works well, i'm just porting it over to create a GUI.
I have become stuck :-(. The program is not complete, and there's still more to do but I have two issues. The first is the label update.
When a letter is chosen, it creates enough dashes for the letter, and places this in a label called 'letter'.
When a user enters a letter, it replaces the dashes, however it then adds a new label next to the old label, instead, I would like to replace this label. I have tried using the .set() but this doesn't seem to work.
My second issue, and this is more of a logic error (I think), is that I wanted to keep track of the letters entered so that I could compare this to newly entered letters and alert the user. This works well, however when a letter has been entered it will warn the user even if its the first time it has been typed.
Here's the code:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
guesses = 8
def play():
print("play game")
wordList = ["talking", "dollar","choice", "famous", "define", "features"]
wordChoice = random.choice(wordList)
print(wordChoice)
wordLength = (len(wordChoice))
print(wordLength)
guessedLetters = []
dashes = []
def enterLetter():
print("Guess")
global guesses
print(guessedLetters)
while guesses != 0:
guess = entry.get().lower()
if len(guess) >1:
messagebox.showinfo("Error","Sorry, only one letter at a time")
entry.delete("0","end")
return
elif guess.isalpha() == False:
messagebox.showinfo("Error","Letters only please")
entry.delete("0","end")
return
elif guess in guessedLetters:
messagebox.showinfo("Error","You have already used the letter")
entry.delete("0","end")
return
guessedLetters.append(guess)
print(guessedLetters)
print(guesses)
count = 0
for i in range(wordLength):
if wordChoice[i] == guess:
dashes[i] = guess
count = count +1
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
if count == 0:
guesses -= 1
if guesses == 0:
print("You have ran out of guesses!")
print("The word was:",wordChoice)
###### Play Game GUI
play = Toplevel()
play.title("Play Hangman!")
label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)
for i in range(wordLength):
dashes.append("-")
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
entry = Entry(play)
entry.grid(row = 3, column = 1, columnspan = wordLength)
enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
label = Label(play, text = "").grid(row= 4, columnspan = 6)
def scores():
print("check scores")
def howToPlay():
print("how to play")
####### Main Menu
root = Tk()
root.geometry("500x300")
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2)
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2)
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1)
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2)
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)
root.mainloop()
Upvotes: 0
Views: 115
Reputation: 1619
The reason you cant update your label is because you haven't stored it in any variable. The grid, pack and place functions of the Label object and of all other widgets returns None, therefore when you call:
letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10)
your label cannot be accessed by variable letter. To fix this you should split it like so:
letter = Label(play, text = dashes, font = ("Arial",20))
letter.grid(row = 2, column = i+1,padx = 10, pady =10)
To update text of that label, you can call .configure(text = 'new text')
on it.
# letter = Label(play, text = dashes, font = ("Arial",20)).grid(row = 2, column = i+1,padx = 10, pady =10) #
letter.configure(text = dashes)
As for your second issue, i think you confused while
loop and if
statement in the function enterLetter
. It's called once per click and you only need to check one time if player has ran out of guesses.
if guesses != 0:
...
elif guesses == 0:
....
Upvotes: 1
Reputation: 322
if guesses > 0:
Code:
import tkinter
from tkinter import *
from tkinter import messagebox
import random
guesses = 8
letter = None
def play():
global letter
print("play game")
wordList = ["talking", "dollar","choice", "famous", "define", "features"]
wordChoice = random.choice(wordList)
print(wordChoice)
wordLength = (len(wordChoice))
print(wordLength)
guessedLetters = []
dashes = []
play = Toplevel()
play.title("Play Hangman!")
label = Label(play, text="HANGMAN", font = ("Arial",16)).grid(row = 0)
label = Label(play, text="Enter your guess >").grid(row = 3, column = 0)
for i in range(wordLength):
dashes.append("-")
letter = Label(play, text = dashes, font = ("Arial",20))
letter.grid(row = 2, column = i+1,padx = 10, pady =10)
print(letter)
def enterLetter():
print("Guess")
global guesses, letter
print(guessedLetters)
if guesses != 0:
guess = entry.get().lower()
if len(guess) >1:
messagebox.showinfo("Error","Sorry, only one letter at a time")
return
elif guess.isalpha() == False:
messagebox.showinfo("Error","Letters only please")
return
elif guess in guessedLetters:
messagebox.showinfo("Error","You have already used the letter")
return
entry.delete("0","end")
guessedLetters.append(guess)
#print(guessedLetters)
#print(guesses)
print(dashes)
count = 0
for i in range(wordLength):
if wordChoice[i] == guess:
dashes[i] = guess
count += 1
letter.configure(text = dashes)
if count == 0:
guesses -= 1
if "".join(dashes) == wordChoice:
print("succsess!")
play.destroy()
return
if guesses == 0:
print("You have ran out of guesses!")
print("The word was:",wordChoice)
###### Play Game GUI
entry = Entry(play)
entry.grid(row = 3, column = 1, columnspan = wordLength)
enterButton = Button(play, text = "Enter Guess", width = 15, command = enterLetter).grid(row = 3, column = (wordLength+2))
label = Label(play, text = "Letter used: ").grid(row = 4, columnspan = 2)
label = Label(play, text = "").grid(row= 4, columnspan = 6)
def scores():
print("check scores")
def howToPlay():
print("how to play")
####### Main Menu
root = Tk()
root.geometry("500x300")
root.title("HANGMAN")
label = Label(root, text="HANGMAN", font = ("Arial",30)).grid(row = 0, columnspan = 3)
label = Label(root, text = "Option 1 :", font = ("Arial",12)).grid(row = 1, column = 1)
playButton = Button(root, text = "Play Game", width = 15, command = play).grid(row = 1, column = 2)
label = Label(root, text = "Option 2 :", font = ("Arial",12)).grid(row = 2, column = 1)
instructionsButton = Button(root, text = "How to play", width = 15, command = howToPlay).grid(row = 2, column = 2)
label = Label(root, text = "Option 3 :", font = ("Arial",12)).grid(row = 3, column = 1)
scoresButton = Button(root, text = "View Scores", width = 15, command = scores).grid(row = 3, column = 2)
label = Label(root, text = "Option 4 :", font = ("Arial",12)).grid(row = 4, column = 1)
exitButton = Button(root, text = "Exit", width = 15, command = exit).grid(row = 4, column = 2)
root.mainloop()
I hope this helps you.
Upvotes: 1