3
\$\begingroup\$

Having too much spare time during the quarantine I learned some basic python (plus tkinter for GUI) and made a little HangMan game :) Would love any feedback for improvement. Thank you.

import os
import random
from tkinter import *
from PIL import ImageTk, Image
from tkinter import messagebox
import pygame
# Window settings
root = Tk()
root.title("HangMan")
root.iconbitmap("images/icon.ico")
root.geometry("800x400")
root.resizable(width=False, height=False)
def disable_event():
 pass
root.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
pygame.mixer.init()
music_state = False
def play_music():
 global music_state
 if not music_state:
 pygame.mixer.music.load("music/The Witcher 3 OST.mp3")
 pygame.mixer.music.play(loops=0)
 music_state = True
 else:
 pygame.mixer.music.stop()
 music_state = False
def main_menu_():
 root.deiconify()
 global main_menu_bg
 global letter_change
 letter_change = 1
 global word_change
 word_change = 2
 # Create canvas and add background
 canvas = Canvas(root, width="800", height="450")
 canvas.pack()
 main_menu_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas.background = main_menu_bg
 canvas.create_image(0, 0, anchor=NW, image=main_menu_bg)
 # Add buttons to canvas
 start_btn = Button(root, text="New Game", width=15, command=new_game, borderwidth=5)
 canvas.create_window(400, 150, anchor=CENTER, window=start_btn)
 score_btn = Button(root, text="Score Board", width=15, command=score_board, borderwidth=5)
 canvas.create_window(400, 210, anchor=CENTER, window=score_btn)
 quit_btn = Button(root, text="Quit", width=15, command=quit_game, borderwidth=5)
 canvas.create_window(400, 270, anchor=CENTER, window=quit_btn)
 music_btn = Button(root, text="Music", command=play_music)
 canvas.create_window(770, 380, anchor=CENTER, window=music_btn)
def new_game():
 root.withdraw() # Hide root window, to make it visible again use root.deiconify()
 global new_game_bg
 global new_game_window
 new_game_window = Toplevel()
 new_game_window.title("HangMan")
 new_game_window.iconbitmap("images/icon.ico")
 new_game_window.geometry("800x400")
 new_game_window.resizable(width=False, height=False)
 new_game_window.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
 # Create canvas and add background
 canvas_new_game = Canvas(new_game_window, width="800", height="450")
 canvas_new_game.pack()
 new_game_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_new_game.background = new_game_bg
 canvas_new_game.create_image(0, 0, anchor=NW, image=new_game_bg)
 instructions_lbl = Label(new_game_window, text="There are 4 different categories.\n"
 "Choose as many as you'd like,"
 "\nbut do choose wisely, this is not going to be easy!",
 bg="#a5a0b6")
 canvas_new_game.create_window(400, 60, anchor=CENTER, window=instructions_lbl)
 # Will help knowing which categories were chosen
 var1 = StringVar(value="")
 var2 = StringVar(value="")
 var3 = StringVar(value="")
 var4 = StringVar(value="")
 anime_btn = Checkbutton(new_game_window, text="Anime", variable=var1, onvalue="a", offvalue="")
 canvas_new_game.create_window(340, 120, anchor=CENTER, window=anime_btn)
 games_btn = Checkbutton(new_game_window, text="Games", variable=var2, onvalue="g", offvalue="")
 canvas_new_game.create_window(440, 120, anchor=CENTER, window=games_btn)
 movies_btn = Checkbutton(new_game_window, text="Movies", variable=var3, onvalue="m", offvalue="")
 canvas_new_game.create_window(340, 170, anchor=CENTER, window=movies_btn)
 tv_btn = Checkbutton(new_game_window, text="TV-Shows", variable=var4, onvalue="t", offvalue="")
 canvas_new_game.create_window(440, 170, anchor=CENTER, window=tv_btn)
 start_new_game_btn = Button(new_game_window, text="Start new game", width=15,
 command=lambda: [prepare(var1.get() + var2.get() + var3.get() + var4.get())]
 , borderwidth=5)
 canvas_new_game.create_window(390, 220, anchor=CENTER, window=start_new_game_btn)
 back_menu_btn = Button(new_game_window, text="Main Menu", width=15, command=lambda: [main_menu_(),
 new_game_window.destroy()]
 , borderwidth=5)
 canvas_new_game.create_window(390, 260, anchor=CENTER, window=back_menu_btn)
 # quit_game_btn = Button(new_game_window, text="Quit game", width=15, command=quit_game)
 # canvas_new_game.create_window(390, 300, anchor=CENTER, window=quit_game_btn)
 music_btn = Button(new_game_window, text="Music", command=play_music)
 canvas_new_game.create_window(770, 380, anchor=CENTER, window=music_btn)
# choice variable will contain the user's wanted category for the game
def prepare(choice):
 global count_lines
 # Create file of words
 movies = open("movies list.txt", "r") # Open word files
 games = open("games list.txt", "r")
 tv = open("tv list.txt", "r")
 anime = open("anime list.txt", "r")
 categories = ""
 file = open("temp.txt", "a+") # File which will contain words from chosen categories
 if "a" or "g" or "m" or "t" in choice:
 if "m" in choice:
 categories += "Movies / "
 for i in movies.readlines():
 file.write(i)
 if "g" in choice:
 categories += "Games / "
 for j in games.readlines():
 file.write(j)
 if "t" in choice:
 categories += "TV-Shows / "
 for k in tv.readlines():
 file.write(k)
 if "a" in choice:
 categories += "Anime / "
 for t in anime.readlines():
 file.write(t)
 categories = categories[0:-3] # Will go in label
 movies.close() # Close word files
 anime.close()
 tv.close()
 games.close()
 file.close()
 # Get lines count
 categories_file = open("temp.txt", "r")
 count_lines = get_lines_count(categories_file)
 categories_file.close()
 # Get random word to guess
 random_num = random.randint(1, count_lines) # Get a random integer
 word_to_guess = get_word(random_num)
 word_to_guess = word_to_guess[0:-1] # Remove the "\n" char
 # Count word chars
 chars_count = get_chars_count(list(word_to_guess))
 # Create a variable same length as word to guess but made from _
 under_lines_guess = hide_word(word_to_guess)
 play(under_lines_guess, word_to_guess, chars_count)
def hide_word(word):
 hidden = ""
 for hide in range(len(word)): # for 0 in (x-1)
 if word[hide] == " ":
 hidden += " "
 else:
 hidden += "_"
 return hidden
def get_chars_count(count_chars):
 counter_chars = 0
 for index in count_chars:
 if index != " ":
 counter_chars += 1
 return counter_chars
def get_lines_count(file):
 return sum(1 for line in file) # For each line count 1+1+...
def get_word(random_number):
 global count_lines
 f = open("temp.txt", "r")
 lines = f.readlines()
 ret = lines[random_number - 1]
 f.close()
 f_new = open("temp.txt", "w")
 for line in lines: # Write all lines to the file except the one with the word used
 if line != lines[random_number - 1]:
 f_new.write(line)
 f_new.close()
 count_lines -= 1 # Since one line is gone (used and deleted)
 return ret
def close_window():
 option_window.destroy()
def option_a():
 global count_lines
 global word_change
 global letter_change
 if word_change <= 0:
 messagebox.showwarning("Used it all", "You used all of your word change options!")
 option_window.destroy()
 return
 # Get random word to guess
 random_num = random.randint(1, count_lines) # Get a random integer
 word_to_guess = get_word(random_num)
 word_to_guess = word_to_guess[0:-1] # Remove the "\n" char
 # Count word chars
 chars_count = get_chars_count(list(word_to_guess))
 # Create a variable same length as word to guess but made from _
 under_lines_guess = hide_word(word_to_guess)
 word_change -= 1
 play_window.destroy()
 option_window.destroy()
 play(under_lines_guess, word_to_guess, chars_count)
def option_b():
 global chars_bank
 global counter
 global letter_change
 if letter_change <= 0:
 messagebox.showwarning("Used it all", "You used all of your letter helper options!")
 option_window.destroy()
 return
 answer_b = list(wordd) # When done, do - "".join(list to join as string)
 upper_word = wordd.upper()
 upper_word_list_b = list(upper_word)
 len_wordd = len(wordd) - 1
 used_check = True
 while used_check:
 random_num = random.randint(0, len_wordd)
 char_reveal = wordd[random_num-1]
 if char_reveal not in chars_bank:
 chars_bank += char_reveal
 while char_reveal.upper() in str(answer_b).upper():
 print(char_reveal.upper() + str(answer_b).upper())
 i = upper_word_list_b.index(char_reveal.upper()) # Change input char and it's duplicates
 under_lines[i] = answer_b[i]
 answer_b[i] = " "
 upper_word_list_b[i] = " "
 counter -= 1
 if counter == 0:
 messagebox.showinfo("WINNER", "You win!!!")
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 option_window.destroy()
 root.deiconify()
 used_check = False
 letter_change -= 1
 list_chars_bank_ = list(chars_bank)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank_).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
 option_window.destroy()
def assistance():
 global word_change
 global letter_change
 global option_window
 if word_change == 0 and letter_change == 0:
 messagebox.showinfo("Assistance menu", "You don't have any more assistance options to use.")
 else:
 option_window = Toplevel()
 option_window.title("Assistance menu")
 option_window.iconbitmap("images/icon.ico")
 option_window.geometry("270x219")
 option_window.resizable(width=False, height=False)
 option_window.attributes("-topmost", "true")
 # Create canvas and add background
 canvas_option = Canvas(option_window, width="270", height="219")
 canvas_option.pack()
 option_bg = ImageTk.PhotoImage(Image.open("images/choosewisely.jpg").resize((270, 219), Image.ANTIALIAS))
 canvas_option.background = option_bg
 canvas_option.create_image(0, 0, anchor=NW, image=option_bg)
 option_text = ("Choose an option:\nA) Change word (uses left: " + str(word_change)
 + ")\nB) Letter helper (uses left: " + str(letter_change) + ")")
 option_lbl = Label(option_window, text=option_text)
 canvas_option.create_window(135, 55, anchor=CENTER, window=option_lbl)
 option_a_btn = Button(option_window, text="Option A", borderwidth=5, command=option_a)
 canvas_option.create_window(85, 150, anchor=CENTER, window=option_a_btn)
 option_b_btn = Button(option_window, text="Option B", borderwidth=5, command=option_b)
 canvas_option.create_window(185, 150, anchor=CENTER, window=option_b_btn)
 cancel_btn = Button(option_window, text="Nah... I don't need any help", borderwidth=5,
 command=close_window)
 canvas_option.create_window(135, 195, anchor=CENTER, window=cancel_btn)
def my_answer():
 global chars_bank
 global wordd
 global counter
 global guesses
 global list_chars_bank
 global under_lines
 if e.get()[0:1] in "\n =+-*/.`~!@#$%^&*()_,';:":
 messagebox.showwarning("Illegal input",
 "Input is illegal. Enter a character in the range of (a-z) and (0-9)")
 e.delete(0, "end")
 return
 if e.get()[0:1] in chars_bank:
 messagebox.showwarning("Illegal input",
 "Input was used before.")
 e.delete(0, "end")
 return
 else:
 len_align = (len(chars_bank) + 1) % 10
 if len_align == 0:
 chars_bank += "\n"
 chars_bank += e.get()[0:1]
 if e.get()[0:1].upper() in str(answer).upper(): # upper in order to ignore if the letter is written
 while e.get()[0:1].upper() in str(answer).upper(): # Check if its there more than once
 i = upper_word_list.index(e.get()[0:1].upper()) # Returns index of the letter guessed
 under_lines[i] = answer[i]
 answer[i] = " "
 upper_word_list[i] = " "
 counter -= 1
 if counter == 0:
 messagebox.showinfo("WINNER", "You win!!!")
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 root.deiconify()
 else:
 guesses -= 1
 if guesses == 4:
 play_bg4 = ImageTk.PhotoImage(Image.open("images/4guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg4
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg4)
 if guesses == 3:
 play_bg3 = ImageTk.PhotoImage(Image.open("images/3guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg3
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg3)
 if guesses == 2:
 play_bg2 = ImageTk.PhotoImage(Image.open("images/2guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg2
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg2)
 if guesses == 1:
 play_bg1 = ImageTk.PhotoImage(Image.open("images/1guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg1
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg1)
 if guesses == 0:
 play_bg0 = ImageTk.PhotoImage(Image.open("images/0guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg0
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg0)
 messagebox.showinfo("LOSER", "You lose!\nThe word was: " + wordd)
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 root.deiconify()
 e.delete(0, "end")
 # letters_left_lbl = Label(play_window, text=str(counter) + " letters left to solve the word")
 # canvas_play.create_window(400, 370, anchor=CENTER, window=letters_left_lbl)
 #
 list_chars_bank = list(chars_bank)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
def play(hidden, word, count):
 new_game_window.withdraw()
 global play_bg
 global play_window
 global canvas_play
 global chars_bank
 global e
 global answer
 global upper_word_list
 global under_lines
 global wordd
 wordd = word
 global guesses
 guesses = 5
 global counter
 counter = count
 global list_chars_bank
 chars_bank = ""
 list_chars_bank = list(chars_bank)
 global word_change
 global letter_change
 play_window = Toplevel()
 play_window.title("HangMan")
 play_window.iconbitmap("images/icon.ico")
 play_window.geometry("800x400")
 play_window.resizable(width=False, height=False)
 play_window.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
 # Create canvas and add background
 canvas_play = Canvas(play_window, width="800", height="450")
 canvas_play.pack()
 play_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg)
 under_lines = list(hidden) # Will make it easier to change chars in string
 answer = list(word) # When done, do - "".join(list to join as string)
 upper_word = word.upper()
 upper_word_list = list(upper_word)
 chars_bank = ""
 # letters_left_lbl = Label(play_window, text=str(counter) + " letters left to solve the word")
 # canvas_play.create_window(400, 370, anchor=CENTER, window=letters_left_lbl)
 #
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 back_menu_btn_ = Button(play_window, text="Main Menu", borderwidth=5, width=15,
 command=lambda: [main_menu_(),
 play_window.destroy(),
 new_game_window.destroy()])
 canvas_play.create_window(70, 370, anchor=CENTER, window=back_menu_btn_)
 e = Entry(play_window, width=4, borderwidth=2)
 canvas_play.create_window(380, 250, anchor=CENTER, window=e)
 assistance_btn = Button(play_window, text="Other options", width=15, borderwidth=5, command=assistance)
 canvas_play.create_window(70, 30, anchor=CENTER, window=assistance_btn)
 input_answer = Button(play_window, text="Confirm", command=my_answer, borderwidth=5)
 canvas_play.create_window(430, 250, anchor=CENTER, window=input_answer)
 music_btn = Button(play_window, text="Music", command=play_music)
 canvas_play.create_window(770, 380, anchor=CENTER, window=music_btn)
def score_board():
 return
def quit_game():
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 root.destroy()
main_menu_() # Start game
root.mainloop()

If needed, image are below: enter image description here enter image description here enter image description here enter image description here enter image description here enter image description here link to the music file, link to the ico image

Heslacher
50.9k5 gold badges83 silver badges177 bronze badges
asked Oct 6, 2020 at 23:45
\$\endgroup\$
1
  • 2
    \$\begingroup\$ I have rolled back your latest edit. Please do not update the code in your question to incorporate feedback from answers, doing so goes against the Question + Answer style of Code Review. This is not a forum where you should keep the most updated version in your question. Please see what you may and may not do after receiving answers . \$\endgroup\$ Commented Oct 7, 2020 at 10:02

2 Answers 2

2
\$\begingroup\$

Code/Logic

 if not music_state:
 pygame.mixer.music.load("music/The Witcher 3 OST.mp3")
 pygame.mixer.music.play(loops=0)
 music_state = True
 else:
 pygame.mixer.music.stop()
 music_state = False

This is backwards. Since you're handling both cases, the natural thing to do would be

if music_state:
 pygame.mixer.music.stop()
 music_state = False
else:
 pygame.mixer.music.load("music/The Witcher 3 OST.mp3")
 pygame.mixer.music.play(loops=0)
 music_state = True

But also, you're flipping the music_state in both cases, so you can take that out and rather move it after the if-else and do

music_state = not music_state
answered Oct 7, 2020 at 8:33
\$\endgroup\$
1
\$\begingroup\$

I changed the if statements of music_state as was answered. Also, I've noticed that if the user lost the game and wishes to play again, the assistance options (letter change and word change) don't reset, so added:

word_change = 2
letter_change = 1

in the methods which handles losing. Another issue is that when using option b (letter helper) the loop had issues on two occasions, if the answer contained more than one word then if the " " is chosen randomly as the letter helper, the loop will become infinite, and the second issue is if the word contained for example an upper and lower "A", then if the loop chooses "a", it won't handle the upper case "A". Below is the new code:

import os
import random
from tkinter import *
from PIL import ImageTk, Image
from tkinter import messagebox
import pygame
# Window settings
root = Tk()
root.title("HangMan")
root.iconbitmap("images/icon.ico")
root.geometry("800x400")
root.resizable(width=False, height=False)
def disable_event():
 pass
root.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
pygame.mixer.init()
music_state = False
def play_music():
 global music_state
 if music_state:
 pygame.mixer.music.stop()
 else:
 pygame.mixer.music.load("music/The Witcher 3 OST.mp3")
 pygame.mixer.music.play(loops=0)
 music_state = not music_state
def main_menu_():
 root.deiconify()
 global main_menu_bg
 global letter_change
 letter_change = 1
 global word_change
 word_change = 2
 # Create canvas and add background
 canvas = Canvas(root, width="800", height="450")
 canvas.pack()
 main_menu_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas.background = main_menu_bg
 canvas.create_image(0, 0, anchor=NW, image=main_menu_bg)
 # Add buttons to canvas
 start_btn = Button(root, text="New Game", width=15, command=new_game, borderwidth=5)
 canvas.create_window(400, 150, anchor=CENTER, window=start_btn)
 score_btn = Button(root, text="Score Board", width=15, command=score_board, borderwidth=5)
 canvas.create_window(400, 210, anchor=CENTER, window=score_btn)
 quit_btn = Button(root, text="Quit", width=15, command=quit_game, borderwidth=5)
 canvas.create_window(400, 270, anchor=CENTER, window=quit_btn)
 music_btn = Button(root, text="Music", command=play_music)
 canvas.create_window(770, 380, anchor=CENTER, window=music_btn)
def new_game():
 root.withdraw() # Hide root window, to make it visible again use root.deiconify()
 global new_game_bg
 global new_game_window
 new_game_window = Toplevel()
 new_game_window.title("HangMan")
 new_game_window.iconbitmap("images/icon.ico")
 new_game_window.geometry("800x400")
 new_game_window.resizable(width=False, height=False)
 new_game_window.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
 # Create canvas and add background
 canvas_new_game = Canvas(new_game_window, width="800", height="450")
 canvas_new_game.pack()
 new_game_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_new_game.background = new_game_bg
 canvas_new_game.create_image(0, 0, anchor=NW, image=new_game_bg)
 instructions_lbl = Label(new_game_window, text="There are 4 different categories.\n"
 "Choose as many as you'd like,"
 "\nbut do choose wisely, this is not going to be easy!",
 bg="#a5a0b6")
 canvas_new_game.create_window(400, 60, anchor=CENTER, window=instructions_lbl)
 # Will help knowing which categories were chosen
 var1 = StringVar(value="")
 var2 = StringVar(value="")
 var3 = StringVar(value="")
 var4 = StringVar(value="")
 anime_btn = Checkbutton(new_game_window, text="Anime", variable=var1, onvalue="a", offvalue="")
 canvas_new_game.create_window(340, 120, anchor=CENTER, window=anime_btn)
 games_btn = Checkbutton(new_game_window, text="Games", variable=var2, onvalue="g", offvalue="")
 canvas_new_game.create_window(440, 120, anchor=CENTER, window=games_btn)
 movies_btn = Checkbutton(new_game_window, text="Movies", variable=var3, onvalue="m", offvalue="")
 canvas_new_game.create_window(340, 170, anchor=CENTER, window=movies_btn)
 tv_btn = Checkbutton(new_game_window, text="TV-Shows", variable=var4, onvalue="t", offvalue="")
 canvas_new_game.create_window(440, 170, anchor=CENTER, window=tv_btn)
 start_new_game_btn = Button(new_game_window, text="Start new game", width=15,
 command=lambda: [prepare(var1.get() + var2.get() + var3.get() + var4.get())]
 , borderwidth=5)
 canvas_new_game.create_window(390, 220, anchor=CENTER, window=start_new_game_btn)
 back_menu_btn = Button(new_game_window, text="Main Menu", width=15, command=lambda: [main_menu_(),
 new_game_window.destroy()]
 , borderwidth=5)
 canvas_new_game.create_window(390, 260, anchor=CENTER, window=back_menu_btn)
 # quit_game_btn = Button(new_game_window, text="Quit game", width=15, command=quit_game)
 # canvas_new_game.create_window(390, 300, anchor=CENTER, window=quit_game_btn)
 music_btn = Button(new_game_window, text="Music", command=play_music)
 canvas_new_game.create_window(770, 380, anchor=CENTER, window=music_btn)
# choice variable will contain the user's wanted category for the game
def prepare(choice):
 global count_lines
 # Create file of words
 movies = open("movies list.txt", "r") # Open word files
 games = open("games list.txt", "r")
 tv = open("tv list.txt", "r")
 anime = open("anime list.txt", "r")
 categories = ""
 file = open("temp.txt", "a+") # File which will contain words from chosen categories
 if "a" or "g" or "m" or "t" in choice:
 if "m" in choice:
 categories += "Movies / "
 for i in movies.readlines():
 file.write(i)
 if "g" in choice:
 categories += "Games / "
 for j in games.readlines():
 file.write(j)
 if "t" in choice:
 categories += "TV-Shows / "
 for k in tv.readlines():
 file.write(k)
 if "a" in choice:
 categories += "Anime / "
 for t in anime.readlines():
 file.write(t)
 categories = categories[0:-3] # Will go in label
 movies.close() # Close word files
 anime.close()
 tv.close()
 games.close()
 file.close()
 # Get lines count
 categories_file = open("temp.txt", "r")
 count_lines = get_lines_count(categories_file)
 categories_file.close()
 # Get random word to guess
 random_num = random.randint(1, count_lines) # Get a random integer
 word_to_guess = get_word(random_num)
 word_to_guess = word_to_guess[0:-1] # Remove the "\n" char
 # Count word chars
 chars_count = get_chars_count(list(word_to_guess))
 # Create a variable same length as word to guess but made from _
 under_lines_guess = hide_word(word_to_guess)
 play(under_lines_guess, word_to_guess, chars_count)
def hide_word(word):
 hidden = ""
 for hide in range(len(word)): # for 0 in (x-1)
 if word[hide] == " ":
 hidden += " "
 else:
 hidden += "_"
 return hidden
def get_chars_count(count_chars):
 counter_chars = 0
 for index in count_chars:
 if index != " ":
 counter_chars += 1
 return counter_chars
def get_lines_count(file):
 return sum(1 for line in file) # For each line count 1+1+...
def get_word(random_number):
 global count_lines
 f = open("temp.txt", "r")
 lines = f.readlines()
 ret = lines[random_number - 1]
 f.close()
 f_new = open("temp.txt", "w")
 for line in lines: # Write all lines to the file except the one with the word used
 if line != lines[random_number - 1]:
 f_new.write(line)
 f_new.close()
 count_lines -= 1 # Since one line is gone (used and deleted)
 return ret
def close_window():
 option_window.destroy()
def option_a():
 global count_lines
 global word_change
 global letter_change
 if word_change <= 0:
 messagebox.showwarning("Used it all", "You used all of your word change options!")
 option_window.destroy()
 return
 # Get random word to guess
 random_num = random.randint(1, count_lines) # Get a random integer
 word_to_guess = get_word(random_num)
 word_to_guess = word_to_guess[0:-1] # Remove the "\n" char
 # Count word chars
 chars_count = get_chars_count(list(word_to_guess))
 # Create a variable same length as word to guess but made from _
 under_lines_guess = hide_word(word_to_guess)
 word_change -= 1
 play_window.destroy()
 option_window.destroy()
 play(under_lines_guess, word_to_guess, chars_count)
def option_b():
 global chars_bank
 global counter
 global letter_change
 global word_change
 if letter_change <= 0:
 messagebox.showwarning("Used it all", "You used all of your letter helper options!")
 option_window.destroy()
 return
 answer_b = list(wordd) # When done, do - "".join(list to join as string)
 upper_word = wordd.upper()
 upper_word_list_b = list(upper_word)
 len_wordd = len(wordd) - 1
 used_check = True
 while used_check:
 random_num = random.randint(0, len_wordd)
 char_reveal = wordd[random_num]
 if char_reveal.upper() not in str(chars_bank).upper() and char_reveal not in " ":
 chars_bank += char_reveal
 while char_reveal.upper() in str(answer_b).upper():
 # print(char_reveal.upper() + str(answer_b).upper())
 i = upper_word_list_b.index(char_reveal.upper()) # Change input char and it's duplicates
 under_lines[i] = answer_b[i]
 answer_b[i] = " "
 upper_word_list_b[i] = " "
 counter -= 1
 if counter == 0:
 messagebox.showinfo("WINNER", "You win!!!")
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 letter_change = 1 # Initialize after user loses
 word_change = 2
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 option_window.destroy()
 root.deiconify()
 used_check = False
 letter_change -= 1
 list_chars_bank_ = list(chars_bank)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank_).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
 option_window.destroy()
def assistance():
 global word_change
 global letter_change
 global option_window
 if word_change == 0 and letter_change == 0:
 messagebox.showinfo("Assistance menu", "You don't have any more assistance options to use.")
 else:
 option_window = Toplevel()
 option_window.title("Assistance menu")
 option_window.iconbitmap("images/icon.ico")
 option_window.geometry("270x219")
 option_window.resizable(width=False, height=False)
 option_window.attributes("-topmost", "true")
 # Create canvas and add background
 canvas_option = Canvas(option_window, width="270", height="219")
 canvas_option.pack()
 option_bg = ImageTk.PhotoImage(Image.open("images/choosewisely.jpg").resize((270, 219), Image.ANTIALIAS))
 canvas_option.background = option_bg
 canvas_option.create_image(0, 0, anchor=NW, image=option_bg)
 option_text = ("Choose an option:\nA) Change word (uses left: " + str(word_change)
 + ")\nB) Letter helper (uses left: " + str(letter_change) + ")")
 option_lbl = Label(option_window, text=option_text)
 canvas_option.create_window(135, 55, anchor=CENTER, window=option_lbl)
 option_a_btn = Button(option_window, text="Option A", borderwidth=5, command=option_a)
 canvas_option.create_window(85, 150, anchor=CENTER, window=option_a_btn)
 option_b_btn = Button(option_window, text="Option B", borderwidth=5, command=option_b)
 canvas_option.create_window(185, 150, anchor=CENTER, window=option_b_btn)
 cancel_btn = Button(option_window, text="Nah... I don't need any help", borderwidth=5,
 command=close_window)
 canvas_option.create_window(135, 195, anchor=CENTER, window=cancel_btn)
def my_answer():
 global chars_bank
 global wordd
 global counter
 global guesses
 global list_chars_bank
 global under_lines
 global word_change
 global letter_change
 if e.get()[0:1] in "\n =+-*/.`~!@#$%^&*()_,';:":
 messagebox.showwarning("Illegal input",
 "Input is illegal. Enter a character in the range of (a-z) and (0-9)")
 e.delete(0, "end")
 return
 if e.get()[0:1] in chars_bank:
 messagebox.showwarning("Illegal input",
 "Input was used before.")
 e.delete(0, "end")
 return
 else:
 len_align = (len(chars_bank) + 1) % 10
 if len_align == 0:
 chars_bank += "\n"
 chars_bank += e.get()[0:1]
 if e.get()[0:1].upper() in str(answer).upper(): # upper in order to ignore if the letter is written
 while e.get()[0:1].upper() in str(answer).upper(): # Check if its there more than once
 i = upper_word_list.index(e.get()[0:1].upper()) # Returns index of the letter guessed
 under_lines[i] = answer[i]
 answer[i] = " "
 upper_word_list[i] = " "
 counter -= 1
 if counter == 0:
 messagebox.showinfo("WINNER", "You win!!!")
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 root.deiconify()
 else:
 guesses -= 1
 if guesses == 4:
 play_bg4 = ImageTk.PhotoImage(Image.open("images/4guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg4
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg4)
 if guesses == 3:
 play_bg3 = ImageTk.PhotoImage(Image.open("images/3guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg3
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg3)
 if guesses == 2:
 play_bg2 = ImageTk.PhotoImage(Image.open("images/2guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg2
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg2)
 if guesses == 1:
 play_bg1 = ImageTk.PhotoImage(Image.open("images/1guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg1
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg1)
 if guesses == 0:
 play_bg0 = ImageTk.PhotoImage(Image.open("images/0guesses.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg0
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg0)
 messagebox.showinfo("LOSER", "You lose!\nThe word was: " + wordd)
 answer_ = messagebox.askyesno("HangMan", "Would you like to play again?")
 if answer_ == 0:
 quit_game()
 else:
 word_change = 2
 letter_change = 1
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 new_game_window.destroy()
 play_window.destroy()
 root.deiconify()
 e.delete(0, "end")
 # letters_left_lbl = Label(play_window, text=str(counter) + " letters left to solve the word")
 # canvas_play.create_window(400, 370, anchor=CENTER, window=letters_left_lbl)
 #
 list_chars_bank = list(chars_bank)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
def play(hidden, word, count):
 new_game_window.withdraw()
 global play_bg
 global play_window
 global canvas_play
 global chars_bank
 global e
 global answer
 global upper_word_list
 global under_lines
 global wordd
 wordd = word
 global guesses
 guesses = 5
 global counter
 counter = count
 global list_chars_bank
 chars_bank = ""
 list_chars_bank = list(chars_bank)
 global word_change
 global letter_change
 play_window = Toplevel()
 play_window.title("HangMan")
 play_window.iconbitmap("images/icon.ico")
 play_window.geometry("800x400")
 play_window.resizable(width=False, height=False)
 play_window.protocol("WM_DELETE_WINDOW", disable_event) # Disable window "X" (close) button
 # Create canvas and add background
 canvas_play = Canvas(play_window, width="800", height="450")
 canvas_play.pack()
 play_bg = ImageTk.PhotoImage(Image.open("images/main_bg.jpg").resize((800, 450), Image.ANTIALIAS))
 canvas_play.background = play_bg
 canvas_play.create_image(0, 0, anchor=NW, image=play_bg)
 under_lines = list(hidden) # Will make it easier to change chars in string
 answer = list(word) # When done, do - "".join(list to join as string)
 upper_word = word.upper()
 upper_word_list = list(upper_word)
 chars_bank = ""
 # letters_left_lbl = Label(play_window, text=str(counter) + " letters left to solve the word")
 # canvas_play.create_window(400, 370, anchor=CENTER, window=letters_left_lbl)
 #
 underlines_lbl = Label(play_window, text=" ".join(under_lines))
 canvas_play.create_window(400, 310, anchor=CENTER, window=underlines_lbl)
 guesses_lbl = Label(play_window, text="You have " + str(guesses) + " guesses left")
 canvas_play.create_window(400, 340, anchor=CENTER, window=guesses_lbl)
 bank_lbl = Label(play_window, text="Used characters bank:\n" + " ".join(list_chars_bank).upper())
 canvas_play.create_window(70, 270, anchor=CENTER, window=bank_lbl)
 back_menu_btn_ = Button(play_window, text="Main Menu", borderwidth=5, width=15,
 command=lambda: [main_menu_(),
 play_window.destroy(),
 new_game_window.destroy()])
 canvas_play.create_window(70, 370, anchor=CENTER, window=back_menu_btn_)
 e = Entry(play_window, width=4, borderwidth=2)
 canvas_play.create_window(380, 250, anchor=CENTER, window=e)
 assistance_btn = Button(play_window, text="Other options", width=15, borderwidth=5, command=assistance)
 canvas_play.create_window(70, 30, anchor=CENTER, window=assistance_btn)
 input_answer = Button(play_window, text="Confirm", command=my_answer, borderwidth=5)
 canvas_play.create_window(430, 250, anchor=CENTER, window=input_answer)
 music_btn = Button(play_window, text="Music", command=play_music)
 canvas_play.create_window(770, 380, anchor=CENTER, window=music_btn)
def score_board():
 return
def quit_game():
 if os.path.isfile("temp.txt"): # In case the file was created
 os.remove("temp.txt") # Delete file (no longer needed)
 root.destroy()
main_menu_() # Start game
root.mainloop()
answered Oct 8, 2020 at 0:04
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.