Last active
December 13, 2021 00:45
-
-
Save KTibow/7049169bbf3ed45c51fc18e4d61e75c3 to your computer and use it in GitHub Desktop.
Simple hangman game guesser written in Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Simple hangman guesser by @KTibow | |
# Get the possible words from the file | |
import string | |
all_words = open("words_alpha.txt").read().splitlines() | |
# Get how long the word is | |
word_length = int(input("How long is the word? ")) | |
word_letters = [[] for i in range(word_length)] | |
possible_words = [] | |
def find_representation(not_valid): | |
if len(not_valid) == 25: | |
right_letter = list(string.ascii_lowercase) | |
[right_letter.remove(i) for i in not_valid] | |
return right_letter[0] | |
else: | |
return "_" | |
while True: | |
letter_probabilities = {} | |
possible_words = [] | |
for word in all_words: | |
# Check if the word is the right length | |
if len(word) != word_length: | |
continue | |
# Check if the word has the right letters | |
word_is_valid = True | |
for i, not_options in enumerate(word_letters): | |
if word[i] in not_options: | |
word_is_valid = False | |
break | |
if not word_is_valid: | |
continue | |
# Add the word to the list of possible words | |
possible_words.append(word) | |
# If the word is valid, add it to the letter_probabilities | |
for i in range(word_length): | |
if len(word_letters[i]) < 25: | |
if word[i] in letter_probabilities: | |
letter_probabilities[word[i]] += 1 | |
else: | |
letter_probabilities[word[i]] = 1 | |
# Find the most likely letter and check it | |
opportunity_count = len(possible_words) | |
if opportunity_count <= 1: | |
print("Found the word, it is: " + possible_words[0]) | |
break | |
letter_probabilities = { | |
k: v | |
/ opportunity_count | |
* v # This amount of the time, the letter is used, and this many would remain after that | |
+ (1 - v / opportunity_count) | |
* ( | |
opportunity_count - v | |
) # This amount of the time, the letter is not used, and this many would remain after that | |
for k, v in letter_probabilities.items() | |
} | |
best_letter = min(letter_probabilities, key=letter_probabilities.get) | |
print( | |
f"Best letter to guess: {best_letter} ({letter_probabilities[best_letter] / len(possible_words) * 100:.2f}% chance of being in a word)" | |
) | |
print( | |
f"{len(possible_words)} possible words ({format(len(possible_words) / len(all_words) * 100, '.3f')}% out of total)" | |
) | |
if len(possible_words) <= 20: | |
print("Possible words:", possible_words) | |
for i in range(word_length): | |
if len(word_letters[i]) == 25: | |
continue | |
representation = [find_representation(j) for j in word_letters] | |
representation[i] = "?" | |
user_response = input( | |
f"Is the question mark in {''.join(representation)} the letter {best_letter} (y/ )? " | |
) | |
if user_response == "y": | |
not_options = list(string.ascii_lowercase) | |
not_options.remove(best_letter) | |
word_letters[i] = not_options | |
else: | |
word_letters[i].append(best_letter) | |
print("".join([find_representation(i) for i in word_letters])) | |
print("\n") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment