Written by
Xiaofeng
on
on
A Homemade Wordle
I’ve been hooked to Wordle recently - hats off to the website owner, one Josh Wardle (also congrats to him cuz I think NYT bought the site for allegedly low seven figures. :D). Since I’ve spent much time on cracking its daily challenges, I figured why not write one myself!
As for my little knock-off program, the rules are very simple and are consistent with the official Wordle. For each guess, you get hints on:
- right character in the right place
- right character but wrong place
- no such character
That’s it. And you only have a maximum of 6 attempts too.
Since UI isn’t really my forte, I sorta skipped skimmed on that. Here’s a sample output of my little program from command line:
Welcome to Xiaofeng's own version of command line Wordle. You have a maximum of 6 attempts. Good luck!
Enter your 5-letter guess of word: sunday
Please input a 5-letter word
Enter your 5-letter guess of word: solid
Results:
uppercase = right character in the right place;
lowercase = right character but wrong place;
hyphen = no such character
attempt 1: solid --> - o L - -
Enter your 5-letter guess of word: bully
Results:
uppercase = right character in the right place;
lowercase = right character but wrong place;
hyphen = no such character
attempt 1: solid --> - o L - -
attempt 2: bully --> - - L L -
Enter your 5-letter guess of word: jello
Results:
uppercase = right character in the right place;
lowercase = right character but wrong place;
hyphen = no such character
attempt 1: solid --> - o L - -
attempt 2: bully --> - - L L -
attempt 3: jello --> - E L L O
Enter your 5-letter guess of word: hello
Congrats, you have cracked this!
And the code in Python:
#!/usr/bin/env python3
from collections import Counter, OrderedDict
from enum import Enum
from random import choice
from sys import exit
class Result(Enum):
MATCHED = 10
MISPLACED = 20
NONE = 30
class Wordle:
# All in lowercase. should really hide this and/or get a much bigger dictionary
corpus = [
'hello',
'those',
'skill',
'shard',
'elder',
'pleat',
'tesla'
]
def __init__(self, try_limit):
self.try_limit = try_limit
self.tries = 0
self.secret_word = choice(self.corpus)
self.snaps = []
def check(self, word):
assert len(word) == len(self.secret_word)
if self.tries >= self.try_limit:
exit("Sorry, you have run out number of attempts. The answer is {self.secret_word}. Better luck on the next Wordle!")
self.tries += 1
word = word.lower()
if word == self.secret_word:
exit('Congrats, you have cracked this!')
# Technically we can use list instead, since the key is just the index. But I just love OrderedDict too much
res = OrderedDict()
expected = Counter(self.secret_word)
for i in range(len(word)):
if word[i] == self.secret_word[i]:
res[i] = Result.MATCHED
expected[word[i]] -= 1
continue
if expected[word[i]] > 0:
res[i] = Result.MISPLACED
expected[word[i]] -= 1
else:
res[i] = Result.NONE
self.snaps.append((word,res))
self.print_snaps_()
def print_snaps_(self):
print('Results:\nuppercase = right character in the right place; \nlowercase = right character but wrong place; \nhyphen = no such character')
for i, snap in enumerate(self.snaps):
print(f'attempt {i+1}:', end=' ')
self.print_snap_(snap)
print()
def print_snap_(self, snap):
"""
:type snap: (str, OrderedDict)
"""
word, res = snap
print(word, ' --> ', end='')
for k, v in res.items():
if v == Result.MATCHED:
print(word[k].upper(), end=' ')
if v == Result.MISPLACED:
print(word[k], end=' ')
if v == Result.NONE:
print('-', end=' ')
print()
if __name__ == '__main__':
MAX_GUESS = 6
wordle = Wordle(MAX_GUESS)
print(f"Welcome to Xiaofeng's own version of command line Wordle. You have a maximum of {MAX_GUESS} attempts. Good luck!")
while True:
try:
guess = input("Enter your 5-letter guess of word: ")
if len(guess) != 5:
print("Please input a 5-letter word")
continue
wordle.check(guess)
except Exception as e:
print(e)
A couple things to improve:
- The corpus is definitely too small and shouldn’t be in plaintext for sure. Maybe hook up to some API (such as a word list from Stanford) and encrypt it. I suppose dumping the list to file would work too.
- The input guesses should be valid words but right now 5-letter gibberish would pass too. Need to validate input.
- A bit more thinking needed for edge cases on repeated characters.
Otherwise, this two-hour side hustle was a bit fun!