Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old May 10th, 2006, 12:48 PM   #1
commodore
Programmer
 
Join Date: Nov 2005
Location: Estonia
Posts: 94
Rep Power: 0 commodore is an unknown quantity at this point
Noob trying to code hangman :(

I wanted to create a CLI hangman. It's supposed to read words from a while, choose a random word, let people do the guessing and stuff and if someone guesses the word it will be removed from the file. It somewhat worked but I didn't get any further. Don't laugh too hard at me...

import random
import sys
import time
filer=open('words.txt', 'r')

words=filer.read().split('\n') # puts the words in a list
orgwordstring=str(words[random.randint(0, (len(words)-1))]) # chooses a random word from the list
orgword=[]
for i in orgwordstring: # puts the letters in a string
    orgword.append(i)

ranges=len(orgword)-2 # how many letters have to be replaced with '_'
newword=[orgword[0]]
for i in range(1, ranges+1):
    newword.append('_')
newword.append(orgword[-1])

life=10
while newword!=orgword or life!=0:
    print 'The word is: %s' % (' '.join(newword))
    print ''
    what=str(raw_input('Type in a letter that you think should be in that word or leave empty if you want to quit: '))
    if what=="":
        sys.exit()
    elif ''.join(orgword).find(what)==-1:
        life=life-1
        print 'Sorry this letter isn\'t included in the word. You have lost a life. You have %d lives left' % (life)
    else:
        finding=''.join(orgword).find(what)
        while finding!=-1:
            newword[finding]=orgword[finding]

filer.close()
if life!=0:
    'Gongratulations! You have guessed the word! It is ', newword
    wordloc=''.join(words).find(orgword)
    del words[wordloc]  # deletes the guessed word from the list
    words='\n'.join(words)                     
    filew=open('words.txt', 'w')
    filew.write(words)  # writes the words back to the file, now without the guessed word
    filew.close()
else:
    'You have 0 lives left. You didn\'t guess the word.'
time.sleep(10)
sys.exit()
commodore is offline   Reply With Quote
Old May 10th, 2006, 3:08 PM   #2
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
You use list comprehensions and various object functions very well for a "noob", so my congratulations there!

Still, I can recommend some improvements. First, the readlines function on file objects comes in handy (note that filew.writelines will do the reverse):
words = filer.readlines()
And so too does the random.choice function (plus the strip function, for removing the newline character at the end of the word):
orgwordstring = random.choice(words).strip()
To turn a string into a list:
orgword = list(orgwordstring)
And to replace all the middle letters with _s, you can use the * operator on a string (e.g. ("a" * 4) becomes "aaaa"):
newword = list(orgword[0] + ("_" * (len(orgword) - 2)) + orgword[-1])
Instead of find, a good tip is to use the "in" operator instead:
if what == "":
    sys.exit()

if what not in orgword:
    life -= 1
    print "Sorry this letter isn't included in the word."
else:
    for position, letter in enumerate(orgword):
        if letter == what:
            newword[position] = letter
I've also done away with find here, instead opting for a for-loop (the enumerate function encodes the index with each item in the list). However, your use of find wasn't a bad decision; for large pieces of text using the find function is a must. However, since words are usually less than 10 letters long, the efficiency gains by using find are very small. Also, with a for-loop you can guarentee that the loop will finish, whilst it's easier to get the logic wrong in a while loop.

Which, coincidentally, is what's wrong with your code. You don't change the "finding" variable in the loop, so it keeps replacing the same letter over and over again:
        finding=''.join(orgword).find(what)
        while finding!=-1:
            newword[finding]=orgword[finding]
Arevos is offline   Reply With Quote
Old May 11th, 2006, 12:06 AM   #3
hydroxide
Programmer
 
Join Date: Apr 2005
Posts: 73
Rep Power: 4 hydroxide is on a distinguished road
The logic could be _much_ simpler if you processed your two lists as follows. The code is VERY rough - just to give the idea. Actual correct implementation is left as an exercise ;-)
solution = list(word)
current = ["_"] * len(word)
guessed = set()

def replace_if_ok(sollet, currlet, letter):
    if sollet == letter:
        return sollet
    else:
        return currlet
while lives:
    if letter in guessed:
        handle_it()
    elif letter not in solution:
        do_something()
    else:
        current = [replace_if_ok(sollet, currlet, letter)
                       for sollet, currlet in zip(solution, current)]
    guessed.add(letter)
    print " ".join(current)
hydroxide is offline   Reply With Quote
Old May 11th, 2006, 9:15 AM   #4
demon101
Hobbyist Programmer
 
demon101's Avatar
 
Join Date: Mar 2006
Location: westboro, ohio
Posts: 159
Rep Power: 0 demon101 is an unknown quantity at this point
Send a message via Yahoo to demon101
i am a noob and i am not even going to try that i dont know loops that well. i would like to make a web server or something along that line.

i would like to make something like sane did.
__________________
Demon101 Production's

Code Forums
demon101 is offline   Reply With Quote
Old May 11th, 2006, 9:43 AM   #5
commodore
Programmer
 
Join Date: Nov 2005
Location: Estonia
Posts: 94
Rep Power: 0 commodore is an unknown quantity at this point
Thank you Arevos and hydroxide!

Web server? Am I not understanding something in here? Do you want to make a website in python? I want to do it too. I already did some coding, but I don't have a cgi enabled web server because I don't have money
commodore is offline   Reply With Quote
Old May 11th, 2006, 10:16 AM   #6
commodore
Programmer
 
Join Date: Nov 2005
Location: Estonia
Posts: 94
Rep Power: 0 commodore is an unknown quantity at this point
I haven't tried hydroxide's version yet. Arevos' post helped me a lot but I still have a problem. It doesn't exit the biggest while loop. If I guess the word it will still offer me to guess it and if I have lost all my lives it still does so.

The current code looks like this:

import random
import sys
import time
filer=open('words.txt', 'r')

words=filer.readlines() # puts the words in a list
orgwordstring=random.choice(words).strip() # chooses a random word from the list
orgword=list(orgwordstring)

newword=list(orgword[0]+((len(orgword)-2)*'_')+orgword[-1])

life=10
while newword!=orgword or life!=0:
    print 'The word is: %s' % (' '.join(newword))
    print ''
    what=str(raw_input('Type in a letter that you think should be in that word or leave empty if you want to quit: '))
    if what=="":
        sys.exit()
    if what not in orgword:
        life=life-1
        print 'Sorry this letter isn\'t included in the word. You have lost a life. You have %d lives left' % (life)
    else:
        for position, letter in enumerate(orgword):
            if letter == what:
                newword[position]=letter

filer.close()
if life!=0:
    'Gongratulations! You have guessed the word! It is ', newword
    wordloc=''.join(words).find(orgword)
    del words[wordloc]  # deletes the guessed word from the list
    words='\n'.join(words)                     
    filew=open('words.txt', 'w')
    filew.write(words)  # writes the words back to the file, now without the guessed word
    filew.close()
else:
    'You have 0 lives left. You didn\'t guess the word.'
time.sleep(10)
sys.exit()
commodore is offline   Reply With Quote
Old May 11th, 2006, 10:19 AM   #7
UnKnown X
Hobbyist Programmer
 
UnKnown X's Avatar
 
Join Date: Dec 2005
Location: Sandvika, Norway
Posts: 114
Rep Power: 0 UnKnown X is an unknown quantity at this point
Send a message via MSN to UnKnown X
I've made my own hangman game with which you can compare yours. I don't know if you're familiar with functions, but it should be fairly easy to see what's going on.

import random

def get_guess(used_letters, word, word_hidden):
    while True:
        guess = get_string("Guess a letter or the entire word.").lower()
        if not guess.isalpha():
            print "Cannot use '%s' as the guess (failed at guess.isalpha()). Try again." % guess
        elif guess == word:
            return "$word"
        elif len(guess) != 1:
            return "$wrong"
            continue
        elif len(guess) == 1:
            error = False
            for letter in used_letters:
                if guess == letter:
                    print "You've already guessed '%s'! Try again." % guess,
                    error = True
                    break
            for letter in word_hidden:
                if guess == letter:
                    print "You've already used '%s'! Try again." % guess,
                    error = True
                    break
            if error == True:
                continue
            return guess

def get_string(message):
    print str(message) + "\n"
    while True:
        try:
            the_string = raw_input("> ")
        except ValueError:
            print "ValueError exception encountered! Try again."
            continue
        if the_string == "":
            print "Error! Empty string! Try again."
            continue
        break
    return the_string

def play(word):
    word_hidden = "_"*len(word[2:])
    used_letters = []
    tries_left = 8
    while True:
        print "\n\t\t\t%s\nValue: %s points\n" % (word_hidden, word[0:2])
        if used_letters != []:
            print "---- Used letters:", used_letters
        print ""
        guess = get_guess(used_letters, word[2:], word_hidden)
        print "\n\n"
        if guess == "$word":
            print "Correct!"
            guessed_letters = []
            for letter in word_hidden:
                if letter.isalpha():
                    used = False
                    for item in guessed_letters:
                        if letter == item:
                            used = True
                    if used == False:
                        guessed_letters.append(letter)
            if len(guessed_letters) == 0:
                print "\nMEGABONUS!!!\n"
                return int(word[0:2])*5
            elif len(used_letters) == 0:
                print "\nSUPER BONUS!!\n"
                return int(word[0:2])*3
            else:
                print "\nBonus!\n"
                return int(word[0:2])*2 - len(guessed_letters)
        i = 0
        guessed = False
        if guess != "$wrong":
            for letter in word[2:]:
                if guess == letter:
                    word_hidden = word_hidden[:i] + guess + word_hidden[i+1:]
                    guessed = True
                i += 1
        if word_hidden == word[2:]:
            print "Correct! You found the word '%s'!" % word[2:]
            return int(word[0:2])
        if guessed == True:
            print "Found one!"
        else:
            print "Wrong!",
            tries_left -= 1
            if tries_left > 1:
                print "Tries left:", tries_left
            elif tries_left == 1:
                print "This is your last try!!"
            elif tries_left == 0:
                print "\nYou didn't find the word '%s'..." % word[2:]
                return 0
            if guess != "$wrong":
                used_letters.append(guess)

def wait(message):
    raw_input(message)

def main():
    print "Initializing...\n"
    fwords = open("hmwl.hang", "r")
    shuffle = random.shuffle
    wordlist = []
    for line in fwords.read().split("\n"):
        wordlist.append(line)
    shuffle(wordlist)
    fwords.close()
    score = 0
    extra = 0
    continues = 3
    while continues >= 0:
        word = wordlist.pop()
        points = play(word)
        if points == 0:
            continues -= 1
        else:
            score += points
            extra += points
        print "\nScore: %d points + %d points won = %d points" % (score-points, points, score)
        while extra >= 100:
            continues += 1
            print "\nExtra chance awarded! Chances left:", continues
            extra -= 100
        if continues == 1:
            print "\nThis is your last chance!!"
        elif continues == 0:
            print "\nGame over."
            break
        else:
            print "\nChances left:", continues
        wait("\nPress enter to continue...")
        print "\n\n\n"
    wait("Exiting...")

if __name__ == '__main__':
    main()

My wordlist was over 7MB, so I can't attach it, but here's just a short (and rather silly) one if you want to test the programme (I generated the values with another programme). Just put this in a file called "hmwl.hang":

09animal
22antidisestablishmentarianism
08apple
28bababadalgharaghtakamminarronnkonnbronntonnerronntuonnthunntrovarrhounawnskawntoohoohoordenenthur
07cat
07dog
22ethylenediaminetetraacetates
21floccinaucinihilipilification
09fruit
08game
10hangman
23honorificabilitudinitatibus
33lipsmackinthirstquenchinacetastinmotivatingoodbuzzincooltalkinhighwalkinfastlivinevergivincoolfizzin
28llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
10monkey
10orange
08pear
24pneumonoultramicroscopicsilicovolcanoconiosis
10program
10python
20sesquipedalianism
28sodiummetadiaminoparadioxyarsenobenzoemethylenesulphoxylate
25supercalifragilisticexpialidocious
28twoallbeefpattiesspecialsaucelettucecheesepicklesonionsonasesameseedbun
09waffle

(Edit: Some of the words are fairly long and the forum code inserts a space there. If you quote my post, it'll be easier to copy-paste)
UnKnown X is offline   Reply With Quote
Old May 11th, 2006, 4:12 PM   #8
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
In your while loop, you're using "or" when you should be using "and".

The while loop runs whilst the condition it's initiated with is true. The first element of your condition is "newword!=orgword". This will become false when the user wins at hangman. The second condition is "life!=0". This will become false when the user loses at hangman.

With the "or" operator, the while condition will remain true so long as one of the conditions is true. You want the loop to end if any one of the conditions becomes false, so you want an "and":

while newword!=orgword and life!=0:
Arevos is offline   Reply With Quote
Old May 11th, 2006, 4:15 PM   #9
Arevos
Programming Guru
 
Arevos's Avatar
 
Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4 Arevos is on a distinguished road
As an aside, you can remove an object from a list more easily with the "remove" method:
words.remove("".join(orgword) + "\n")
(The newline is on the end because readlines doesn't remove it). And write a whole bunch of lines to a file via writelines:
filew=open('words.txt', 'w')
filew.writelines(words)
filew.close()
Arevos is offline   Reply With Quote
Old May 12th, 2006, 10:59 AM   #10
commodore
Programmer
 
Join Date: Nov 2005
Location: Estonia
Posts: 94
Rep Power: 0 commodore is an unknown quantity at this point
Thanks Arevos! It works perfectly now!

The code is here (LOL at the MIT license):
'''
The MIT License

Copyright (c) 2006 Ville Sokk (Commodore)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

NOTE: the program was taken to the final state thanks to the help of Arevos from http://www.programmingforums.org
'''

import random
import sys
import time
filer=open('words.txt', 'r')

words=filer.readlines() # puts the words in a list
orgwordstring=random.choice(words).strip() # chooses a random word from the list
orgword=list(orgwordstring)

newword=list(orgword[0]+((len(orgword)-2)*'_')+orgword[-1])

life=10
while newword!=orgword and life!=0:
    print 'The word is: %s' % (' '.join(newword))
    print ''
    what=str(raw_input('Type in a letter that you think should be in that word or leave empty if you want to quit: '))
    if what=="":
        sys.exit()
    if what not in orgword:
        life=life-1
        print 'Sorry this letter isn\'t included in the word. You have lost a life. You have %d lives left' % (life)
    else:
        for position, letter in enumerate(orgword):
            if letter == what:
                newword[position]=letter

filer.close()
if life==0:
    print 'You have 0 lives left. You didn\'t guess the word.'
else:
    print 'Gongratulations! You have guessed the word! It is ', ''.join(orgword)
    words.remove(''.join(orgword)+'\n')
    words=''.join(words)                     
    filew=open('words.txt', 'w')
    filew.writelines(words)  # writes the words back to the file, now without the guessed word
    filew.close()

exiter=raw_input('Press enter to quit: ')
while exiter!='':
    exiter=raw_input('I said press ENTER! ')
if exiter=='':
    sys.exit()

I have to finish my other (non-programming) projects and then I can try other peoples versions too!
commodore is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 6:06 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC