You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

136 lines
3.7 KiB

#!/usr/bin/env python3
import random
print("Welcome to this debug tool!")
print("Just follow the instructions,")
print("however the input syntax is special.")
print()
print("A letter following by a !:")
print(" this letter doesn't exist at all")
print()
print("A letter following by a ?:")
print(" this letter exits but is misplaced")
print()
print("For example:")
print("li!n?u!s!")
print()
print("Which translates into:")
print(" the first letter is an l")
print(" the word doesn't contain an i")
print(" the letter n is misplaced")
print(" the word doesn't contain an u")
print(" the word doesn't contain an s")
print()
print()
def determine_guess(words: list, tries: int) -> str:
""" Selects one word from the remaining dictionary """
if tries > 0:
return random.choice(words) # good enough
else:
return "intro"
def is_letter(char: str) -> bool:
""" Checks if a character exists within the alphabet """
return char >= "a" and char <= "z"
def get_next_letter(response: str, current_index: int) -> str:
""" Returns the following letter """
next_index = current_index + 1
if next_index >= len(response):
return None
return response[next_index]
def update_hints(hints: dict, response: str) -> dict:
"""
Reads the user supplied response and translates it into logical assumptions
The hints dictionary contains single letters as keys,
where the values are lists of possible locations for this letter.
When the user enters o! we know that 'o' has no valid position within the searched word.
dict['o'] -> []
When a letter is marked as misplaced, this eliminates possible positions.
dict['k'] -> [0, 1, 3, 4]
Lastly, correct letters are greatly reducing the possibilities.
dict['m'] -> [2]
"""
response = response.lower()
position = 0
for i in range(len(response)):
letter = response[i]
if not is_letter(letter):
continue
if not letter in hints:
hints[letter] = [0, 1, 2, 3, 4]
next_letter = get_next_letter(response, i)
if not next_letter or is_letter(next_letter):
hints[letter] = [position]
elif next_letter == "?":
hints[letter] = [l for l in hints[letter] if l != position]
elif next_letter == "!":
hints[letter] = []
else:
print("invalid input syntax")
position += 1
return hints
def narrow_dictionary(words: list, hints: dict) -> list:
""" Apply the hints to narrow down the possibilities """
invalid_words = []
for word in words:
for key in hints:
pos = word.find(key)
# skip optional hints
if pos == -1 and len(hints[key]) == 0:
continue
if not pos in hints[key]:
invalid_words.append(word)
break
return list(filter(lambda w: w not in invalid_words, words))
with open("en.txt", "r") as handle:
words = handle.readlines()
words = list(map(lambda l: l.strip(), words))
hints = {}
tries = 0
while tries < 6:
guess = determine_guess(words, tries)
print(f"{len(words)} words remaining")
print(f"input: {guess}")
response = input("response: ")
print()
hints = update_hints(hints, response)
words = narrow_dictionary(words, hints)
if len(words) == 1:
print(f"It must be {words[0]}")
exit()
if len(words) == 0:
print("There are no words left, please check your input.")
exit()
tries += 1
print("I hope the last try was successful.")
print()