Created
March 12, 2024 21:48
-
-
Save TheRealRyGuy/95e491b3c4c0a05baf6df6c7f8e5da57 to your computer and use it in GitHub Desktop.
Wordle Solving Algorithm taking in any wordlist! Just run python3 main.py wordlistfile.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rich import print | |
import sys | |
#TODO: Remove / reformat debug statements, allowing the class to be useable in any way | |
class WordleBot: | |
def __init__(self, wordlist): | |
self.listfile = wordlist | |
self.words = set() | |
self.badletters = set() | |
self.known = dict() | |
self.knownletters = set() | |
self.badpositions = dict() | |
def preload(self): | |
with open(self.listfile) as file: | |
self.words = list(map(lambda x: x.strip(), file.readlines())) | |
print(f"Found {len(self.words)} words!") | |
removed = 0 | |
for word in self.words: | |
if(len(word)) != 5: | |
self.words.remove(word) | |
removed += 1 | |
print(f"Removed {removed} non 5-letter words") | |
def getCommonLetters(self) -> dict: | |
letters = dict() | |
for word in self.words: | |
for letter in word: | |
if letter not in letters: | |
letters[letter] = 1 | |
else: | |
letters[letter] = letters[letter] + 1 | |
return letters | |
def getWord(self): | |
keys = dict(sorted(self.getCommonLetters().items(), key=lambda item: item[1], reverse=True)[0:10]) | |
size = 5 | |
letters = {k: keys[k] for k in list(keys.keys())[:size]} | |
newWords = [w for w in self.words if all(c in list(letters.keys()) for c in [*w])] | |
print(f"Found {len(newWords)} words for 5 letters") | |
oldsize = len(newWords) | |
if len(newWords) < 2: | |
size += 1 | |
while True: | |
letters = {k: keys[k] for k in list(keys.keys())[:size]} | |
newWords = [w for w in self.words if all(c in list(keys.keys()) for c in [*w])] | |
print(f"Found {len(newWords)} words for {size} letters") | |
if len(newWords) >= 2 or oldsize == len(newWords): | |
if len(newWords) > 20: | |
newWords = [w for w in newWords if all(w.count(c) == 1 for c in w)] | |
return newWords | |
else: | |
size += 1 | |
return newWords | |
def getFirstWord(self): | |
keys = dict(sorted(self.getCommonLetters().items(), key=lambda item: item[1], reverse=True)[0:5]) | |
word = [w for w in self.words if all(c in w for c in list(keys.keys()))] | |
print(f"Found {len(word)} words with all of the most common 5 letters") | |
return word | |
def guess(self, word, res): | |
for index, letter in enumerate(res): | |
if(letter == "G"): | |
if index in self.known.keys() and self.known[index] != word[index]: | |
print("You already have a", self.known[index], "in position", index) | |
continue | |
self.known[index] = word[index] | |
elif letter == "O": | |
self.knownletters.add(word[index]) | |
if index in self.badpositions.keys(): | |
self.badpositions[index].append(word[index]) | |
else: | |
self.badpositions[index] = list(word[index]) | |
else: | |
self.badletters.add(word[index]) | |
def updateWords(self): | |
removed=0 | |
print("Currently known letters in the word:", self.knownletters) | |
print("Currently known letters in the correct positions:", self.known.items()) | |
print("Currently known letters not in the word:", self.badletters) | |
for c in self.badletters: | |
if c in self.knownletters: continue | |
if c in self.known.values(): continue | |
if c in [j for i in self.badpositions.values() for j in i]: continue | |
for word in self.words[:]: | |
#print(f"Checking {c} with {word} = {c in word}") | |
if c in word: | |
self.words.remove(word) | |
removed += 1 | |
continue | |
for position, letter in self.known.items(): | |
for word in self.words[:]: | |
if word[position] != letter: | |
self.words.remove(word) | |
removed += 1 | |
continue | |
for position, letters in self.badpositions.items(): | |
for word in self.words[:]: | |
if word[position] in letters: | |
self.words.remove(word) | |
removed += 1 | |
continue | |
if len(self.knownletters) != 0: | |
for word in self.words[:]: | |
if not all(c in word for c in self.knownletters): | |
self.words.remove(word) | |
print(f"Eliminated {removed} words, Parsed down to {len(self.words)} words!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
from rich import print | |
from bot import WordleBot | |
def main(): | |
turn = 1 | |
path = sys.argv[1] | |
if(not path.strip()): | |
print("No wordlist file given! Ignoring") | |
sys.exit(1) | |
bot = WordleBot(path) | |
bot.preload() | |
firstWord = bot.getWord() | |
print("Guess any one of these first words!", firstWord) | |
while True: | |
print("Now write the word that you guessed!") | |
word = input() | |
print("Input your result below! If the letter was [green1]green[/green1], write G! If it was [bright_yellow]yellow[/bright_yellow], right O! If it just didn't work, write P!") | |
res = input() | |
if(res[0:5] == "GGGGG"): | |
print("Congratulations, you won! Goodbye") | |
sys.exit(0) | |
bot.guess(word.lower(), res.upper()) | |
turn += 1 | |
if turn == 7: | |
print("No more turns! Goodbye!") | |
sys.exit(0) | |
bot.updateWords() | |
if turn == 2: | |
print("Choosing another elimination word to remove more letters") | |
newWords = bot.getWord() | |
else: | |
newWords = bot.getWord() | |
print("Narrowed down your words to these:", newWords) | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment