Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import customtkinter as ctk # Importing customtkinter library as ctk
- from CTkMessagebox import CTkMessagebox # Importing CTkMessagebox class from CTkMessagebox module
- import random # Importing random module for random word selection
- import PIL
- from PIL import Image
- from CTkMenuBar import CustomDropdownMenu, CTkTitleMenu # Add this import line
- from CTkMenuBar import *
- class ModernWordleGUI:
- def __init__(self, master, word_list):
- # Initialize the GUI
- self.master = master # Master window
- self.word = random.choice(word_list).upper() # Select a random word from the list and convert it to uppercase
- self.word_list = word_list
- self.attempts = 0 # Initialize attempts counter
- self.current_guess = '' # Initialize current guess
- # Initialize the state of letters (default color)
- self.letters_state = {chr(i): 'light grey' for i in range(65, 91)}
- self.buttons = {} # Dictionary to store letter buttons
- self.master.bind("<Key>", self.key_pressed) # Bind key press event to key_pressed method
- self.master.bind("<Return>", lambda event: self.enter_key()) # Bind return key to enter_key method
- self.master.bind("<BackSpace>", lambda event: self.backspace()) # Bind backspace key to backspace method
- self.setup_gui()
- def setup_gui(self):
- self.master.title("Wordle Game") # Set window title
- image = PIL.Image.open("photo.png")
- background_image = ctk.CTkImage(image, size=(600, 500))
- bg_lbl = ctk.CTkLabel(app, text="", image=background_image)
- bg_lbl.place(x=0, y=0)
- self.master.geometry("310x500") # Set window
- self.guess_grid = [] # Initialize the guess grid
- for k in range(5):
- row = []
- for p in range(5):
- # Create label for displaying guesses
- label = ctk.CTkLabel(self.master, text=' ', font=('Gill Sans MT Condensed', 35), height=56,
- width=56, fg_color='black')
- label.grid(row=k, column=p, padx=3, pady=3) # Grid placement
- row.append(label)
- for i in range(5):
- row = []
- for j in range(5):
- # Create label for displaying guesses
- label = ctk.CTkLabel(self.master, text=' ', font=('Gill Sans MT Condensed', 35), height=50,
- width=50, fg_color='#BDB0B0')
- label.grid(row=i, column=j, padx=3, pady=3) # Grid placement
- row.append(label)
- self.guess_grid.append(row)
- # Setup the keyboard
- self.setup_keyboard() # Call setup_keyboard method
- # Create and place the submit button
- submit_btn = ctk.CTkButton(self.master, text="Submit", command=self.submit_guess,font=('Gill Sans MT Condensed', 18),
- fg_color='#848484', text_color='black')
- submit_btn.grid(row=7, columnspan=5, pady=10) # Grid placement
- self.buttons['Submit'] = submit_btn # Store the submit button in the buttons dictionary with the key 'Submit'
- settings_icon = PIL.Image.open("icon.png")
- settings_photo = ctk.CTkImage(settings_icon)
- setting = ctk.CTkLabel(app, text="", image=settings_photo)
- setting.place(x=0, y=470)
- # Add menu with restart option
- def restart_game(self):
- # Method to restart the game
- self.attempts = 0
- self.current_guess = ''
- self.word = random.choice(self.word_list).upper()
- self.update_guess_display()
- for i in range(5):
- for j in range(5):
- label = self.guess_grid[i][j]
- label.configure(text=' ', fg_color='#BDB0B0') # Reset label text and foreground color
- for button_key, button in self.buttons.items():
- if button_key != 'Submit': # Exclude the "Submit" button
- button.configure(fg_color=self.letters_state[button.cget('text')])
- button.configure(state="normal")
- def key_pressed(self, event):
- # Method to handle key presses for typing letters
- if event.char and event.char.isalpha(): # Check if the pressed key is a valid letter
- letter = event.char.lower() # Get the character of the key that was pressed and convert to lowercase
- self.press_key(letter) # Call press_key method with the pressed letter
- def setup_keyboard(self):
- # Setup the keyboard layout
- keyboard_frame = ctk.CTkFrame(self.master, fg_color='#BDB0B0') # Create keyboard frame
- keyboard_frame.grid(row=6, columnspan=7, pady=15) # Grid placement
- rows = ['QWERTYUIOP', 'ASDFGHJKL', 'ZXCVBNM'] # Define keyboard rows
- for i, row in enumerate(rows):
- frame = ctk.CTkFrame(keyboard_frame, fg_color='transparent') # Create frame for each row
- frame.grid(row=i, pady=5) # Grid placement
- for letter in row:
- # Create button for each letter
- btn = ctk.CTkButton(frame, text=letter, command=lambda l=letter: self.press_key(l),
- font=('Gill Sans MT Condensed', 18), fg_color=self.letters_state[letter], text_color='black', width=13, height=18)
- self.buttons[letter] = btn # Store button in dictionary
- btn.pack(side='left', padx=2) # Pack button into frame
- # Create and place backspace button
- backspace = ctk.CTkButton(frame, text='⌫', text_color='black',fg_color='transparent',command=self.backspace, font=('Gill Sans MT Condensed', 18), width=2, height=1)
- backspace.pack(side='left', padx=2) # Pack backspace button into frame
- def press_key(self, event):
- # Method to handle key presses for typing letters
- if isinstance(event, str): # Check if event is a string (from button click)
- letter = event.lower() # Convert letter to lowercase
- else: # If event is not a string (from key press)
- letter = event.char.lower() # Get the character of the key that was pressed and convert to lowercase
- if len(self.current_guess) < 5:
- self.current_guess += letter # Add pressed letter to current guess
- self.update_guess_display() # Update the display of current guess
- print(self.current_guess, "&&&", " ", letter, " word:", self.word) # Debug print statement
- if len(self.current_guess) == 5: # Check if the length of the current guess is 5
- self.buttons['Submit'].configure(fg_color='#C9C9C9') # Change the color of the submit button to red
- def backspace(self, event=None):
- # Method to handle backspace key press
- if len(self.current_guess) > 0:
- self.current_guess = self.current_guess[:-1] # Remove last character from current guess
- self.update_guess_display() # Update the display of current guess
- def enter_key(self, event=None):
- # Method to handle Enter key press
- self.submit_guess() # Call submit_guess method
- def update_guess_display(self):
- # Method to update the display of current guess
- for i in range(5):
- char = self.current_guess[i].upper() if i < len(
- self.current_guess) else ' ' # Convert character to uppercase
- self.guess_grid[self.attempts][i].configure(text=char) # Update the text of the label
- def submit_guess(self):
- # Method to submit the current guess
- self.buttons['Submit'].configure(fg_color='#848484')
- if len(self.current_guess) == 5: # Check if the current guess is of length 5
- if self.current_guess.lower() in self.word_list: # Check if the guess is in the word list
- self.check_guess(self.current_guess.upper()) # Call check_guess method with the guess in uppercase
- self.current_guess = '' # Reset current guess
- if all(lbl.cget('fg_color') == 'green' for lbl in
- self.guess_grid[self.attempts]): # Check if all labels are green
- self.end_game("Congratulations, you've won!") # Call end_game method with winning message
- elif self.attempts < 4: # Check if attempts are less than 4
- self.attempts += 1 # Increment attempts counter
- else:
- self.end_game(
- f"Game over, the word was {self.word}. You didn't guess the word in time!") # Call end_game method with game over message
- else:
- CTkMessagebox(title="Invalid Guess",
- message="Please enter a valid 5-letter word from the word list.") # Show message box for invalid guess
- def check_guess(self, guess):
- # Method to check the current guess
- guessed_indices = [] # Initialize list to keep track of guessed indices
- for i, char in enumerate(guess):
- if char == self.word[i]:
- # Mark correct letter in the correct position as green
- self.guess_grid[self.attempts][i].configure(fg_color='green')
- self.buttons[char].configure(fg_color='green') # Change button color to green
- guessed_indices.append(i) # Add index to guessed_indices
- elif char in self.word and self.word.index(char) not in guessed_indices:
- # Mark correct letters in the wrong position as yellow
- self.guess_grid[self.attempts][i].configure(fg_color='#B3A036')
- self.buttons[char].configure(fg_color='#A1A636') # Change button color to yellow
- else:
- # Mark incorrect letters as light grey
- self.guess_grid[self.attempts][i].configure(fg_color='#747474')
- self.buttons[char].configure(fg_color='#747474') # Change button color to yellow
- def end_game(self, message):
- # Get yes/no answers
- msg = CTkMessagebox(title="Exit?", message=message,
- option_1="Play again", option_2="Quit",justify= 'center', width=340,height=150,button_width= 50,button_height=30)
- response = msg.get()
- if response == "Quit":
- self.master.destroy()
- else:
- self.restart_game()
- # Removed the duplicate end_game function defined after the class definition
- if __name__ == "__main__":
- app = ctk.CTk() # Create root window using customtkinter
- word_list = []
- with open("words.txt", "r") as words_file:
- lines = words_file.readlines() # Read all lines from the file into a list
- for line in lines:
- word_list.append(
- line.strip()) # Append each line (word) to the word_list after stripping any leading/trailing whitespace
- apps = ModernWordleGUI(app, word_list) # Create game instance
- app.mainloop() # Start the main event loop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement