Your code looks pretty good
Here's a different approach, using classes, functions and sets. It's a little longer, I think, and it's perhaps not as obvious what's doing what. But it might be of use in demostrating a different path to the same solution.
import random
def random_line(filename):
"Returns a random line from a file."
file = open(filename)
try: return random.choice(file.readlines())
finally: file.close()
class AlreadyGuessed(Exception):
def __init__(self, letters):
self.letters = letters
class Word(object):
def __init__(self, word, lives = 10):
self.word = word
self.guesses = set()
self.lives = lives
def guess(self, letters):
"Guess letter(s) in the word."
same = set(letters).intersection(self.guesses)
if same: raise AlreadyGuessed(same)
self.guesses.add(letters)
self.lives -= len([l for l in letters if l not in self.word])
@property
def lost(self): return self.lives == 0
@property
def won(self): return set(self.word).issubset(self.guesses)
@property
def wrong_guesses(self):
return word.guesses.difference(set(self.word))
def __str__(self):
"Returns a string showing how much the user has guessed of the word."
return " ".join(l not in self.guesses and "_" or l for l in self.word)
if __name__ == '__main__':
word = Word(random_line("words.txt").strip().lower())
while not word.lost and not word.won:
print "Word:", word
print "Wrong guesses:", " ".join(word.wrong_guesses)
print "Lives left:", word.lives
print
try:
word.guess(raw_input("Please enter a letter: ").lower())
except AlreadyGuessed, e:
print "Already guessed:", " ".join(e.letters)
if word.lost: print "You've lost."
elif word.won: print "You've won."
print "The word was:", word.word