2012-04-03 4 views
1

Ein wenig Hintergrund:Wie Indexerror vermeiden

Ich bin ein kleines Wort basierte Labyrinth-Spiel mit einem einfachen Labyrinth von X, O und F.

Mein Labyrinth gemacht Start Schreiben ist eine Liste Listen, die das Labyrinth selbst darstellen, wobei X eine Wand ist, O ist ein offener Punkt und F ist die Ziellinie.

Ich versuche, eine Funktion zu schreiben, die den Namen des Irrgartens und der aktuellen Position des Benutzers nimmt und eine Liste aller legalen Bewegungen von dieser Position (N, S, E oder W) zurückgibt.

Hier ist meine Praxis Labyrinth und Funktion.

def get_legal_directions(maze, position): 
    x = position[0] 
    y = position[1] 
    legal = [] 
    if maze[x-1][y] == 'O' or maze[x-1][y] == 'F': 
     legal.append('N') 
    if maze[x+1][y] == 'O' or maze[x+1][y] == 'F': 
     legal.append('S') 
    if maze[x][y+1] == 'O' or maze[x][y+1] == 'F': 
     legal.append('E') 
    if maze[x][y-1] == 'O' or maze[x][y-1] == 'F': 
     legal.append('W') 
    return legal 


>>> maze1 = [['X', 'X', 'X', 'X', 'X'], ['X', 'O', 'X', 'F', 'X'], ['X', 'O', 'X', 'O', 'X'], ['X', 'O', 'O', 'O', 'X'], ['X', 'X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X']] 
>>> 

Eingang: get_legal_directions(maze1, (1,1))

Ausgang: ['S']

so erscheint die Funktion normal, hier zu arbeiten, aber wenn ich die Funktion innerhalb einer anderen Funktion, damit der Benutzer mit dem Labyrinth zu interagieren , bekomme ich diese:

def interact(): 
    maze = raw_input('Maze File: ') 
    x = maze[0] 
    y = maze[1] 
    pos = (1,1) 
    history = [pos] 
    while 1: 
     print 'You are at position', pos 
     command = raw_input('Command: ') 
     if command == 'Q': 
      com = raw_input('Are you sure you want to quit? [y] or [n]: ') 
      if com =='y': 
       print 'Thank you for playing - Goodbye!' 
       break 
      else: continue 
     elif command == 'L': 
      get_legal_directions(maze, pos) 
     else: print 'invalid command' 

ich folgendes erhalten:

Ist etwas falsch mit der Art, wie ich die if-Anweisung geschrieben habe, oder ist es etwas anderes? Danke an alle, die helfen können. Wie kann ich den Befehl L erhalten, um die Funktion get_legal_directions() aufzurufen?

+0

Sie haben den Stack-Trace weggelassen. –

Antwort

3

Dies macht einen String Labyrinth:

maze = raw_input('Maze File: ') 

Ihre Funktion anstatt eine Liste von Listen erwartet.

+0

Das war eine dieser Fragen, bei denen ich den Code anstarrte, dann antworteten Sie und ich war wie "Doh". – jdi

1

Im Moment lesen Sie eine Zeichenfolge.

So erhalten Sie:

maze = 'maze1' 

statt, was Sie wahrscheinlich erwartet haben:

maze = maze1 = [['X', 'X', 'X', 'X', 'X']... 

Ich glaube, Sie den Namen einer Variablen an der Eingabeaufforderung eingeben wollte, und haben sie verwandelte sich in die Inhalt dieser Variablen.

Sie lesen also eine Zeichenfolge, aber Sie möchten, dass sie als Python-Code ausgeführt wird. Sie tun das, indem eval, z.B .:

maze = eval(raw_input('Maze File: ')) 

aber das ist nicht sehr sicher, weil Ihre Benutzer es eine Python-Code einfügen könnte.

Vielleicht stattdessen ist es besser, für ein Labyrinth Nummer zu fragen, die Sie bestätigen können:

mazes = [] 
mazes.append([['X', 'X', 'X', 'X', 'X'], ['X', 'O', 'X', 'F', 'X'], ['X', 'O', 'X', 'O', 'X'], ['X', 'O', 'O', 'O', 'X'], ['X', 'X', 'X', 'X', 'X'], ['X', 'X', 'X', 'X', 'X']]) 

maze_number = raw_input('Maze Number: ') 
maze = mazes[int(maze_number)] 
+0

'Eingabe' wird auch als unsicher angesehen, da es eine' eval' – jdi

0

Ich bin nicht sicher, was Sie zu tun beabsichtigen.Sie lesen den Namen der Variablen maze1 und versuchen dann, sie über die Variable zu indizieren? Dies wird definitiv nicht funktionieren.

Eine mögliche Lösung ist die Verwendung eval, wie andere darauf hingewiesen haben. Wie Sie bereits verstanden haben, ist eval nicht sicher und hat mögliche Sicherheitsbedenken. Ein weiterer sicherer Weg besteht darin, die Globals als Wörterbuch mit der eingegebenen Zeichenfolge zu adressieren, die als Variable ausgewertet werden sollte. Hier

ist ein Beispiel für den geänderten Code

Aktuelle

maze = raw_input('Maze File: ') 

Vorgeschlagen

max_try=3 
while True: 
    try: 
     maze = globals()[raw_input('Maze File: ')] 
     break 
    except KeyError: 
     print "Wrong Input" 
     max_try-=1 
     if not max_try: 
      print "Time Out" 
      return 
+0

Dies ist ein Kommentar, keine Antwort. – jdi

+0

Dies ist das Problem im Code. OP liest maze1 als String und beabsichtigt, es als Variable zu verwenden. – Abhijit

+0

Dies ist jedoch keine klare Antwort. Sie zeigen keine Beispiele oder Referenzen. Die anderen Antworten beziehen sich zumindest auf eine Zeile und erklären einige Details. Ich sollte nicht zwischen Ihrer Antwort und dem OP-Code suchen müssen, um herauszufinden, worauf Sie sich gerade beziehen. – jdi

0

Die erste Zeile der interact() ist:

maze = raw_input('Maze File: ') 

Wenn Sie ein tat te st run, du hast "maze1" an der Eingabeaufforderung eingegeben. Daher ist maze jetzt auf "maze1" eingestellt.

x = maze[0] #x is set to 'm' 
y = maze[1] #y is set to 'a' 

und so weiter und so weiter.

Für Ihren Testlauf ändern interact() so, dass sie den Parameter maze

def interact(mazeData): 
    maze = mazeData[:] 
    ... 
    ... 

akzeptiert und es dann aus dem Dolmetscher rufen wie so:

>>> maze1 = [['X', 'X' ... ... ]] 

>>> interact(maze1) 
... 
... 

im Auge behalten, auch, dass die Funktion get_legal_directions() gibt einen Indexfehler zurück, wenn Sie eine Position am entfernten Ende eines Labyrinths verwenden. Angenommen, Sie geben (10, 5) als Position und Ihr Labyrinth ist 10x10. Die zweite if-Anweisung versucht, auf zuzugreifen, was maze[11] ist, was außerhalb des Listenbereichs liegt. Außerdem geben einige Positionsargumente (Position = 0), die Sie an die Funktion senden, einen negativen Index an. Dies wird keinen Fehler erzeugen, aber es wird auf das letzte Element in der Liste zugreifen, was auch nicht das ist, was Sie wollen. Sie müssen eine Art Kantenerkennung hinzufügen, so dass get_legal_directions() weiß, wann es sich am Rande des Labyrinths befindet und entsprechend handeln wird.

+0

Noch eine Sache: Es gibt keinen Grund, in dieser Situation 'else: continue' in der Hauptschleife zu verwenden. Alle anderen Elif/Else-Blöcke werden automatisch übersprungen. Wenn ... elif ... elif ... andere Blöcke in Python nicht wie Switch-Blöcke in c/java funktionieren. Die Ausführung wird nicht zum nächsten Block "durchfallen". Die Fortsetzung ist impliziert. –

Verwandte Themen