Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Command Line Hangman Game in Python
New Posts  All Forums:Forum Nav:

Command Line Hangman Game in Python

post #1 of 7
Thread Starter 
Hey, guys! I've gotten bored recently so I have quickly coded up a Command Line Hangman Game and wanted to share it with you guys smile.gif. It handles all input, gets a word list from a text file, gets the hangman frames from a text file, and is only 35 lines of code smile.gif. It was a great short project and I actually used the 'try and except' code block in Python for the first time. However, if you're trying it on Linux, replace os.system('cls') with os.system('clear'). Here it is!

hangman.py
Code:
import random, string, time, os
frames = open('hangman.txt').read().split('nextscene\n')
rword = random.choice(open('words.txt').read().split('\n'))
key = rword.translate(string.maketrans(string.lowercase, '_' * len(string.lowercase)))
letters = []
def clear(s):
    print s
    time.sleep(1); os.system('cls')
while True:
    print frames[0] % (str(letters).replace('\'', ''), key)
    if key == rword:
        print 'YOU WIN!'; break
    if len(frames) == 1:
        print 'YOU LOSE!'; break
    try:
        letter = raw_input()
    except:
        clear('That is not valid input!'); continue
    if letter not in [l for l in string.lowercase]:
        clear('That is not valid input!'); continue
    if letter in letters:
        clear('That letter was already tried!'); continue
    letters.append(letter)
    if letter in rword:
        key = [t for t in key]; c = 0; n = []
        for a in rword:
            if a == letter:
                n.append(c)
            c += 1
        for b in n:
            key[b] = rword[b]
        key = ''.join(key)
        clear('That letter is in the word!'); continue
    del frames[0]
    clear('That letter is not in the word!')

hangman.txt
Code:
HANGMAN  %s
 _______
|   |  \|
        |
        |
        |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
        |
        |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
    |   |
        |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
   \|   |
        |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
   \|/  |
        |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
   \|/  |
    |   |
        |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
   \|/  |
    |   |
   /    |
        |
        |
       ---
%snextscene
 HANGMAN  %s
 _______
|   |  \|
    O   |
   \|/  |
    |   |
   / \  |
        |
        |
       ---
%s

words.txt
Code:
jazz
strengths
gypsy
rhythmic
cognac
jukebox
sprightly
asthma
orphan
months
czar
depths
geniuses
withhold
powwow
bookkeeper
kamikaze
fettuccine
quagmire
mannequin
caribou
nymph
skiing
queueing
symphony
crypt
wintry
twelfth
sequoia
gauntlet
zoology
unscrupulous
tympani
furlough
coffee
papaya
catchphrase
paprika
brouhaha
impromptu
cyclists
plateaued
cushion
alfalfa
jambalaya
ukulele
anchovy
messiah
buoyed
rendezvous

Edited by BuizelON - 8/9/13 at 7:36pm
post #2 of 7
Thread Starter 
Bump?
Any constructive criticism or tips to what I should have done?
post #3 of 7
Can you add a screen shot of some sample console output? As for constructive criticism, it's pretty sweet that you could complete the entire game is such few lines of code but now try to abstract it so that the code is more readable. Obviously this isn't needed in a small little game like this, but I would suggest trying to get good at splitting your code up into separate modules so that things don't get messy.

Try to see how generic you can make the game, so that you can add new features by just adding another module, limiting the amount of code changing that needs to go on.
post #4 of 7
Thread Starter 
"Can you add a screen shot of some sample console output?"
Sure.
d8a0eec8_hangman.gif
"As for constructive criticism, it's pretty sweet that you could complete the entire game is such few lines of code but now try to abstract it so that the code is more readable. Obviously this isn't needed in a small little game like this, but I would suggest trying to get good at splitting your code up into separate modules so that things don't get messy.

Try to see how generic you can make the game, so that you can add new features by just adding another module, limiting the amount of code changing that needs to go on."
Thanks for the advice biggrin.gif.

EDIT: Sorry, but you have to right click on the 'No Image Available' image and click on 'Open Link In New Tab' (in Chrome, don't know about IE or FF) to actually see the screenshot. Don't know why OCN is doing that though? Did I format something wrong?

EDIT 2: Never mind, I got it working.
Edited by BuizelON - 8/9/13 at 4:33pm
post #5 of 7
if you want a little constructive criticism
0: # 0 because it only apples if cross platform is a goal
Code:
os.system('cls')
could be written using a ternary conditional operator
Code:
os.system('cls' if os.name=='nt' else 'clear')
or a true/false list index
Code:
os.system(['clear','cls'][os.name == 'nt'])


1:
you did not close the files you opened, a small point since you did not write to them
Code:
frames = open('hangman.txt').read().split('nextscene\n')
rword = random.choice(open('words.txt').read().split('\n'))
Code:
frameFile = open('hangman.txt')
frames = frameFile.read().split('nextscene\n')
frameFile.close()

wordFile = open('words.txt')
rword = random.choice(wordFile.read().split('\n'))
wordFile.close()

2:
if you create the word and the key as a list of the same length then you could use one for loop to check for a letter match and change the key at the same time
and with another boolean display the message for the match
Code:
    letters.append(letter)
    
    if letter in rword:
        key = [t for t in key]
        c = 0
        n = []
        for a in rword:
            if a == letter:
                n.append(c)
            c += 1
        for b in n:
            key[b] = rword[b]
        key = ''.join(key)
        clear('That letter is in the word!')
        continue
      
    del frames[0]
    clear('That letter is not in the word!')
Code:
     if letter not in letters:
        letters.append(letter)

        for a in range(len(rword)):
            if letter == rword[a]:
                key[a] = letter
                inWord = True
                
        if inWord:
            display('That letter is in the word!' + '\n' + 'Enter a guess')
        else:
            del frames[0]
            display('That letter is not in the word!' + '\n' + 'Enter a guess')

3:
you said it was the first time you used try/execpt. but it could be done a lot easier
Code:
     try:
        letter = raw_input()
    except:
        clear('That is not valid input!')
        continue
      
    if letter not in [l for l in string.lowercase]:
        clear('That is not valid input!')
        continue
Code:
    valid = False
    while not valid:
        letter = raw_input().lower()
        if len(letter) != 1 or ord(letter) < ord("a") or ord(letter) > ord("z"): # I didn't use the string module
            display('That is not valid input!' + '\n' + 'Enter a guess')
        else:
            valid = True

this is a good effort, and I'm not knocking it, just giving some hints on alternative ways of doing things
Core I7
(13 items)
 
  
CPUMotherboardGraphicsRAM
I7 920 rev. D0 @ 4.26Ghz EVGA X58 SLI EVGA GTX 285 OCZ XMP 3x2Gb (pc3 12800) 
Hard DriveOptical DriveOSMonitor
Western Digital Caviar Black 640Gb x 2 LG GH22LS30 openSuse 12.1 x64 HP F2105 
PowerCase
CORSAIR 850TX Cooler Master ATCS 840 
  hide details  
Reply
Core I7
(13 items)
 
  
CPUMotherboardGraphicsRAM
I7 920 rev. D0 @ 4.26Ghz EVGA X58 SLI EVGA GTX 285 OCZ XMP 3x2Gb (pc3 12800) 
Hard DriveOptical DriveOSMonitor
Western Digital Caviar Black 640Gb x 2 LG GH22LS30 openSuse 12.1 x64 HP F2105 
PowerCase
CORSAIR 850TX Cooler Master ATCS 840 
  hide details  
Reply
post #6 of 7
Thread Starter 
Quote:
1:
you did not close the files you opened, a small point since you did not write to them
Code:
frames = open('hangman.txt').read().split('nextscene\n')
rword = random.choice(open('words.txt').read().split('\n'))
Code:
frameFile = open('hangman.txt')
frames = frameFile.read().split('nextscene\n')
frameFile.close()

wordFile = open('words.txt')
rword = random.choice(wordFile.read().split('\n'))
wordFile.close()
Sorry if this sounds idiotic, but does closing files increase the "performance" at all, or is it just good practice?
Quote:
2:
if you create the word and the key as a list of the same length then you could use one for loop to check for a letter match and change the key at the same time
and with another boolean display the message for the match
Code:
    letters.append(letter)
    
    if letter in rword:
        key = [t for t in key]
        c = 0
        n = []
        for a in rword:
            if a == letter:
                n.append(c)
            c += 1
        for b in n:
            key[b] = rword[b]
        key = ''.join(key)
        clear('That letter is in the word!')
        continue
      
    del frames[0]
    clear('That letter is not in the word!')
Code:
     if letter not in letters:
        letters.append(letter)

        for a in range(len(rword)):
            if letter == rword[a]:
                key[a] = letter
                inWord = True
                
        if inWord:
            display('That letter is in the word!' + '\n' + 'Enter a guess')
        else:
            del frames[0]
            display('That letter is not in the word!' + '\n' + 'Enter a guess')
Thanks biggrin.gif! I would have never thought of that. Well, maybe I would have, if I spent enough time thinking about it.
Quote:
3:
you said it was the first time you used try/execpt. but it could be done a lot easier
Code:
     try:
        letter = raw_input()
    except:
        clear('That is not valid input!')
        continue
      
    if letter not in [l for l in string.lowercase]:
        clear('That is not valid input!')
        continue
Code:
    valid = False
    while not valid:
        letter = raw_input().lower()
        if len(letter) != 1 or ord(letter) < ord("a") or ord(letter) > ord("z"): # I didn't use the string module
            display('That is not valid input!' + '\n' + 'Enter a guess')
        else:
            valid = True
Yeah, sorry, I should have explained why I used the try/except block in the OP. I was using it to handle any characters that would cause the Keyboard Interrupt Error to be raised (like CTRL-Z or something like that).
Quote:
this is a good effort, and I'm not knocking it, just giving some hints on alternative ways of doing things
Yeah, I know, thanks biggrin.gif! +REP
post #7 of 7
Quote:
Originally Posted by BuizelON View Post

Sorry if this sounds idiotic, but does closing files increase the "performance" at all, or is it just good practice?
Nothing to do with performance, just good practice in this case, since your only reading from the files.
Quote:
Originally Posted by BuizelON View Post

Yeah, sorry, I should have explained why I used the try/except block in the OP. I was using it to handle any characters that would cause the Keyboard Interrupt Error to be raised (like CTRL-Z or something like that).
okay, didn't know that was the goal.thumb.gif
Core I7
(13 items)
 
  
CPUMotherboardGraphicsRAM
I7 920 rev. D0 @ 4.26Ghz EVGA X58 SLI EVGA GTX 285 OCZ XMP 3x2Gb (pc3 12800) 
Hard DriveOptical DriveOSMonitor
Western Digital Caviar Black 640Gb x 2 LG GH22LS30 openSuse 12.1 x64 HP F2105 
PowerCase
CORSAIR 850TX Cooler Master ATCS 840 
  hide details  
Reply
Core I7
(13 items)
 
  
CPUMotherboardGraphicsRAM
I7 920 rev. D0 @ 4.26Ghz EVGA X58 SLI EVGA GTX 285 OCZ XMP 3x2Gb (pc3 12800) 
Hard DriveOptical DriveOSMonitor
Western Digital Caviar Black 640Gb x 2 LG GH22LS30 openSuse 12.1 x64 HP F2105 
PowerCase
CORSAIR 850TX Cooler Master ATCS 840 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Coding and Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Command Line Hangman Game in Python