2012-04-03 4 views
1

약간의 배경 :IndexError를 방지하는 방법

나는 X의, O의와 F로 만든 간단한 미로로 시작하는 작은 단어 기반 미로 게임을 쓰고 있어요

내 미로의 목록입니다 X가 벽인 미로를 나타내는 목록, O는 열린 지점, F는 결승선입니다.

미로의 이름과 사용자의 현재 위치를 취하고 그 위치 (N, S, E 또는 W)에서 모든 법적 이동 목록을 반환하는 함수를 작성하려고합니다.

여기 내 연습 미로와 기능입니다.

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']] 
>>> 

입력 : get_legal_directions(maze1, (1,1))

출력 : ['S']

그래서 함수 I 미로와 상호 작용하는 사용자 위해서는 다른 함수 내의 함수를 사용할 경우에는, 일반적으로 여기서 일 보인다 나는 다음을 얻을

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' 

:

,이 수
>>> interact() 

Maze File: maze1 

You are at position (1, 1) 

Command: L 

" if maze[x-1][y] == 'O' or maze[x-1][y] == 'F': 
IndexError: string index out of range" 

if 문을 작성한 방식에 이상이 있습니까? 아니면 다른 것입니까? 도움을 줄 수있는 사람에게 감사드립니다.

함수를 호출하려면 어떻게해야합니까? get_legal_directions()?

maze = raw_input('Maze File: ') 

함수는리스트의 목록을 대신 기대 :

+0

스택 추적을 생략했습니다. –

답변

3

이 문자열을 미로 있습니다.

+0

이것은 코드를 쳐다 본 질문 중 하나였습니다. 그렇다면 당신은 대답했고 나는 "doh"와 같았습니다. – jdi

1

지금은 문자열을 읽는 중입니다. 그래서

당신이 얻을 :

대신 당신이 아마 기대 하였다
maze = 'maze1' 

: 난 당신이 프롬프트에서 변수의 이름을 입력하고 싶었가로 설정되어 있다고 생각

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

그 변수의 내용.

문자열을 읽었으나 파이썬 코드로 실행되기를 원합니다. 당신은 사용자가 임의의 파이썬 코드를 붙여 수 있기 때문에 eval, 예컨대 :

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

를 사용하는하지만 그건 매우 안전하지 그렇게.

아마 대신 당신이 확인할 수있는 미로 번호를 요청하는 것이 좋습니다 :

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

'input' 또한'eval'처럼 안전하지 않은 것으로 간주됩니다. – jdi

0

나는 당신이하려는 무엇 확실하지 않다.변수 maze1의 이름을 읽은 다음 변수를 통해 색인을 생성하려고합니까? 이것은 확실히 작동하지 않습니다.

가능한 해결책 중 하나는 eval을 사용하는 것입니다. 이미 이해 했으므로 eval은 안전하지 않으며 보안 문제가 발생할 수 있습니다. 또 다른 안전한 방법은 변수로 평가해야하는 입력 문자열을 사전으로 전역 변수를 지정하는 것입니다. 여기

는 제안

maze = raw_input('Maze File: ') 

현재 변경된 코드의 예입니다

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

이것은 답변이 아니라 주석입니다. – jdi

+0

이것은 코드의 문제입니다. OP는 maze1을 문자열로 읽고 변수로 사용하려고합니다. – Abhijit

+0

그러나 이것은 분명한 대답은 아닙니다. 당신은 어떤 예나 참고 문헌도 보여주지 않습니다. 다른 답변은 적어도 라인을 참조하고 일부 세부 사항을 설명합니다. 나는 당신이 무엇을 언급하고 있는지 알아 내기 위해 당신의 대답과 OP 코드 사이를 스캔해서는 안됩니다. – jdi

0

interact()의 첫 번째 줄은 다음과 같습니다

maze = raw_input('Maze File: ') 

당신이했다 테 st run에서 프롬프트에서 "maze1"을 입력했습니다. 따라서 maze"maze1"으로 설정되었습니다.

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

... 등. 테스트 실행에 대한

,이 매개 변수를 maze

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

을 허용하도록 interact()을 변경하고 다음과 같이 인터프리터에서 호출 :

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

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

는 또한 기능 get_legal_directions() 것을 명심 미로의 가장 자리에 위치 할 때마다 색인 오류를 반환합니다. 위치가 (10, 5)이고 미로가 10x10 인 경우를 가정 해보십시오. 두 번째 if 문은 에 액세스하려고 시도하며 목록 범위를 벗어난 maze[11]이됩니다. 또한 함수에 보내는 일부 위치 인수 (position = 0)는 음수 인덱스를 제공합니다. 이렇게해도 오류는 발생하지 않지만 원하는 항목이 아닌 목록의 마지막 항목에 액세스합니다. 어떤 종류의 가장자리 감지를 추가해야합니다. 따라서 get_legal_directions()은 미로 가장자리에있을 때를 알고 그에 따라 작동합니다.

+0

또 하나 더 :이 상황에서 메인 루프에서'else : continue'를 사용할 이유가 없습니다. 다른 모든 elif/else 블록은 자동으로 건너 뜁니다. 만약 ... 엘프 ... 엘프 ... 다른 블럭은 파이썬에서 스위치 블록처럼 행동하지 않습니다/자바. 실행은 다음 블록으로 넘어 가지 않습니다. 계속은 함축되어 있습니다. –

관련 문제