import random
def find_all(s, ch):
'''Get indexes of all occurences of a char in a str (or array)
code from https://stackoverflow.com/a/11122355
'''
return [i for i, ltr in enumerate(s) if ltr == ch]
def get_words():
'''Return a list of words for user to guess
from user input or from words.txt
'''
word_source = ""
while word_source not in ["m", "p"]:
word_source = input("\n\nDo you want to enter a list of words manually (m) or use preset words (p)?\n Please enter 'm' or 'p': ")
if word_source == "p":
return open("words.txt").read().splitlines()
else:
words_string = input("\nEnter words seperated by a space (' '): ")
return words_string.split()
def new_word():
'''Get a random word from list
then remove it from list so it's not picked again
'''
global words
word = random.choice(words)
words.remove(word)
return word.lower()
def draw_hangman(lives_used):
'''draw the gallows and man being hung'''
#order: base, upright, horizontal, rope, diagonal, head, body, left arm, right arm, left leg, right leg
#each sub list is the next step in drawing the gallows
#each sub sub list is format [[x,y], character]
order = [
[[[15,0],"-"],[[15,1],"-"],[[15,2],"-"],[[15,3],"-"],[[15,4],"-"],[[15,5],"-"],[[15,6],"-"],[[15,7],"-"],[[15,8],"-"],[[15,9],"-"]],
[[[14,3],"|"],[[13,3],"|"],[[12,3],"|"],[[11,3],"|"],[[10,3],"|"],[[9,3],"|"],[[8,3],"|"],[[7,3],"|"],[[6,3],"|"],[[5,3],"|"],[[4,3],"|"],[[3,3],"|"],[[2,3],"|"],[[1,3],"|"]],
[[[0,3],"+"],[[0,4],"-"],[[0,5],"-"],[[0,6],"-"]],
[[[0,7],"+"],[[1,7],"|"]],
[[[3,4],"/"],[[2,5],"/"],[[1,6],"/"]],
[[[2,7],"-"],[[3,6],"|"],[[3,8],"|"],[[4,7],"-"]],
[[[5,7],"|"],[[6,7],"|"],[[7,7],"|"],[[8,7],"|"]],
[[[5,6],"-"],[[6,5],"/"],[[7,5],"|"],[[8,5],"|"]],
[[[5,8],"-"],[[6,9],"\\"],[[7,9],"|"],[[8,9],"|"]],
[[[9,6],"/"],[[10,6],"|"],[[11,6],"|"],[[12,6],"|"],[[13,6],"/"]],
[[[9,8],"\\"],[[10,8],"|"],[[11,8],"|"],[[12,8],"|"],[[13,8],"\\"]],
]
#16x10 array
toprint = [[" " for y in range(10)] for x in range(16)]
#print out as many items in order as lives have been used
for l in range(lives_used):
step = order[l]
for part in step:
x = part[0][0]
y = part[0][1]
character = part[1]
#add character to relevant position in toprint
toprint[x][y] = character
for m in toprint:
for n in m:
print(n, end="")
print("")
def play():
'''Play the actual game'''
# random word as chars in a list
word = list(new_word())
# set guessed word to as many blanks as there are letters in word
guessed_word = ["_"] * len(word)
lives_used = 0
guessed_letters = []
# while user hasn't completley guessed word (will also be limited by lives_used in future)
while guessed_word != word and lives_used < 11:
print("\n\n")
draw_hangman(lives_used)
# print out the guessed_word so far and wrong letters guessed in nice format
print(" ".join(guessed_word))
print("You have already guessed: " + ", ".join(guessed_letters))
guessed_letter = input("\nGuess a letter: ").lower()
# only let user guess a single letter
while len(guessed_letter) != 1 :
print("Please enter a single letter.")
guessed_letter = input("\nGuess a letter: ").lower()
# only let user guess letters they haven't guessed already
while guessed_letter in guessed_letters:
print("You already guessed that letter.")
guessed_letter = input("\nGuess a letter: ").lower()
if guessed_letter in word:
# get indexes in word that are guessed_letter
letter_indexes = find_all(word, guessed_letter)
for i in letter_indexes:
# replace correct blanks with letter
guessed_word[i] = guessed_letter
print("Correct!")
else:
lives_used += 1
print("Wrong! You have used %i lives" % lives_used)
# in future: you have n lives left
guessed_letters.append(guessed_letter)
print("\n\n")
if guessed_word == word:
print(" ".join(guessed_word))
print("Well done, you guessed the word! In total you used %i lives." % lives_used)
elif lives_used == 11:
draw_hangman(lives_used)
print("You died! Better luck next time.")
print("The word was: %s" % "".join(word))
input("Press any key to start.")
words = get_words()
play_again = 'y';
while len(words) > 0 and play_again =='y':
print("\n\n")
play()
print("\n\n")
play_again = ''
# while user doesn't enter y or n
while play_again not in ['y','n']:
play_again = input("Play again? (y/n): ").lower()
print("\n")
# if user chose to play again but while ended because len(words) == 0
if play_again == 'y':
print("Sorry, I ran out of words.")
print("Bye.")