Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 17419

Fixing Logic With Repeated Letters in Wordle

$
0
0

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.


Viewing all articles
Browse latest Browse all 17419

Latest Images

Trending Articles



Latest Images