From 191c746957036ab96930d020995aa8149e09f7f2 Mon Sep 17 00:00:00 2001 From: rafael <30427560+rafrafavi@users.noreply.github.com> Date: Thu, 28 Mar 2024 12:25:28 +0800 Subject: [PATCH] Fixes #1 by temporarily removing repeat char preference alogrithm --- caddy.py | 71 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/caddy.py b/caddy.py index 2f0ea16..084f27d 100644 --- a/caddy.py +++ b/caddy.py @@ -3,19 +3,23 @@ import re import pathlib -WORDS_FILE = 'target_words.txt' -no_repeat_chars_regex = r'^(?:([a-z])(?!.*\1))*$' # Ensure unique characters in suggestions -OPENER = 'crane' -INTRO = 'Welcome to Wordle Caddy: a Wordle word filterer.\nType help for a list of commands.' +WORDS_FILE = "target_words.txt" +no_repeat_chars_regex = ( + r"^(?:([a-z])(?!.*\1))*$" # Ensure unique characters in suggestions +) +OPENER = "crane" +INTRO = "Welcome to Wordle Caddy: a Wordle word filterer.\nType help for a list of commands." class WordleCaddy(cmd.Cmd): def __init__(self): super().__init__() - self.words = (pathlib.Path(__file__).parent / WORDS_FILE).read_text().splitlines() + self.words = ( + (pathlib.Path(__file__).parent / WORDS_FILE).read_text().splitlines() + ) self.last_search = self.words self.intro = INTRO - self.prompt = '(wordle ) ' + self.prompt = "(wordle ) " self.not_contains = set() self.contains = set() self.matches = set() @@ -24,7 +28,7 @@ def __init__(self): def do_ipick(self, arg): """Intelligently picks a word based on textual representation of clues.""" try: - guess, score = re.split(r'\s|:', arg) + guess, score = re.split(r"\s|:", arg) except ValueError: score = arg guess = self.recommended @@ -34,18 +38,18 @@ def do_ipick(self, arg): return not_in_word = [] - exact_positions = ['.'] * len(guess) + exact_positions = ["."] * len(guess) in_word = [] - not_in_positions = ['.'] * len(guess) + not_in_positions = ["."] * len(guess) for i, (g, s) in enumerate(zip(guess, score)): - if s in '-_.g': + if s in "-_.g": not_in_word.append(g) - elif s in 'o?y': + elif s in "o?y": in_word.append(g) not_in_positions[i] = g self.contains.add(g) - elif s in 'x+g': + elif s in "x+g": exact_positions[i] = g self.matches.add(g) @@ -53,13 +57,17 @@ def do_ipick(self, arg): def process_filters(self, not_in_word, exact_positions, not_in_positions, in_word): """Applies filters based on the clues provided.""" - if not_in_word_filtered := [char for char in not_in_word if char not in self.contains.union(self.matches)]: - self.do_not(''.join(not_in_word_filtered)) - self.do_sub(''.join(exact_positions)) - self.do_sub(''.join([f'[^{c}]' if c != '.' else '.' for c in not_in_positions])) + if not_in_word_filtered := [ + char + for char in not_in_word + if char not in self.contains.union(self.matches) + ]: + self.do_not("".join(not_in_word_filtered)) + self.do_sub("".join(exact_positions)) + self.do_sub("".join([f"[^{c}]" if c != "." else "." for c in not_in_positions])) if in_word: - self.do_contains(''.join(in_word)) - self.do_suggest('') + self.do_contains("".join(in_word)) + self.do_suggest("") def do_find(self, arg, sub_search=False, show=True): """Finds arg in the word list using regex syntax.""" @@ -79,7 +87,7 @@ def do_contains(self, arg): self.contains = set() return self.contains.update(arg) - query = ''.join(f'(?=.*{c})' for c in self.contains) + query = "".join(f"(?=.*{c})" for c in self.contains) self.do_sub(query) def do_suggest(self, arg, auto_suggest=True): @@ -93,8 +101,25 @@ def display_suggestions(self, auto_suggest): """Displays word suggestions.""" suggestion = self.recommended if auto_suggest else None if auto_suggest: - self.do_find(no_repeat_chars_regex, True, False) - suggestion = random.choice(self.last_search) if self.last_search else self.recommended + # TODO: Implement unbuggy prefernce for unique characters + # (This is buggy because it doesn't account for the current search results) + # self.do_find(no_repeat_chars_regex, True, False) + # if self.last_search and 10 < (choices := len(self.last_search)) < 100: + # # suggestion = random.choice( + # # [word for word in self.last_search if set(word) == 5] + # # ) + # suggestion = ( + # random.choice(self.last_search) + # if self.last_search + # else self.recommended + # ) + # else: + suggestion = ( + random.choice(self.last_search) + if self.last_search + else self.recommended + ) + if suggestion and self.recommended != suggestion: self.recommended = suggestion print("Suggested:", suggestion) @@ -107,7 +132,7 @@ def do_not(self, arg): self.not_contains = set() return self.not_contains.update(arg) - self.do_sub(r'[^' + ''.join(self.not_contains) + ']{5}') + self.do_sub(r"[^" + "".join(self.not_contains) + "]{5}") def do_reset(self, arg): """Resets the search to the full word list.""" @@ -129,5 +154,5 @@ def main(): w.cmdloop() -if __name__ == '__main__': +if __name__ == "__main__": main()