After a quick test, your code seems to be working fine.
Before going into interesting comments, let's go through quick details. Python has a style guide called PEP8. The document is definitly worth a read. Except if you have good reason not to, you should probably comply to this guideline. You'll find various tools to check you code like pep8 or to fix it autopep8.
Here, pep8 gives :
hangman.py:3:14: E703 statement ends with a semicolon
hangman.py:3:15: E261 at least two spaces before inline comment
hangman.py:3:80: E501 line too long (106 > 79 characters)
hangman.py:5:26: E703 statement ends with a semicolon
hangman.py:6:8: E221 multiple spaces before operator
hangman.py:6:15: E703 statement ends with a semicolon
hangman.py:11:47: E703 statement ends with a semicolon
hangman.py:13:30: E703 statement ends with a semicolon
hangman.py:15:1: E302 expected 2 blank lines, found 1
hangman.py:17:44: E703 statement ends with a semicolon
hangman.py:18:24: E111 indentation is not a multiple of four
hangman.py:18:24: E113 unexpected indentation
hangman.py:20:1: E302 expected 2 blank lines, found 1
hangman.py:21:24: E703 statement ends with a semicolon
hangman.py:23:44: E703 statement ends with a semicolon
hangman.py:24:22: E703 statement ends with a semicolon
hangman.py:25:58: E703 statement ends with a semicolon
hangman.py:25:59: E261 at least two spaces before inline comment
hangman.py:25:80: E501 line too long (86 > 79 characters)
hangman.py:26:20: E703 statement ends with a semicolon
hangman.py:29:80: E501 line too long (92 > 79 characters)
hangman.py:29:92: E703 statement ends with a semicolon
hangman.py:30:44: E703 statement ends with a semicolon
hangman.py:31:24: E703 statement ends with a semicolon
hangman.py:32:23: E703 statement ends with a semicolon
hangman.py:33:80: E501 line too long (84 > 79 characters)
hangman.py:33:84: E703 statement ends with a semicolon
hangman.py:34:80: E501 line too long (87 > 79 characters)
hangman.py:34:87: E703 statement ends with a semicolon
hangman.py:35:54: E703 statement ends with a semicolon
hangman.py:37:55: E703 statement ends with a semicolon
hangman.py:40:35: E703 statement ends with a semicolon
hangman.py:42:42: E703 statement ends with a semicolon
hangman.py:43:41: E703 statement ends with a semicolon
hangman.py:45:37: E703 statement ends with a semicolon
hangman.py:46:56: E703 statement ends with a semicolon
hangman.py:47:26: E703 statement ends with a semicolon
hangman.py:49:59: E703 statement ends with a semicolon
hangman.py:51:45: E703 statement ends with a semicolon
hangman.py:52:19: E703 statement ends with a semicolon
hangman.py:53:29: E703 statement ends with a semicolon
hangman.py:54:38: E703 statement ends with a semicolon
hangman.py:55:17: E703 statement ends with a semicolon
hangman.py:58:24: E703 statement ends with a semicolon
hangman.py:59:26: E703 statement ends with a semicolon
hangman.py:61:26: E703 statement ends with a semicolon
hangman.py:61:27: E261 at least two spaces before inline comment
hangman.py:63:18: E703 statement ends with a semicolon
Also, the names do not follow the naming convention.
After fixing this, the code looks like :
import random
DEBUG = False # If set to true, displays chosen word before each game. For debugging and cheating only :)
DICT_FILE = "english.txt"
GUESSES = 10
def prompt(s):
while True:
ans = raw_input(s + " (Y/n) ").lower()
if ans in ["y", "n"]:
return ans == "y"
def load_words():
with open(DICT_FILE, "r") as f:
return f.read().strip().split("\n") # Strip in case of newline at end of file
def play(word):
word = word.lower()
if DEBUG:
print "[DEBUG] word is %r" % (word)
guesses = GUESSES
to_guess = set(l for l in word.upper() if l.isalpha()) # Handles apostrophes, etc.
letters = set()
while guesses > 0:
if len(to_guess) == 0:
print "You win with %d guess%s left!" % (guesses, "" if guesses == 1 else "es")
print "The word is %r" % (word)
return True
print "=" * 78
print "You have %d guess%s left." % (guesses, "" if guesses == 1 else "es")
print "Word: " + " ".join("_" if c in to_guess else c for c in word.upper())
print "Letters: " + " ".join(sorted(letters))
while True:
l = raw_input("Choose a letter: ").upper()
if l.isalpha():
if l not in letters:
letters.add(l)
if l in to_guess:
to_guess.remove(l)
print "Correct!"
else:
guesses -= 1
print "Sorry, not in the word."
break
else:
print "You already chose that letter!"
else:
print "That's not a letter!"
print "=" * 78
print "Sorry, you lose."
print "The word was: %r" % (word)
return False
if __name__ == "__main__":
words = load_words()
random.shuffle(words)
while True:
play(words.pop()) # Remove a random word so it's not chosen again
if not prompt("Would you like to play again?"):
break
Now, for the actual comments.
It would probably be worth writing a function to get the new letter. Something like :
def prompt_new_letter(s, letters):
while True:
l = raw_input(s).upper()
if l.isalpha():
if l not in letters:
return l
else:
print "You already chose that letter!"
else:
print "That's not a letter!"
...
l = prompt_new_letter("Choose a letter: ", letters)
letters.add(l)
if l in to_guess:
to_guess.remove(l)
print "Correct!"
else:
guesses -= 1
print "Sorry, not in the word."
Not much else to say at the moment.
;)? \$\endgroup\$from __future__ import braces\$\endgroup\$