1
\$\begingroup\$

I created a Python script that solves Wordle (more specifically this version: https://mywordle.org), it uses a wordlist of all possible answers, it is working perfectly and it rarely loses, you can see it in action here (Google Drive).

You will need this file, I obtained it by editing this file: https://mywordle.org/f5.txt?v=0.2.0.

The Script:

import random
import re
import time
from copy import deepcopy
from pathlib import Path
from selenium import webdriver
from selenium.webdriver import FirefoxProfile
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.firefox.options import Options
from string import ascii_lowercase

options = Options()
options.add_argument("--log-level=3")
options.add_argument("--mute-audio")
options.add_argument("--no-sandbox")
options.add_argument("--disable-dev-shm-usage")
capabibilties = DesiredCapabilities().FIREFOX
capabibilties['pageLoadStrategy'] = 'eager'
profile = FirefoxProfile()
profile.set_preference("http.response.timeout", 1)

Firefox = webdriver.Firefox(capabilities=capabibilties, options=options, firefox_profile=profile)
wait = WebDriverWait(Firefox, 3)

grid = "//div/div[contains(@class, 'game-grid')]"
cell = grid + "/div[contains(@class, 'game-item')]"

states = {
    'bg-gray-400': 'absent', 
    'bg-orange-400': 'present',
    'bg-green-500': 'correct'
}

wordlelist = Path('D:/corpus/wordle-5.txt').read_text().splitlines()

class Agent:
    def __init__(self):
        self.pool = deepcopy(wordlelist)
        self.letters = ascii_lowercase
        self.pattern = ''
        self.present = set()
    
    def guess(self):
        return random.choice(self.pool)
    
    def update(self, conditions):
        pool = list()
        self.process(conditions)
        for word in self.pool:
            if re.match(self.pattern, word):
                if not self.present or all(l in word for l in self.present):
                    pool.append(word)
        self.pool = pool
    
    def process(self, conditions):
        for letter, state in conditions:
            if state == 'absent':
                self.letters = self.letters.replace(letter, '')
        
        pattern = []
        self.present.clear()
        for letter, state in conditions:
            if state == 'absent':
                pattern.append('[' + self.letters + ']')
            elif state == 'present':
                pattern.append('[' + self.letters.replace(letter, '') + ']')
                self.present.add(letter)
            elif state == 'correct':
                pattern.append(letter)
        
        self.pattern = '^' + ''.join(pattern) + '$'


def solve():
    agent = Agent()
    correct_status = ['bg-green-500'] * 5
    wait.until(EC.visibility_of_element_located((By.XPATH, grid)))
    for i in range(6):
        guess = agent.guess()
        Firefox.find_element('xpath', '//body').send_keys(guess)
        Firefox.find_element('xpath', '//body').send_keys(Keys.ENTER)
        cells = Firefox.find_elements('xpath', cell)
        time.sleep(2)
        status = [c.find_element('xpath', './div[2]').get_attribute('class').split()[2] for c in cells[i*5:i*5+5]]
        if status == correct_status:
            break
        status = [states[s] for s in status]
        agent.update(list(zip(guess, status)))
    time.sleep(3)
    wait.until(EC.visibility_of_element_located((By.XPATH, '//div[1]/div[1]/button[3]')))
    Firefox.find_element('xpath', '//div[1]/div[1]/button[3]').click()

if __name__ == '__main__':
    Firefox.get('https://mywordle.org')
    time.sleep(3)
    while True:
        solve()

I wrote this script in under 3 hours all by myself, the part of the script that I want to get reviewed is the class Agent. It can work with other front-end as well, I am perfectly capable of writing a full-fledged working GUI Wordle game using PyQt6, but nah I am lazy.

I want to know how I can improve the logic, algorithm, efficiency et cetera of that particular class.

\$\endgroup\$

0

Your Answer

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

Browse other questions tagged or ask your own question.