简体   繁体   中英

How to code so the program finds multiple instances - Python

I have this code:

Words = ['python','candy', 'banana', 'chicken', 'pizza', 'calculus',
     'cheeseburger', 'binder', 'computer', 'pencil', 'school'
     'artist', 'soccer', 'tennis', 'basketball', 'panda',
     'zebra', 'horse', 'cereal', 'alphabet', 'understand']

number = raw_input('Enter a 1 through 20: ')
x = list()
find = list(Words[int(number)-1])
notherword = list(Words[int(number)-1])
l = list(len(find)*'_')
print 'Your word is', len(find)*'_ '
playing = True
while playing:
    letter = raw_input('Please pick a letter ')
    if letter in find:
        a = find.index(str(letter))
        l[int(a)] = letter
        q = (' ')
        j = q.join(l)
        print j
        find[a] = ('_')
        if l == notherword:
            print 'You win!!!'
            playing = False
    else:
        print 'Strike ' +str(len(x)+1) +str('.') +str(' Not a letter in the word')
        x.append(letter)
        if len(x) > 4:
            print 'Game Over x('
            playing = False

This is a hangman game. You first pick a number then that number corresponds with the word and starts a game of hangman. But when i do the word banana it only finds the first a and does not find the other a's. How do I code so that it can find multiple instances at the same time so that it runs through fine??

Edited with newer code

A simple solution would be to replace the found letters with something else, so they can't be found twice. You could grab all the indexes of a given letter using a list comprehension:

if letter in find:
    # use a list comprehension to get the index of all occurrences of a given letter
    indexes = [i for i, char in enumerate(find) if char == letter]
    # update found and l accordingly
    for i in indexes:
        find[i] = None
        l[i] = letter

And then to check if they've won, you can instead do:

if '_' not in l:
    print 'You win!!!'

You'll also want to create x outside of the while loop, instead of recreating it every time a player guesses wrong, so the player can actually lose (you can also do while True and break, instead of using the playing variable):

x = list()
while True:
    ...
    else:
        print 'Not a letter in the word'
        x.append(letter)
        if len(x) > 4:
            print 'Game Over'
            break

As an aside, you don't need to use str or int in the loop. Also ''.join() is a common Python idiom, you should use that instead. Here's a revised version, taking the above into consideration:

Words = ['python','candy', 'banana', 'chicken', 'pizza', 'calculus',
     'cheeseburger', 'binder', 'computer', 'pencil', 'school'
     'artist', 'soccer', 'tennis', 'basketball', 'panda',
     'zebra', 'horse', 'cereal', 'alphabet', 'understand']

number = raw_input('Enter a 1 through 20: ')

find = list(Words[int(number)-1])
l = list(len(find)*'_')
x = list()

print 'Your word is', len(find)*'_ '

while True:
    letter = raw_input('Please pick a letter ')
    if letter in find:
        indexes = [i for i, char in enumerate(find) if char == letter]
        for i in indexes:
            find[i] = None
            l[i] = letter
        print ' '.join(l)
        if '_' not in l:
            print 'You win!!!'
            break
    else:
        print 'Not a letter in the word'
        x.append(letter)
        if len(x) > 4:
            print 'Game Over'
            break

You have to use a loop to match each a in turn:

while playing:
    letter = raw_input('Please pick a letter ')
    while letter in find:
        a = find.index(letter)

        # Clear the letter so we can match the next instance.
        find[a] = None 

        l[a] = letter
        q = (' ')
        j = q.join(l)
        print j
        if l == find:
            print 'You win!!!'
            playing = False
    else:
        ....

[ It's not all that commonly done, but you can use else with while in Python. ]

Also, you should set x = list() above the game loop, as it stands, you will never lose.

You should replace this

if letter in find:
    a = find.index(str(letter))
    l[int(a)] = letter

with this

letter_in_word = False
for a,c in enumerate(find):
    if c == letter:
        l[a] = letter
        letter_in_word = True
if letter_in_word:
    ...
else:
    ...

Instead of

a = find.index(str(letter))
l[int(a)] = letter

Try this

[l.__setitem__(pos, letter) for pos in range(len(find)) if find[pos]==letter]

Basically, it iterates over the word sets the letter at the position to be the chosen letter if the chosen letter is at that position in the word that needs to be found.

I wouldn't normally just write the code for someone, but sometimes it's the best way to illustrate various techniques. Please study closely. Note that if I were actually writing this code, it wouldn't have any of those comments; these techniques are standard.

# Let's wrap the "main" code in a function for cleanliness.
def main():
    words = [
        'python','candy', 'banana', 'chicken', 'pizza', 'calculus',
        'cheeseburger', 'binder', 'computer', 'pencil', 'school'
        'artist', 'soccer', 'tennis', 'basketball', 'panda',
        'zebra', 'horse', 'cereal', 'alphabet', 'understand'
    ]
    import random
    word = random.choice(words)
    # Instead of using a list of characters for what's been
    # guessed, a string will work fine. We can iterate over it
    # the same way.
    guessed = '_' * len(word)
    failures = '' # used to be 'x'. Use descriptive names.

    # To break out of a loop, we can use the 'break' keyword.
    # So we don't really need a separate variable to control the loop.
    # We want to show status every time through the loop, so we put that
    # inside the loop.
    while True:
        print guessed
        # Note the idiomatic way we use to intersperse spaces into the word.
        print 'Not in the word:', ' '.join(failures)
        letter = raw_input('Please pick a letter: ')
        # We use the following trick to update the guess status:
        # 1) We'll create a second string that contains the guessed
        # letter in each place where it should appear.
        # 2) If that string differs from the old guess, then we
        # must have guessed a letter correctly. Otherwise, the letter
        # is not in the word.
        # We take pairs of letters from `word` and `guessed` using the
        # zip() function, and use the letter from the word if it's matched,
        # and otherwise keep the letter from the old guess. `''.join` joins
        # up all the chosen letters to make a string again.
        new_guess = ''.join(
            w if w == letter else g
            for (w, g) in zip(word, guessed) 
        )
        if new_guess == word:
            print 'You win!!!'
            break
        elif new_guess != guessed:
            print "Yes, '%s' is in the word." % letter
        else:
            # Instead of having the ugly '+1' in the logic for counting misses,
            # just count the misses *after* processing this one. Also note how
            # the string formatting works.
            failures += letter
            print "Strike %d. '%s' is not in the word." % (len(failures), letter)
            if len(failures) > 4:
                print 'Game Over x('
                break

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM