삽질하는플머

'이런저런잡다구리/Research'에 해당되는 글 1건

  1. 방향 선호 셸 추출

방향 선호 셸 추출

이런저런잡다구리/Research
선공, 또는 먹자 몬스터가 시야 내의 유저나 아이템을 발견할 때 사용한 방법.
2004. 6. 8. 작업노트로 부터 정리 해 둠.




오브젝트가 향하는 방향값은 다음과 같이 정의되어있다.

4 0 5
3 C 1
7 2 6


첫번째 테이블, 즉 거리가 1일 때의 갯수는 8개이며 거리에 비례해 8의 배수로 늘어난다.

1st Table
0, 4, 5, 3, 1, 7, 6, 2
1, 5, 6, 0, 2, 4, 7, 3
2, 6, 7, 1, 3, 5, 4, 0
3, 7, 4, 2, 0, 6, 5, 1
4, 3, 0, 7, 5, 2, 1, 6
5, 0, 1, 4, 6, 3, 2, 7
6, 1, 2, 5, 7, 0, 3, 4
7, 2, 3, 6, 4, 1, 0, 5

2nd Table
0-0, 4-0, 5-0, 4-4, 5-5, 4-3, 5-1, 3-3, 1-1, 7-3, 6-1, 7-7, 6-6, 7-2, 6-2, 2-2
0-0의 의미는 0번 방향에서 다시 0번방향이라는 의미...

이 관계를 테이블로 정리 해 보면 다음과 같다.

4,4,4,4 4,4,4,0 4,4,0,0 4,0,0,0 0,0,0,0 5,0,0,0 5,5,0,0 5,5,5,0 5,5,5,5
(-4,-4) (-3,-4) (-2,-4) (-1,-4) (0,-4) (1,-4) (2,-4) (3,-4) (4,-4)
4,4,4,3 4,4,4 4,4,0 4,0,0 0,0,0 5,0,0 5,5,0 5,5,5 5,5,5,1
(-4,-3) (-3,-3) (-2,-3) (-1,-3) (0,-3) (1,-3) (2,-3) (3,-3) (4,-3)
4,4,3,3 4,4,3 4,4 4,0 0,0 5,0 5,5 5,5,1 5,5,1,1
(-4,-2) (-3,-2) (-2,-2) (-1,-2) (0,-2) (1,-2) (2,-2) (3,-2) (4,-2)
4,3,3,3 4,3,3 4,3 4 0 5 5,1 5,1,1 5,1,1,1
(-4,-1) (-3,-1) (-2,-1) (-1,-1) (0,-1) (1,-1) (2,-1) (3,-1) (4,-1)
3,3,3,3 3,3,3 3,3 3 C 1 1,1 1,1,1 1,1,1,1
(-4,0) (-3,0) (-2,0) (-1,0) (0,0) (1,0) (2,0) (3,0) (4,0)
7,3,3,3 7,3,3 7,3 7 2 6 6,1 6,1,1 6,1,1,1
(-4,1) (-3,1) (-2,1) (-1,1) (0,1) (1,1) (2,1) (3,1) (4,1)
7,7,3,3 7,7,3 7,7 7,2 2,2 6,2 6,6 6,6,1 6,6,1,1
(-4,2) (-3,2) (-2,2) (-1,2) (0,2) (1,2) (2,2) (3,2) (4,2)
7,7,7,3 7,7,7 7,7,2 7,2,2 2,2,2 6,2,2 6,6,2 6,6,6 6,6,6,1
(-4,3) (-3,3) (-2,3) (-1,3) (0,3) (1,3) (2,3) (3,3) (4,3)
7,7,7,7 7,7,7,2 7,7,2,2 7,2,2,2 2,2,2,2 6,2,2,2 6,6,2,2 6,6,6,2 6,6,6,6
(-4,4) (-3,4) (-2,4) (-1,4) (0,4) (1,4) (2,4) (3,4) (4,4)


정리결과 재미난 규칙을 발견함.. 기준좌표를 중심으로 6-2-2-2 위치의 좌표는 6방향 옵셋값인 (1,1)과 2방향 옵셋값인 (0,1)을 그 반복횟수만큼 옵셋시킨 값이 된다. (1,1) + (0,1) + (0,1) + (0,1) = (1,4).

각 방향의 '어깨걸이' 방향을 좌우 순서로 정리하면 다음과 같다.

0 - 4, 5
1 - 5, 6
2 - 6, 7
3 - 7, 4
4 - 3, 0
5 - 0, 1
6 - 1, 2
7 - 2, 3

단계 1의 방향을 추출해 보자.

1의 왼쪽 오른쪽인 5, 6까지 추출... 5번의 왼쪽 0, 6번의 오른쪽 2,
다시 0번의 왼쪽 4, 2번의 오른쪽 7. 마지막으로 4의 왼쪽 3 또는 7의 오른쪽 3.

1, 5, 6, 0, 2, 4, 7, 3

어깨걸이 좌표 테이블로부터 추출이 가능하다는 얘기가 됨.

기준좌표로부터 거리 3인 위치를 6번방향 기준으로 추출할 경우...
먼저 3개의 인자를 갖는 바이트배열 두 개를 준비한다. 각각 오른쪽, 왼쪽값이 된다.
DirArr_R, DirArr_L : TByteArray;

초기값은 두 방향 모두 6-6-6 으로 채운다. DirArr_R[0], [1], [2] := 6;
이 인자들의 값을 해당 루프만큼 바꿔가며 방향을 추출할 수 있다.
총 루프 횟수는 거리값인 3 * 8 / 2 -1 = 11 번이 된다.
(하나의 방향이 모두 치환되는 횟수는 거리값, 즉 이경우 3번이 된다.)

시작방향이 0~3이면 앞부분을 치환, 4~7이면 뒷부분을 치환한다.

RepPos: Integer;

오른쪽을 기준으로 설명 해 보자. 시작방향, 즉 DirArr_R[0] 값이 6이므로 뒷부분 치환.

RefPos:= 0;
RepPos:= 거리 -1;
IncVal := -1; // RepPos를 줄이는 참조값.

또한 6의 오른쪽 방향은 ND2CD_TBL[6][7] => 2 이므로 루프 첫번째 값은 [6-6-2] 이다.
DirArr_R[RepPos] := ND2CD_TBL[ DirArr_R[RefPos] ][7];

RepPos는 하나 줄인다.
Inc(RepPos, IncVal);

RepPos가 0보다 작아지면 RepPos를 0으로, RefPos를 거리-1로, IncVal을 1로 수정.
RepPos가 거리보다 크거나 같아지면 RepPos를 거리-1로 RefPos를 0으로, IncVal을 -1로 수정.

이 과정을 총 루프횟수만큼 반복한 후 마지막 방향은 처음방향의 역방향으로 결정.
또는 왼쪽, 오른쪽 아무쪽이나 이 과정을 한 번 더 진행시켜 결정.

얻어낸 좌표옵셋의 거리제곱이 주어진 (거리+1)의 제곱보다 작은 경우만 범위로 인정.
이렇게 추출한 점열들은 결국 원형이 된다. 이 때 원형 내부에 꽉 차는 축직교 정사각형의 범위는 굳이 거리를 재지  않아도 원 내부이며 따라서 단순 비교문만으로 처리할 수 있다. 주어진 거리에 cos(45) 값을 곱한 후 반올림하면 사각영역의 경계값을 얻게 되며 이 경계안에 포함되는 영역은 거리비교를 하지 않도록 하자.
이 경계값은 스텝에 바로 대응된다. n번째 스탭에서 (n <= 경계값)의 조건을 만족 한다면 거리값을 잴 필요없이 원형 범위 이내가 된다는 이야기..

추출좌표의 총 갯수는 ((추출하려는 거리 * 2) -1)^2 -1 이 된다. 여기서 -1은 원점을 뺐기 때문이다.



지금까지의 정리를 코딩을 통해 확인. (델파이 5)


흰색 점 : 거리를 벗어난 셸
검은 점 : 거리 이내로 판단된 셸
회색 점 : 사각영역이므로 거리판단을 생략하고 무조건 추출한 셸