184 lines
7.1 KiB
Python
184 lines
7.1 KiB
Python
import random
|
|
|
|
from lib import cat_words, INSTRUCTIONS, BLANK, ROUNDS, DEBUG, DICTIONARY
|
|
|
|
|
|
def remove_non_letters(word, non_letters, unconsumed_letters, non_pos_unconsumed_letters):
|
|
for non_letter in non_letters:
|
|
if non_letter in word:
|
|
if non_letter in unconsumed_letters or non_letter in non_pos_unconsumed_letters:
|
|
return True
|
|
return False
|
|
|
|
|
|
def remove_positional_letters(word, positional_letters):
|
|
rv, unconsumed_letters = False, ''
|
|
for pos_idx, positional_letter in enumerate(positional_letters):
|
|
if positional_letter == BLANK:
|
|
unconsumed_letters += word[pos_idx]
|
|
continue
|
|
if positional_letter not in word:
|
|
rv = True
|
|
elif word[pos_idx] != positional_letter:
|
|
rv = True
|
|
return rv, unconsumed_letters
|
|
|
|
|
|
def remove_non_positional_letters(word, non_positional_letters, unconsumed_letters):
|
|
rv, non_pos_unconsumed_letters = False, ''
|
|
for non_pos_idx, non_positional_letter in enumerate(non_positional_letters):
|
|
if non_positional_letter == BLANK:
|
|
continue
|
|
non_pos_unconsumed_letters += word[non_pos_idx]
|
|
if non_positional_letter in unconsumed_letters:
|
|
unconsumed_letters = unconsumed_letters.replace(non_positional_letter, '', 1)
|
|
if non_positional_letter not in word:
|
|
rv = True
|
|
elif word[non_pos_idx] == non_positional_letter:
|
|
rv = True
|
|
return rv, non_pos_unconsumed_letters, unconsumed_letters
|
|
|
|
|
|
def round_words(non_letters, all_positional_letters, all_non_positional_letters, dictionary=DICTIONARY):
|
|
for word in cat_words(dictionary):
|
|
skip = False
|
|
# Find positional letters, e.g. a----
|
|
for positional_letters in all_positional_letters:
|
|
skip, unconsumed_letters = remove_positional_letters(word, positional_letters)
|
|
if skip:
|
|
break
|
|
if skip:
|
|
continue
|
|
# Find non-positional letters, e.g. h-s--
|
|
for non_positional_letters in all_non_positional_letters:
|
|
skip, non_pos_unconsumed_letters, unconsumed_letters = remove_non_positional_letters(
|
|
word, non_positional_letters, unconsumed_letters)
|
|
if skip:
|
|
break
|
|
if skip:
|
|
continue
|
|
skip = remove_non_letters(word, non_letters, unconsumed_letters, non_pos_unconsumed_letters)
|
|
if skip:
|
|
continue
|
|
if not skip:
|
|
yield word
|
|
|
|
|
|
def first_round_words():
|
|
for word in cat_words():
|
|
word_break = [letter for letter in word]
|
|
skip = False
|
|
for letter in word_break:
|
|
if word_break.count(letter) > 1:
|
|
skip = True
|
|
break
|
|
if skip:
|
|
continue
|
|
yield word
|
|
|
|
|
|
def resolve_positions(letters):
|
|
positional_letters, non_positional_letters, is_good = '', '', True
|
|
for letter in letters:
|
|
if letter == BLANK:
|
|
positional_letters += BLANK
|
|
non_positional_letters += BLANK
|
|
elif letter.isupper():
|
|
positional_letters += letter.lower()
|
|
non_positional_letters += BLANK
|
|
elif letter.islower():
|
|
positional_letters += BLANK
|
|
non_positional_letters += letter
|
|
else:
|
|
print("ERROR: {}".format(INSTRUCTIONS))
|
|
is_good = False
|
|
return positional_letters, non_positional_letters, is_good
|
|
|
|
|
|
def main_loop():
|
|
all_non_letters = ''
|
|
all_positional_letters = []
|
|
all_non_positional_letters = []
|
|
print(INSTRUCTIONS)
|
|
for round_number in range(ROUNDS):
|
|
if round_number == 0:
|
|
this_round_words = [w for w in first_round_words()]
|
|
else:
|
|
this_round_words = [w for w in
|
|
round_words(all_non_letters, all_positional_letters, all_non_positional_letters)]
|
|
if DEBUG:
|
|
for word in this_round_words:
|
|
print(word)
|
|
print("This round words: {}".format(len(this_round_words)))
|
|
print("=" * 10)
|
|
if len(this_round_words) == 0:
|
|
print("ERROR: No known words left.")
|
|
break
|
|
if DEBUG:
|
|
print("ALL Non-letters: {}".format(','.join(all_non_letters)))
|
|
print("ALL Positional letters: {}".format(','.join(all_positional_letters)))
|
|
print("ALL Non-Positional letters: {}".format(','.join(all_non_positional_letters)))
|
|
print("Random word: {}".format(random.choice(this_round_words)))
|
|
if len(this_round_words) == 1:
|
|
print("That's all I got.")
|
|
break
|
|
print("=" * 10)
|
|
print("ROUND {}".format(round_number + 1))
|
|
print("-" * 10)
|
|
while True:
|
|
non_letters = input("Non letters: ")
|
|
if not all([x.islower() for x in non_letters]):
|
|
print("ERROR: {}".format(INSTRUCTIONS))
|
|
continue
|
|
break
|
|
all_non_letters += non_letters
|
|
while True:
|
|
letters = input("Letters: ")
|
|
if len(letters) != 5:
|
|
print("ERROR: {}".format(INSTRUCTIONS))
|
|
continue
|
|
positional_letters, non_positional_letters, is_good = resolve_positions(letters)
|
|
if is_good:
|
|
all_positional_letters.append(positional_letters)
|
|
all_non_positional_letters.append(non_positional_letters)
|
|
break
|
|
if all([letter.isupper() for letter in letters]):
|
|
print("WIN")
|
|
break
|
|
else:
|
|
print("Sorry. Remaining words: {}".format(len(this_round_words)))
|
|
for word in this_round_words:
|
|
print(word)
|
|
|
|
|
|
def find_word(search):
|
|
for i, word in enumerate(cat_words()):
|
|
if word == search:
|
|
print(i)
|
|
|
|
|
|
def do_test():
|
|
assert [w for w in round_words('', ['towns'], ['-----'], dictionary=['towns'])] == ['towns']
|
|
assert [w for w in round_words('', ['-----'], ['stown'], dictionary=['towns'])] == ['towns']
|
|
assert [w for w in round_words('', ['----y'], ['-----'], dictionary=['slily'])] == ['slily']
|
|
assert [w for w in round_words('', ['-----'], ['yy---'], dictionary=['slyly'])] == ['slyly']
|
|
assert [w for w in round_words('', ['----y'], ['y----'], dictionary=['slyly'])] == ['slyly']
|
|
assert [w for w in round_words('', ['---yy'], ['y----'], dictionary=['slyyy'])] == ['slyyy']
|
|
assert [w for w in round_words('', ['---yy'], ['-----'], dictionary=['slyyy'])] == ['slyyy']
|
|
assert [w for w in round_words('', ['-y---'], ['--y--'], dictionary=['sysys'])] == ['sysys']
|
|
assert [w for w in round_words('', ['--b-y'], ['ab---'], dictionary=['cabby'])] == ['cabby']
|
|
assert [w for w in round_words('', ['--b-y'], ['-a-b-'], dictionary=['abbey'])] == ['abbey']
|
|
assert [w for w in round_words('nu', ['-o-ns'], ['-----'], dictionary=['towns'])] == ['towns'] # nouns
|
|
assert [w for w in round_words('r', ['p-int'], ['-----'], dictionary=['print', 'point'])] == ['point']
|
|
assert [w for w in round_words('fos', ['-l---'], ['---s-'], dictionary=['slung'])] == ['slung'] # typed basil floss
|
|
|
|
|
|
def main():
|
|
do_test()
|
|
main_loop()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
# find_word('towns')
|
|
main()
|