2014-11-19 2 views
1

나는 매우 기본적이고 단순한 것처럼 보이는 문제를 겪었지만 적절하고 우아한 방법으로 문제를 해결할 방법을 찾지 못했습니다.파이썬 if-elif 명령문 주문

상황은 다음과 같습니다. 움직일 수있는 플레이어가 있습니다. 움직이는 동안 그는 몇 가지 장애물을 만날 수 있습니다 - 나무를 보자. 그리고 그는이 같은 아주 간단한 알고리즘을 사용하여 우회 할 수있다 :

if <the obstacle has a free tile on its RIGHT>: 
    move_right() 
elif <the obstacle has a free tile on its LEFT>: 
    move_left() 
else: 
    stop() 

글쎄, 그것은 완벽하게 작동하지만, 단점이있다 : 장애물이 오른쪽에서와가에서 우회 할 수 있도록 왼쪽 모두 무료 타일이있는 경우 양측 모두 플레이어는 항상 오른쪽에서 우회합니다. 그것은 꽤 설명 할 만하지만 여전히 그렇게 멋지지 않습니다.

아이디어는 약간의 다양성을 추가하고 플레이어가 타일의 가용성을 확인하는 순서를 무작위로 지정하므로 두 가지 모두 자유롭게 할 수 있으면 반드시 오른쪽이 아니라 임의의 방향으로 이동할 수 있습니다. 그리고 나는 간단하고 아름다운 방법으로 그것을하는 방법을 생각해 낼 수 없다는 것을 인정해야합니다.

기본적으로,이 솔루션은 아마 ...

if random(0, 1) == 0: 
    if <the obstacle has a free tile on its RIGHT>: 
    move_right() 
    elif <the obstacle has a free tile on its LEFT>: 
    move_left() 
    else: 
    stop() 
else: 
    if <the obstacle has a free tile on its LEFT>: 
    move_left() 
    elif <the obstacle has a free tile on its RIGHT>: 
    move_right() 
    else: 
    stop() 

을 이런 식으로 뭔가해야하지만 나는 그것이 가장 좋은 일을하지 않는 것 같습니다 이유를 설명 할 필요가 없습니다 같아요. =/

답변

5
그런 다음, 목록에서 가능한 모든 방향을 넣어 그에 random.choice()을 사용할 수 있습니다

:

directions = [] 
if <the obstacle has a free tile on its RIGHT>: 
    directions.append(move_right) 
if <the obstacle has a free tile on its LEFT>: 
    directions.append(move_left) 

if not directions: 
    stop() 
else: 
    random.choice(directions)() # pick an available direction at random 

길 찾기 목록이 다음에 중 0, 1 또는 2 함수 참조가됩니다; 비어있는 경우 아무 옵션도없고 stop()으로 전화를 거십시오. 그렇지 않으면 무작위로 목록에서 선택하고 선택한 함수를 호출합니다. 입력 목록이 비어있는 경우 random.choice()IndexError을 제기하기 때문에

, 당신은 너무 TOF 사용을 만들 수 :

try: 
    # pick an available direction at random 
    random.choice(directions)() 
except IndexError: 
    # no directions available 
    stop() 
+0

확인을 보인다. 그러나 문제를 조금 더 복잡하게 만들면 어떨까요? 'move_right()'와'move_left()'와 같은 메소드는 없지만'self.X + = step' 나'self.X - = step'과 같은 단순한 연산이 있습니다. – Romitas

+0

@Romitas :'lambda' 함수를 대신 추가 할 수 있습니다; 예 : 익명 함수로 표현식을 래핑합니다 :'(.attattr (self, 'X', self.X + self.step)) # move right'' ('setattr 'lambda') 아니면 그냥 어쨌든 움직임을위한 메서드 나 로컬, 중첩 된 함수를 만들면됩니다. –