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 and non_letter in unconsumed_letters and 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): rv, unconsumed_letters = False, '' for non_pos_idx, non_positional_letter in enumerate(non_positional_letters): if non_positional_letter == BLANK: continue unconsumed_letters += word[non_pos_idx] if non_positional_letter not in word: rv = True elif word[non_pos_idx] == non_positional_letter: rv = True return rv, 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 = remove_non_positional_letters(word, non_positional_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('', ['----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('nu', ['-o-ns'], ['-----'], dictionary=['towns'])] == ['towns'] # nouns 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()