I was making a wordle game in TKinter in python, when suddenly I ran into an error with the letter matching function (Return green color if letter in word, and in the correct place, if letter in word but not in correct place, return yellow.) started being weird, and I noticed that if I input a query with duplicate letters, but one letter is in the correct place, it will highlict all of the duplicate letters. ie: I input: Boogan
Word is: Loaren
It highlights: Bo(green)o(green)gan(green) It should not highlight the second o because in its place, there is a. Not O.
Code:
import tkinter as tk
import string
import os
import asyncio
import random
import aiofiles
import json
import time
# Constants
WINDOW_WIDTH = 500
WINDOW_HEIGHT = 600
FONT_SIZE = 20
FONT_FAMILY = "Segoe UI"
FRAME_SIZE = 60
STROKE_SIZE = 3
PADY_FRAME = 50
PADX_FRAME = 100
# Integers
guessed = 0
current_guess = 0
is_correct = False
framerow1=None
framerow12 = None
framerow13 = None
framerow14 = None
frame1 = None
frame2 = None
frame3 = None
frame4 = None
frame5 = None
frame12 = None
frame13 = None
frame14 = None
frame22 = None
frame23 = None
frame24 = None
frame32 = None
frame33 = None
frame34 = None
frame42 = None
frame43 = None
frame44 = None
frame52 = None
frame53 = None
frame54 = None
# Variables
word = ""
guessed_letters = []
guessed_words = []
keysin = []
row = 1
frames = []
# Functions
def set_word():
global word
wordsList = 'words.json'
with open(wordsList, 'r') as f:
words = json.loads(f.read())
words = words['words']
while True:
word = random.choice(words)
if len(word) == 5:
break
def validate_word(word: str) -> bool:
return word.isalpha() and len(word) >3
def check_guess(wordGuess: str) -> bool:
return wordGuess == word
def check_matches(wordG: str) -> list:
if word == "":
return False
matchedLetters = []
for h in word:
for g in wordG:
if g == h:
matchedLetters.append(g)
return matchedLetters
def keyed(e):
if not e.char == '\x08':
if not len(keysin) == 5:
keysin.append(e.char)
add_key(e.char)
elif e.char == '\x08':
if not len(keysin) == 0:
keysin.remove(keysin[-1])
add_key(e.char)
def on_enter(d):
global current_guess
f = d
if validate_word(f):
if not check_guess(f):
current_guess -= 1
guessed_words.append(f)
a = check_matches(f)
if len(a)>0:
guessed_letters.extend(a)
set_word()
root = tk.Tk()
root.title("Wordle")
root.geometry(f"{WINDOW_WIDTH}x{WINDOW_HEIGHT}")
root.config(bg="floral white")
root.resizable(False, False)
# Create frame that is as big as the root
framerow1 = tk.Frame(root)
framerow1.grid(row=1, column=1, padx =50)
framerow1.config(bg="floral white")
# Frame one
framebg1 = tk.Frame(framerow1, width=63, height=63)
framebg1.grid(row=1, column=1, pady=10, padx=6)
frame1 = tk.Frame(framerow1, width=60, height=60)
frame1.grid(row=1, column=1, pady = 10, padx=6)
frame1.config(bg="floral white")
# Frame two
framebg2 = tk.Frame(framerow1, width=63, height=63)
framebg2.grid(row=1, column=2, pady=10, padx=6)
frame2 = tk.Frame(framerow1, width=60, height=60)
frame2.grid(row=1, column=2, pady = 10, padx=6)
frame2.config(bg="floral white")
# # Frame three
framebg3 = tk.Frame(framerow1, width=63, height=63)
framebg3.grid(row=1, column=3, pady=10, padx=6)
frame3 = tk.Frame(framerow1, width=60, height=60)
frame3.grid(row=1, column=3, pady = 10, padx=6)
frame3.config(bg="floral white")
# # Frame four
framebg4 = tk.Frame(framerow1, width=63, height=63)
framebg4.grid(row=1, column=4, pady=10, padx=6)
frame4 = tk.Frame(framerow1, width=60, height=60)
frame4.grid(row=1, column=4, pady = 10, padx=6)
frame4.config(bg="floral white")
# # Frame five
framebg5 = tk.Frame(framerow1, width=63, height=63)
framebg5.grid(row=1, column=5, pady=10, padx=6)
frame5 = tk.Frame(framerow1, width=60, height=60)
frame5.grid(row=1, column=5, pady = 10, padx=6)
frame5.config(bg="floral white")
framerow12 = tk.Frame(root)
framerow12.grid(row=2, column=1, padx =50)
framerow12.config(bg="floral white")
# Frame one
framebg12 = tk.Frame(framerow12, width=63, height=63)
framebg12.grid(row=1, column=1, pady=10, padx=6)
frame12 = tk.Frame(framerow12, width=60, height=60)
frame12.grid(row=1, column=1, pady = 10, padx=6)
frame12.config(bg="floral white")
# Frame two
framebg22 = tk.Frame(framerow12, width=63, height=63)
framebg22.grid(row=1, column=2, pady=10, padx=6)
frame22 = tk.Frame(framerow12, width=60, height=60)
frame22.grid(row=1, column=2, pady = 10, padx=6)
frame22.config(bg="floral white")
# # Frame three
framebg32 = tk.Frame(framerow12, width=63, height=63)
framebg32.grid(row=1, column=3, pady=10, padx=6)
frame32 = tk.Frame(framerow12, width=60, height=60)
frame32.grid(row=1, column=3, pady = 10, padx=6)
frame32.config(bg="floral white")
# # Frame four
framebg42 = tk.Frame(framerow12, width=63, height=63)
framebg42.grid(row=1, column=4, pady=10, padx=6)
frame42 = tk.Frame(framerow12, width=60, height=60)
frame42.grid(row=1, column=4, pady = 10, padx=6)
frame42.config(bg="floral white")
# # Frame five
framebg52 = tk.Frame(framerow12, width=63, height=63)
framebg52.grid(row=1, column=5, pady=10, padx=6)
frame52 = tk.Frame(framerow12, width=60, height=60)
frame52.grid(row=1, column=5, pady = 10, padx=6)
frame52.config(bg="floral white")
framerow13 = tk.Frame(root)
framerow13.grid(row=3, column=1, padx =50)
framerow13.config(bg="floral white")
# Frame one
framebg13 = tk.Frame(framerow13, width=63, height=63)
framebg13.grid(row=1, column=1, pady=10, padx=6)
frame13 = tk.Frame(framerow13, width=60, height=60)
frame13.grid(row=1, column=1, pady = 10, padx=6)
frame13.config(bg="floral white")
# Frame two
framebg23 = tk.Frame(framerow13, width=63, height=63)
framebg23.grid(row=1, column=2, pady=10, padx=6)
frame23 = tk.Frame(framerow13, width=60, height=60)
frame23.grid(row=1, column=2, pady = 10, padx=6)
frame23.config(bg="floral white")
# # Frame three
framebg33 = tk.Frame(framerow13, width=63, height=63)
framebg33.grid(row=1, column=3, pady=10, padx=6)
frame33 = tk.Frame(framerow13, width=60, height=60)
frame33.grid(row=1, column=3, pady = 10, padx=6)
frame33.config(bg="floral white")
# # Frame four
framebg43 = tk.Frame(framerow13, width=63, height=63)
framebg43.grid(row=1, column=4, pady=10, padx=6)
frame43 = tk.Frame(framerow13, width=60, height=60)
frame43.grid(row=1, column=4, pady = 10, padx=6)
frame43.config(bg="floral white")
# # Frame five
framebg53 = tk.Frame(framerow13, width=63, height=63)
framebg53.grid(row=1, column=5, pady=10, padx=6)
frame53 = tk.Frame(framerow13, width=60, height=60)
frame53.grid(row=1, column=5, pady = 10, padx=6)
frame53.config(bg="floral white")
framerow14 = tk.Frame(root)
framerow14.grid(row=4, column=1, padx =50)
framerow14.config(bg="floral white")
# Frame one
framebg14 = tk.Frame(framerow14, width=63, height=63)
framebg14.grid(row=1, column=1, pady=10, padx=6)
frame14 = tk.Frame(framerow14, width=60, height=60)
frame14.grid(row=1, column=1, pady = 10, padx=6)
frame14.config(bg="floral white")
# Frame two
framebg24 = tk.Frame(framerow14, width=63, height=63)
framebg24.grid(row=1, column=2, pady=10, padx=6)
frame24 = tk.Frame(framerow14, width=60, height=60)
frame24.grid(row=1, column=2, pady = 10, padx=6)
frame24.config(bg="floral white")
# # Frame three
framebg34 = tk.Frame(framerow14, width=63, height=63)
framebg34.grid(row=1, column=3, pady=10, padx=6)
frame34 = tk.Frame(framerow14, width=60, height=60)
frame34.grid(row=1, column=3, pady = 10, padx=6)
frame34.config(bg="floral white")
# # Frame four
framebg44 = tk.Frame(framerow14, width=63, height=63)
framebg44.grid(row=1, column=4, pady=10, padx=6)
frame44 = tk.Frame(framerow14, width=60, height=60)
frame44.grid(row=1, column=4, pady = 10, padx=6)
frame44.config(bg="floral white")
# # Frame five
framebg54 = tk.Frame(framerow14, width=63, height=63)
framebg54.grid(row=1, column=5, pady=10, padx=6)
frame54 = tk.Frame(framerow14, width=60, height=60)
frame54.grid(row=1, column=5, pady = 10, padx=6)
frame54.config(bg="floral white")
framerow1s = []
framerow2s = []
framerow3s = []
framerow4s = []
textLost = None
textLost2 = None
frameLost = None
frameWon = None
textWon = None
textWon2 = None
def lost():
global frameLost
global textLost
global textLost2
frameLost = tk.Frame(root, width=500, height=500)
frameLost.grid(row=4, column=1, padx =50)
frameLost.config(bg="floral white")
textLost = tk.Label(frameLost, text="You Lost", font=("Arial", 30, "bold"))
textLost.grid(row=1, column=1)
textLost.config(bg="floral white")
textLost2 = tk.Label(frameLost, text="Press Enter to Restart", font=(FONT_FAMILY, FONT_SIZE))
textLost2.grid(row=2, column=1)
root.bind("<Return>", restart)
root.unbind("<Key>")
def won():
global frameWon
global textWon
global textWon2
frameWon = tk.Frame(root, width=500, height=500)
frameWon.grid(row=4, column=1, padx =50)
frameWon.config(bg="floral white")
textWon = tk.Label(frameWon, text="You Won", font=("Arial", 30, "bold"))
textWon.grid(row=1, column=1)
textWon.config(bg="floral white")
textWon2 = tk.Label(frameWon, text="Press Enter to Restart", font
=(FONT_FAMILY, FONT_SIZE))
textWon2.grid(row=2, column=1)
textWon2.config(bg="floral white")
root.bind("<Return>", restart)
root.unbind("<Key>")
def restart(e):
global row
global col
global frameWon
global textWon
global textWon2
global frameLost
global textLost
global textLost2
global keysin
global framerow1
global framerow12
global framerow13
global framerow14
row = 1
col = 0
if frameWon and textWon and textWon2:
frameWon.destroy()
textWon.destroy()
textWon2.destroy()
if frameLost and textLost and textLost2:
frameLost.destroy()
textLost.destroy()
textLost2.destroy()
keysin = []
for g in framerow1.winfo_children():
if isinstance(g, tk.Label):
g.destroy()
else:
if g.cget("bg") == "floral white":
g.config(width=60, height=60)
else:
g.config(width=63, height=63)
for g in framerow12.winfo_children():
if isinstance(g, tk.Label):
g.destroy()
else:
if g.cget("bg") == "floral white":
g.config(width=60, height=60)
else:
g.config(width=63, height=63)
for g in framerow13.winfo_children():
if isinstance(g, tk.Label):
g.destroy()
else:
if g.cget("bg") == "floral white":
g.config(width=60, height=60)
else:
g.config(width=63, height=63)
for g in framerow14.winfo_children():
if isinstance(g, tk.Label):
g.destroy()
else:
if g.cget("bg") == "floral white":
g.config(width=60, height=60)
else:
g.config(width=63, height=63)
set_word()
root.bind("<Return>", lambda event: new_line())
root.bind("<Key>", keyed)
cool = 0
def new_line():
global row
global cool
global word
global keysin
global framerow1
global framerow12
global framerow1s
global framerow2s
global framerow3s
global framerow4s
global framerow13
global framerow14
frameNow = None
print(row)
if row == 1:
frameNow = framerow1
elif row == 2:
frameNow = framerow12
elif row == 3:
frameNow = framerow13
else:
frameNow = framerow14
if not row == 4:
if keysin == []:
return
row += 1
on_enter(''.join(keysin))
for i in keysin:
if i in guessed_letters:
for h in frameNow.winfo_children():
cool += 1
animate_flip(h)
lb = -1
if isinstance(h, tk.Label):
h.config(width=3, height=2)
animate_flip_frame(h, 'gray16')
if h.cget("text")== str(i.upper()):
for gg in zip(word, ''.join(keysin)):
if gg[0] == gg[1]:
print(''.join(keysin), word)
animate_flip_frame(h, 'dark green')
elif gg[0] in gg[1]:
animate_flip_frame(h, 'DarkOrange1')
else:
animate_flip_frame(h, 'gray16')
elif row == 4:
if not ''.join(keysin) == word:
lost()
else:
won()
keysin = []
def animate_flip_frame(frame,is_gray, i=0):
if i<3:
frame.config(height=3-i)
root.after(100, lambda: animate_flip_frame(frame, is_gray,i+1))
elif i>3:
frame.config(fg='white')
frame.config(bg=is_gray)
root.after(100, lambda: animate_flip_frame(frame, is_gray,i+1))
elif i<6:
frame.config(fg='white')
frame.config(bg=is_gray)
def animate_flip(frame, i=0):
if i<3:
frame.config(height=3-i)
root.after(300, lambda: animate_flip(frame,i+1))
elif i>3:
frame.config(fg='white')
frame.config(bg=is_gray)
root.after(300, lambda: animate_flip_frame(frame, is_gray,i+1))
elif i<6:
frame.config(height=2)
def animate_frame(frame, col, i=0):
frame.configure(bg='floral white')
if i < 5:
frame.configure(font=(FONT_FAMILY, FONT_SIZE+i))
root.after(30, animate_frame, frame, col, i+1)
else:
frame.configure(font=(FONT_FAMILY, FONT_SIZE))
frame.configure(bg="floral white")
frame.grid(row=1, column=col, pady=10, padx=6)
def add_key(key):
col = 0
cul = 0
global framerow1
global framerow12
global framerow13
global framerow14
global frame1
global frame2
global frame3
global frame4
global frame5
global frame12
global frame13
global frame14
global frame22
global frame23
global frame24
global frame32
global frame33
global frame34
global frame42
global frame43
global frame44
global frame52
global frame53
global frame54
global keysin
global frames
global row
global keys_guessed
if row == 1:
if not key == '\x08':
if key.isalpha():
if 'x' in key and not key == 'x':
return
col = 0
cus = 0
frame = False
if key in keysin and key == keysin[-1] and not len(keysin) == 6:
col = 0
for gh in keysin:
col += 1
if key == gh and keysin.index(gh) == len(keysin)-1:
break
lbl2 = tk.Label(framerow1, text=(str(key)).upper(), font=(FONT_FAMILY, FONT_SIZE+5))
lbl2.grid(row=1, column=col, pady=5, padx=3)
animate_frame(lbl2, col)
else:
labls = []
for i in framerow1.winfo_children():
if isinstance(i,tk.Label):
labls.append(i)
if len(labls) > 0:
labls[-1].destroy()
elif row == 2:
if not key == '\x08':
if key.isalpha():
if 'x' in key and not key == 'x':
return
col = 0
cus = 0
frame = False
print(len(keysin))
if key in keysin and key == keysin[-1] and not len(keysin) == 6:
col = 0
for gh in keysin:
col += 1
if key == gh and keysin.index(gh) == len(keysin)-1:
break
print(col)
lbl2 = tk.Label(framerow12, text=(str(key)).upper(), font=(FONT_FAMILY, FONT_SIZE))
lbl2.grid(row=1, column=col, pady=10, padx=6)
animate_frame(lbl2, col)
print(key)
else:
print(key)
labls = []
for i in framerow12.winfo_children():
if isinstance(i,tk.Label):
labls.append(i)
if len(labls) > 0:
labls[-1].destroy()
elif row ==3:
if not key == '\x08':
print(key)
if key.isalpha():
if 'x' in key and not key == 'x':
return
col = 0
cus = 0
frame = False
print(len(keysin))
if key in keysin and key == keysin[-1] and not len(keysin) == 6:
col = 0
for gh in keysin:
col += 1
if key == gh and keysin.index(gh) == len(keysin)-1:
break
print(col)
lbl2 = tk.Label(framerow13, text=(str(key)).upper(), font=(FONT_FAMILY, FONT_SIZE))
lbl2.grid(row=1, column=col, pady=10, padx=6)
animate_frame(lbl2, col)
print(key)
else:
print(key)
labls = []
for i in framerow13.winfo_children():
if isinstance(i,tk.Label):
labls.append(i)
if len(labls) > 0:
labls[-1].destroy()
elif row == 4:
if not key == '\x08':
print(key)
if key.isalpha():
if 'x' in key and not key == 'x':
return
col = 0
cus = 0
frame = False
print(len(keysin))
if key in keysin and key == keysin[-1] and not len(keysin) == 6:
col = 0
for gh in keysin:
col += 1
if key == gh and keysin.index(gh) == len(keysin)-1:
break
print(col)
lbl2 = tk.Label(framerow14, text=(str(key)).upper(), font=(FONT_FAMILY, FONT_SIZE))
lbl2.grid(row=1, column=col, pady=10, padx=6)
animate_frame(lbl2, col)
print(key)
else:
print(key)
labls = []
for i in framerow14.winfo_children():
if isinstance(i,tk.Label):
labls.append(i)
if len(labls) > 0:
labls[-1].destroy()
# Guess textbox
guessed_letters = []
guessed_words = []
current_guess = 10
is_correct = False
root.bind("<Return>", lambda event: new_line())
root.bind("<Key>", keyed)
root.mainloop()
Also, it would be appreciated if someone could tell me how to make the flip animations more like wordle. Thanks!
I tried the zipping function, and indexing it in both the word and the keys entered