2010-01-13 4 views
1

나는 (3x3) 정사각형으로 처리해야하는 배열 (9 개 요소, 말)이 있습니다. 질문을 단순화하기 위해 이것은 1 기반 배열입니다 (즉, 인덱싱은 0 대신 1에서 시작합니다).배열로 저장된 정사각형의 유효 인접 셀 결정

제 목표는 시작점을 기준으로 유효한 인접한 정사각형을 결정하는 것입니다.

가 메모리에 저장 어떻게 즉

것은 : 1 2 3 4 5 6 7 8 9

것은 나는 그것을 치료 해요 방법 :
7 8 9
4 5 6
1 2 3

내가 이미 이동하는 방법을 알고 아래로 테스트 (1> = current_index < = 9)

편집 : 나는 위의 테스트가 지나치게 일반적이라는 것을 알고 있지만 간단하고 작동합니다.

//row_size = 3, row_step is -1, 0 or 1 depending on if we're going left, 
//staying put or going right respectively. 
current_index += (row_size * row_step); 

왼쪽 또는 오른쪽으로 이동할 때 범위 초과 조건을 테스트하려면 어떻게해야합니까? 개념적으로는 3이 (예를 들어) 4와 동일한 행에 있는지 (또는 다른 정사각형이 동일한 배열에 연속적으로있는 경우 대체 패턴으로 9와 동일한 정사각형 내에 10이 있는지 여부) , 그러나 나는 그것을 결정하는 방법을 이해할 수 없다. 나는 어딘가에 모듈러스가 있다고 상상한다. 그러나 어디에서?

덕분 대단히
제프

는 부록 : 여기
0부터 배열 용도 변경 결과 코드가있어 인접 안내 (I 프로젝트 내의 오프셋 코드 존재를 정리) 사각형.

bool IsSameSquare(int index0, int index1, int square_size) { 
    //Assert for square_size != 0 here 
    return (!((index0 < 0) || (index1 < 0)) 
     && ((index0 < square_size) && (index1 < square_size))) 
     && (index0/square_size == index1/square_size); 
} 
bool IsSameRow(int index0, int index1, int row_size) { 
    //Assert for row_size != 0 here 
    return IsSameSquare(index0, index1, row_size * row_size) 
    && (index0/row_size == index1/row_size); 
} 
bool IsSameColumn(int index0, int index1, int row_size) { 
    //Assert for row_size != 0 here 
    return IsSameSquare(index0, index1, row_size * row_size) 
     && (index0 % row_size == index1 % row_size); 
} 

//for all possible adjacent positions 
for (int row_step = -1; row_step < 2; ++row_step) { 
    //move up, down or stay put. 
    int row_adjusted_position = original_position + (row_size * row_step); 
    if (!IsSameSquare(original_position, row_adjusted_position, square_size)) { 
    continue; 
    } 
    for (int column_step = -1; column_step < 2; ++column_step) { 
    if ((row_step == 0) & (column_step == 0)) { continue; } 
    //hold on to the position that has had its' row position adjusted. 
    int new_position = row_adjusted_position; 

    if (column_step != 0) { 
     //move left or right 
     int column_adjusted_position = new_position + column_step; 
     //if we've gone out of bounds again for the column. 
     if (IsSameRow(column_adjusted_position, new_position, row_size)) { 
     new_position = column_adjusted_position; 
     } else { 
     continue;       
     } 
    } //if (column_step != 0) 
    //if we get here we know it's safe, do something with new_position 
    //... 
    } //for each column_step 
} //for each row_step 

답변

3

0 기반 인덱싱을 사용하면이 방법이 더 쉽습니다. 귀하의 모든 인덱스에서 1을 뺄 경우 이러한 규칙이 작동 :

  • 두 인덱스는 같은 광장에있는 경우 (A/9) == (B/9)와> = 0와 ​​b> = 0
  • 두 개의 인덱스는 같은 사각형에 있고 (a/3) == (b/3)이면 같은 행에 있습니다.
  • 두 개의 인덱스가 같은 칸에 있고 (a % 3) == (b % 3) 인 경우 두 개의 인덱스가 같은 열에 있습니다.
+0

단순화로 1 기반 배열을 사용하고 있었지만 실제로는 0부터 시작하는 배열입니다. 셀 0은 사각형 셀 보행에서 제외되는 별도의 소스 노드를 나타냅니다. 답장을 보내 주셔서 감사 드리며, 제가 이것을 어떻게 할 수 있는지 보여 드리겠습니다. :) – Geoff

+0

난 그냥 정수 나누기에 의존 문제를 지적하고 싶습니다. 그리고 펀치에 나를 때리는 당신을 찰싹 때려! – cmaynard

+0

흠. 정수 나누기를 피할 수있는 방법이 있습니까? kramthegram의 포인트는 테스트 할 때까지 나에게 일어나지 않았다. 분명히 -1/3과 0/3은 어떻게 든 동일합니다 (나는 왜 그런지, 그들은 단지 나에게 발생하지 않았 음을 안다.). – Geoff

-1

이 경우 다차원 배열을 사용해야합니다.

배열 클래스가 다차원 요소를 지원하지 않으면 빠른 래퍼를 작성해야합니다.

+0

같은 하나의 규칙을 할 수있는 것은 옵션이 아닙니다, 그러나 당신의 답장을 보내 주셔서 감사합니다 그럼에도 불구하고. – Geoff

+0

왜 옵션이 아닌가요? 라이트 웨이트 래퍼를 작성하고 액세스해야하는 항목이 있으면 기본 선형 배열에 계속 액세스 할 수 있습니다. –

+0

어레이 주위를 움직이거나 이웃을 확인하면서 성능을 보신다면 2D는 옵션이 아닙니다. 그리드 [pos + offset]를 보면 그리드 [pos_x + offset_x] [pos_y + offset_y]보다 훨씬 빠릅니다. – phkahler

0

몇 가지 방법이 있습니다. 나는 재미로 이상한 것을 고르고 있습니다. 모듈러스를 사용하십시오.

행의 크기가 3 인 경우 모듈의 수는 3이고 두 개의 간단한 규칙이 사용됩니다.

If currPos mod 3 = 0 and (currPos+move) mod 3 = 1 then invalid 
If currPos mod 3 = 1 and (currPos+move) mod 3 = 0 then invalid 

새 행을 두 점프에 대해이 검사가, 당신은 또한 다차원 배열을 사용하여이

if (currPos mod 3)-((currPos+move) mod 3)> 1 then invalid 

건배