Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

PYTHON: The goal of this assignment is to use tkinter to produce a class hangman

ID: 3696171 • Letter: P

Question

PYTHON:

The goal of this assignment is to use tkinter to produce a class hangman that allows the user to play a simple game of hangman. It will loosely follow the strategy we used for the Calculator in class. Follow these guidelines:

Write a (module level, not in the class) function mask that takes two string arguments, the first a word the second containing exceptions. The function mask returns a string in which every character in the word has been replaced by ‘?’ except for the characters in exceptions. For example:

>>> mask('APPLE','AE')

'A???E'

>>> mask('APPLE','')

'?????'

>>> mask('APPLE','PLEASE')

'APPLE'

>>>

The interface (see images below):

hangman should inherit from Frame.

Hangman Label & Entry displays the current state of the word

Right Label & Entry – letters guessed correctly so far (no repeats listed)

Wrong Label & Entry – letters guessed incorrectly so far (repeats not listed)

26 buttons, one for each letter of the alphabet

Gameplay. The player clicks on a letter button. Three things can happen:

the letter is already in either the list of right or wrong letters. In this case nothing happens.

the letter is in the word (but not in either list). Then that letter is added to the list of right letters, the word is remasked and the masked word (use mask) is displayed next to Hangman (in effect revealing the new letter). If the word is finished a showinfo box states “You Win!”

the letter is not in the word (but not in either list). Then that letter is added to the list of wrong letters. If that list contains 6 or more letters, a showinfo box states “You Lose!”

Implementation details:

hangman subclasses Frame

you may assume that the user will not edit the Entry’s (this can be prevented but requires more than what we know now).

in addition to creating the interface, and calling Frame’s__init__, __init__ should take the given word, make it uppercase, and assign it to self.word

each button should set command=cmd, where cmd is a local function accepting one argument that defaults to the same letter on the button label (same thing we did with the calculator). cmd calls another method click to implement the gameplay above.

Here is an example of how the game works. First, start the game:

>>> root = Tk()
>>> hangman("APPLE",root).pack() # will close when “X” cliced

click ‘P’

‘E’,then ‘A’   

  

click ‘P’

click ‘P’ again click ‘N’ ‘L’

‘E’,then ‘A’   

could be ‘You Lose’ if there are 6 wrong letters

Explanation / Answer

from random import *

FOUR = 4

class Hangman:

# --------------------------------------------------------------------------
# Constructor
def __init__(self):
self.__theWord = ''
self.__indexList = []
self.__answer = '_ _ _ _ _ _'
# ---------------------------------------------------------------------------
# Accessors
def getTheWord(self):
return self.__theWord
def getIndexList(self):
return self.__indexList
def getAnswer(self):
return self.__answer
def startFruit(self):
randNumber = randint(0,FOUR)
fruit = open("fruits.txt", 'r')
fruitList = fruit.read().splitlines()
self.__theWord = fruitList[randNumber]
return self.__theWord
def startVege(self):
randNumber = randint(0,FOUR)
vege = open("veges.txt", 'r')
vegeList = vege.read().splitlines()
self.__theWord = vegeList[randNumber]
return self.__theWord
def startName(self):
randNumber = randint(0,FOUR)
name = open("names.txt", 'r')
nameList = name.read().splitlines()
self.__theWord = nameList[randNumber]
return self.__theWord
# --------------------------------------------------------------------------
# Mutators
def find(self, answerWord, inputLetter):
if inputLetter in answerWord:
self.__indexList = [index for index, letter in enumerate(answerWord) if letter == inputLetter]
else:
self.__indexList = []

def set (self, inputLetter):
newString = ""
textList = list(self.__answer)
self.__indexList = self.getIndexList()
location = self.__indexList
for aNum in location:
textList[aNum * 2] = inputLetter
newString = ''.join(textList)
self.__answer = newString

def reset(self):
self.__answer = '_ _ _ _ _ _'
# --------------------------------------------------------------------------
# toString()
def__str__(self):
return "Current answer is: %s" % self.__answer

'''
def main():
game = Hangman()
keyWord = game.startFruit()
letter = input("enter letter")
while letter:
game.find(keyWord, letter)
game.set(letter)
print(game)
letter = input("enter letter")
main()
--------------------------------------------------------------------------------------------------------------------

HangmanGUI.py
------------------
from tkinter import *
from random import *
from hangman import *

FOUR = 4
class HangmanUI(Frame):

def __init__(self):
Frame.__init__(self)
self.master.title("Hangman")
self.grid()
self.__label = Label(self, text = "Let's play Hangman!")
self.__label2 = Label(self, text = "Please choose a category!")
self.__label2.grid(row = 1, column = 0)
self.__buttonPane = Frame(self)
self.__buttonPane.grid(row = 2, column = 0)
# created a model of the hangman class
self.__ans = Hangman()
self.__fruitButton= Button(self.__buttonPane, text = 'Fruits', command = self.startFruit)
self.__nameButton = Button(self.__buttonPane, text = 'Names' , command = self.startName)
self.__vegeButton = Button(self.__buttonPane, text = 'Veges', command = self.startVege)
self.__fruitButton.grid(row = 2, column = 0)
self.__vegeButton.grid(row = 2, column = 1)
self.__nameButton.grid(row = 2, column = 2)
self.__label.grid(row = 0 , column = 0)
#to change later so if shuffles images 1-10 with each error (for loop)
self.__image = PhotoImage(file = "0.gif")
self.__imageLabel = Label(self, image = self.__image)
self.__imageLabel.grid(row = 3, column = 0)
self.__letterLabel = Label(self, text = "Please submit a letter to play!")
# instead of the submit button, tried using enter instead for now
self.__letterVar= StringVar()
#self.__letterEntry = Entry(self, textvariable = self.__letterVar) # commented out this line, maybe i shouldn't have?
self.__letterEntry = Entry(self, width = 10)
self.__letterEntry.bind('<Return>', self.set)
self.__letterLabel.grid(row = 4, column = 0)
self.__letterEntry.grid(row = 5, column = 0)

self.__value = Label(self, textvariable = self.__letterVar)
self.__value.grid(row= 6, column = 0)


#creates nested frame
self.__letterPane = Frame(self)
self.__letterPane.grid(row = 7, column = 0)
self.__letter1 = Label(self.__letterPane, text = '_ _ _ _ _ _')
self.__letter1.grid(row = 7, column = 0)
def startFruit(self):
self.__ans.startFruit()
def startVege(self):
self.__ans.startVege()
def startName(self):
self.__ans.startName()
def set(self,event):
guessWord = self.__ans.getTheWord()
entryLetter = self.__letterEntry.get()
self.__ans.find(guessWord, entryLetter)
newValue = self.__letterEntry.get()
self.__ans.set(newValue)
# display new value in letterVar
# this is where the program crashes
self.__letterVar.set(self.__ans.getAnswer())
# invoke delete() to clear entry box
self.__letterEntry.delete(0,END)


def main():
HangmanUI().mainloop()
main()