I'm not really sure what to make the name of this so I'll explain it a lot better here. I am trying to recreate the game Wordle, and I'll assume you know how the game is played. When you guess a word, if your guess has repeat letters (say you guess sheet) and the word does not have a repeat of that letter (say the word is stale), then only the first letter will show up as yellow, and the second one will show up as grey. However, if you guessed eerie instead, the last e would show up green, and the other two would show up grey. If you guess a word that has 2 of the same letter, and the final word has two of that letter, both show up green or yellow. Basically, if you guess a repeat letter, and there is more of them in your guess than in the answer, it first checks for green letters, then if there are no green then the first one will be yellow. I hope that made some sense, feel free to test it out yourself if you would like. I have the code working fine, but there is one case where it does not work. Let's say the answer is pinch, and I guess crack. The second c in crack would be green, which means that the first c should be grey. However, the first c shows up as yellow because the code has not yet realized that there is a green c later. Essentially, I need a way to either compare the two strings (the guess and the answer) all at once and then decide which ones are green and yellow, or I need some way of correcting it. Here is what I have so far:
if guess_repeat: if not answer_repeat: if character == answer[letter]: rect = pygame.draw.rect(screen, (1, 154, 1), (color_x, color_y, 65, 90)) elif character in answer and character != answer[letter]: if guess_info[character] == 1: rect = pygame.draw.rect(screen, (255, 196, 37), (color_x, color_y, 65, 90)) else: for k in range(5): if guesses[i][k] == character and filled == 0: rect = pygame.draw.rect(screen, (255, 196, 37), (color_x, color_y, 65, 90)) filled = 1 break
I am using the pygame module, but it's not really important for this. What the code is doing is in the first if statement, it is checking whether or not the user guess has repeated letters. If it does, it then checks if the answer has repeated letters, as there are two different cases for whether the answer also has repeat letters. Then it is looping through all the characters (thats the character
local variable in line 3) in the user guess and seeing if it is the same as the corresponding letter in the answer. It checks whether the first letter in the guess is the same as the first letter in the answer, the second letter, and so on. This is how I determine whether there should be a green there. If so I draw a rectangle that fills the square green. Then if the character is in the answer, but not in the right spot (line 5) then I know it's yellow. Line 6 is referencing guess_info
. This is a dictionary that contains how many times each letter appears in the guess. For example with the word sheet it would look like this {'s': 1, 'h': 1, 'e': 2, 't': 1}
. This is just to see if a letter is repeated. If it's not (aka guess_info[character] == 1
) then it just fills the square in yellow. However, if it is repeated then it needs to see when the first instance of the letter is, and make that yellow. That's what lines 9-13 are doing. filled
is a just a variable to make sure that only the first letter gets filled, and not all of them. guesses
is a list containing all of the users guesses (shocking I know) and I'm just looping through all of the guesses. I will attach the code for the entire game at the end here, but it's probably really hard to read, and not really important for the problem.
import pygameimport randompygame.init()screen = pygame.display.set_mode((1920, 1080))color = '#333333'screen.fill(color)user_text = ''font = pygame.font.Font(None, 110)clock = pygame.time.Clock()background = pygame.image.load('wordle.png')screen.blit(background, (0, 0))pygame.display.flip()word = 0guesses = ['', '', '', '', '', '']win_state = Falsewhile True: guess_repeat = False answer_repeat = False guess_info = {} answer_info = {} filled = 0 with open('possible_answers') as possible_answers: content = possible_answers.readlines() randint = random.randint(0, 2309) answer = content[randint] parts = answer.split('\n') answer = parts[0] individual = [*answer] if len(individual) == len(list(set(individual))): answer_repeat = False else: answer_repeat = True for character in answer: answer_info[character] = answer_info.get(character, 0) + 1 print(answer) while not win_state: letter = 0 for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_BACKSPACE: user_text = user_text[:-1] elif event.key == pygame.K_RETURN: with open('possible_guesses') as possible_guesses: if user_text.lower() in possible_guesses.read() and len(user_text) == 5: guesses[word] = user_text for character in user_text: x = 778 + letter * 70 y = 225 + word * 95 if character in answer: rect = pygame.draw.rect(screen, (255, 196, 37), (x, y, 65, 90)) for i in range(5): if user_text[i] == answer[i]: rect = pygame.draw.rect(screen, (1, 154, 1), (x, y, 65, 90)) letter += 1 word += 1 user_text = '' elif len(user_text) < 5: user_text += event.unicode screen.blit(background, (0, 0)) for character in user_text: x = 809 + letter * 70 y = 270 + word * 95 color_x = x - 31 color_y = y - 45 text_surface = font.render(character.lower(), True, (255, 255, 255)) size = font.size(character) screen.blit(text_surface, ((x - size[0] / 2), (y - size[1] / 2))) letter += 1 for i in range(6): letter = 0 guess_info = {} characters = [*guesses[i]] filled = 0 if len(characters) == len(list(set(characters))): guess_repeat = False else: guess_repeat = True for character in characters: guess_info[character] = guess_info.get(character, 0) + 1 for character in guesses[i]: x = 809 + letter * 70 y = 270 + i * 95 color_x = x - 31 color_y = y - 45 if not guess_repeat: if character == answer[letter]: rect = pygame.draw.rect(screen, (1, 154, 1), (color_x, color_y, 65, 90)) if character in answer and character != answer[letter]: rect = pygame.draw.rect(screen, (255, 196, 37), (color_x, color_y, 65, 90)) if guess_repeat: if not answer_repeat: if character == answer[letter]: rect = pygame.draw.rect(screen, (1, 154, 1), (color_x, color_y, 65, 90)) elif character in answer and character != answer[letter]: if guess_info[character] == 1: rect = pygame.draw.rect(screen, (255, 196, 37), (color_x, color_y, 65, 90)) else: for k in range(5): if guesses[i][k] == character and filled == 0: rect = pygame.draw.rect(screen, (255, 196, 37), (color_x, color_y, 65, 90)) filled = 1 break text_surface = font.render(character.lower(), True, (255, 255, 255)) size = font.size(character) screen.blit(text_surface, ((x - size[0] / 2), (y - size[1] / 2))) letter += 1 if guesses[5] != '' and guesses[5] != answer: text = 'L + Bozo' text_surface = font.render(text, True, (150, 0, 0)) screen.blit(text_surface, (790, 850)) reset = pygame.image.load('reset.png') screen.blit(reset, (805, 925)) win_state = True for guess in guesses: if guess == answer: text = 'You Win!' text_surface = font.render(text, True, (255, 255, 255)) screen.blit(text_surface, (790, 850)) win_state = True pygame.display.flip() clock.tick(60) while win_state: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() if event.type == pygame.MOUSEBUTTONDOWN: x, y = pygame.mouse.get_pos() if 805 < x < 1061 and 925 < y < 1053: screen.fill('BLACK') screen.blit(background, (0, 0)) win_state = False word = 0 guesses = ['', '', '', '', '', ''] if event.type == pygame.KEYDOWN: if event.key == pygame.K_r: screen.fill('BLACK') screen.blit(background, (0, 0)) win_state = False word = 0 guesses = ['', '', '', '', '', '']
It's worth noting that it's not finished, and so there is not a case for when there are repeated letters in the guess and the answer. The code snippet above is from lines 97-109. One of my ideas is to remove all the different cases, and just compare it every time for every letter no matter repeating, and then do all of the drawing in the end, but that seems like it would be a large waste of computing time. Thanks in advance, and hopefully this question wasn't terrible.