2016-08-02 23 views
0

Ich habe ein Hangman-Spiel mit einem Fehler erstellt: Wenn Sie den gleichen Buchstaben zweimal erraten, wird er unterbrochen. Ich habe eine Liste aller Buchstaben des Alphabets erstellt und wenn der Spieler diesen Buchstaben rät, wird er aus der Liste entfernt, in der die verbleibenden Zeichen angezeigt werden, die erraten kann. Dies wird durch die .remove-Methode erreicht, die bricht, wenn das Zeichen bereits von einer vorherigen Schätzung entfernt wurde.Eine Liste scannen - IndexError: Listenindex außerhalb des gültigen Bereichs

Ich habe versucht, diese Methode in eine for-Schleife zu verschachteln, die die alphabetische Liste scannt und die Schätzung des Benutzers für eine Übereinstimmung in der Liste überprüft und sie entfernt. Wenn es bereits erraten wurde, wird nichts passieren. Der Fehler, den ich erhalte, ist ein Indexfehler, vermutlich für die Länge der Schätzung. Meine Verwirrung kommt von der Tatsache, dass ich diese genau gleiche Aufgabe direkt unten erreichen kann, wenn ich das Henkerwort einscanne, um der Schätzung des Spielers zu entsprechen. Bitte beachten Sie den folgenden Kurzcode:

# Play begins and player guesses a letter 
player_word = ['_ '] * len(cpu_word) 
player_word2 = ['_'] * len(cpu_word) 
alphabet = ['a','b',etc.] 
print 'You have 10 guesses left' 

# Determines if the guess is correct 
for count in range(10)[::-1]: 
    guess = raw_input(str('Guess a letter: ')) 
    # This is the previous method that creates a bug:/ 
    # alphabet.remove(guess) 
    for e in xrange(len(alphabet)): 
     if alphabet[e] == guess: 
      alphabet.remove(guess) 
    for i in xrange(len(cpu_word)): 
     if cpu_word[i] == guess: 
      player_word [i] = cpu_word [i] 
      print 'Correct!' 

Ich habe zwei Fragen. Der erste ist, dass mir jemand diesen Fehler erklären kann, insbesondere warum er das Hangman-Wort scannt, aber nicht für das Scannen der Liste funktioniert.

Und zweitens kann jemand eine Lösung für dieses Problem bieten.

Ich bin neu in Codierung, so dass jede Info sehr geschätzt wird!

Dank

+0

Danke Münchhausen, das ist die einfache Lösung, nach der ich gesucht habe! – Chris

Antwort

0

Ihr Problem ist, dass, nachdem Sie ein Element aus dem Array entfernen, hat es jetzt ein weniger Element, was bedeutet, dass Sie nicht mit dem früheren Ende des Arrays gehen. Wenn Ihr Buchstabenfeld 26 lang ist und Sie einen Buchstaben entfernen, können Sie nicht mehr auf das 26. Element zugreifen, da das Array jetzt nur noch aus 25 Elementen besteht.Nachdem Sie richtig erraten, könnten Sie einfach brechen, etwa so:

for e in xrange(len(alphabet)): 
    #print alphabet[e], e 
    if alphabet[e] == guess: 
     alphabet.remove(guess) 
     break 

jedoch Sie nur die Linie über Kommentar- könnten, und prüfen, ob es vor dem Entfernen es in der Anordnung ist, wie folgt aus:

for count in range(10)[::-1]: 
guess = raw_input(str('Guess a letter: ')) 
if(guess in alphabet): 
    """"This is the previous method that creates a bug:/""" 
    alphabet.remove(guess) 
    for i in xrange(len(cpu_word)): 
     if cpu_word[i] == guess: 
      player_word [i] = cpu_word [i] 
      print 'Correct!' 
+0

Ich bin mir nicht sicher, welches die Best Practices-Methode ist, aber beide funktionieren, und ich weiß es zu schätzen, dass Sie mir geholfen haben zu verstehen, warum die frühere Methode dies nicht getan hat. Vielen Dank! – Chris

+0

Persönlich würde ich nur den zweiten Weg verwenden (mit der if-Anweisung), seine Zeilen weniger Code und sieht einfach sauberer, aber beide funktionieren. Froh, dass ich helfen konnte! – Wso

1

Ihr Problem ist Indizes Schleife durch die Liste verwenden, und zugleich die Größe der Liste ändern. Sie können entweder eine Schleife durch die Elemente direkt:

for letter in alphabet: 
    if letter == guess: 
     alphabet.remove(guess) 

Oder Sie brechen können, wenn Sie den Buchstaben entfernt haben:

for e in range(len(alphabet)): 
    if alphabet[e] == guess: 
     alphabet.remove(guess) 
     break 

Pause Beendigung der Schleife stoppt, was in Ordnung ist, weil Sie damit fertig sind nachdem du den Brief entfernt hast.

Ich denke, ein set wäre besser als Liste, weil es O(1) Entfernung bietet und enthält. Also:

alphabet = ['a','b','c'...] # list, bad 
alphabet = {'a','b','c'...} # set, good 

Dann wird Ihr Alphabet „Schleife“ wäre:

if guess in alphabet: 
    alphabet.remove(guess) 
2

Es gibt keine Notwendigkeit, eine Schleife über das Alphabet, können Sie überprüfen, ob der Brief noch im Alphabet ist mit:

if guess in alphabet: 
    #And do the function here: 
    alphabet.remove(guess) 

Ihre For-Schleife enthält einen Fehler. Sie entfernen den vermuteten Buchstaben für das Alphabet, aber dann wird Ihre For-Schleife fortgesetzt. Dies führt zu einem Fehler, weil Ihr Alphabet jetzt einen Buchstaben kürzer ist, während der Loop immer noch denkt, dass es die gleiche Größe wie zuvor hat. Deshalb bricht die for-Schleife:

for e in xrange(len(alphabet)): 
    if alphabet[e] == guess: 
     alphabet.remove(guess) 
     break