체스 프로그램을 개발할 때 주어진 값으로 아래 방향 배열을 초기화하는 것의 중요성은 무엇입니까?


106

저는 경쟁 프로그래밍을 처음 접했고, 많은 훌륭한 코더들이 코드에 다음 네 줄을 가지고 있다는 것을 자주 발견했습니다 (특히 배열과 관련된 코드에서).

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int diK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int djK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };

이것이 실제로 의미하는 것은 무엇이며 기술은 무엇을 위해 사용됩니까?


5
나는 이것을 자주 사용 d={0,1,0,-1,0}합니다 : 아이템 쌍은 d[i], d[i+1]네 가지 기본 방향을 제공합니다.
dasblinkenlight 2013 년

14
이것은 놀랍도록 좋은 질문입니다. ... 제목에 대해 할 수있는 일이 있습니까?
luser droog 2013 년

7
그렇다면이 코드가 체스 엔진에서 나온 것이라고는 생각하지 않으셨습니까? 또한 당신은 생각하지 않았다 보면 이 값을 사용하고 얼마나 자신을?
trojanfoe 2013 년

15
"대부분의 훌륭한 코더들은이 네 줄을 가지고 있습니다. [...]"-저는 여기서 짤막한 것입니다.하지만 그들이 훌륭한 코더라면, 그들의 코드는 "wtf가 그 구조입니까?!"
utnapistim 2013 년

6
@utnapistim 대부분의 코드를 작성할 때 맞습니다.하지만 여기서 요점을 놓치고 있습니다. 이 경우는 해당 규칙에 대한 합법적 인 예외입니다. 경쟁을위한 코드를 작성하고 시간 제약이있는 경우, 빠르고 더러운 것이 거의 항상 깨끗하고 유지 가능한 것보다 낫습니다. 이 경우에 당신에게 읽기, 이제 정말 입니다 모든 문제. 훌륭한 코더는 대부분의 일반 코드가 읽기 쉽고 유지 관리가 가능 하더라도이 컨텍스트에서 유지 관리 할 수없는 읽을 수없는 혼란 잘 작성합니다 .
Ben Lee

답변:


84

이것은 모든 방향을 배열로 인코딩하는 기술입니다. 모든 쌍은 di[i],dj[i]다른 방향입니다.

x, y 위치에 조각이 있다고 상상하고 x와 y 값에 더하여 가까운 위치로 이동하려면 1,0은 동쪽, -1,0은 서쪽, 0,1 남쪽, 0, -1은 북쪽입니다.

(여기에서는 왼쪽 상단이 0,0이고 오른쪽 하단이 4,4라고 말했으며 배열의 각 인덱스가 2,2의 중심점 X에서 이동하는 것을 보여주었습니다.)

.....
.536.
.1X0.
.724.
.....

방법은 그것은 당신이 할 경우, 설정 ^1( ^인덱스에있는 비트 XOR)을 당신은 반대 방향을 얻을 - 0과 1은 2, 3 쪽 등이다, 반대이다. (설정하는 또 다른 방법은 북쪽에서 시작하여 시계 방향으로 이동 한 다음 ^4반대 방향으로 이동하는 것입니다.)

이제 각 방향을 자체 라인 (총 8 개)에 쓸 필요없이, didj배열 을 반복하여 주어진 지점에서 모든 방향을 테스트 할 수 있습니다 (경계 확인을 잊지 마세요 :))

diKdjK모든 형태 의 기사 방향 이 아닌 모든 방향에 인접한다. 여기에서 ^1한 축을 따라 뒤집고 ^4반대쪽 기사가 도약합니다.

.7.6.
0...5
..K..
1...4
.2.3.

3
'나이츠 디렉션'은 무엇입니까?
David

4
오, 그런 기사.
David

1
답변 해주셔서 감사합니다 .. 저를 연결해 주시거나 더 잘 설명 할 수있는 코드를 보여 주시겠습니까?. (나는 조금 초보자입니다 .. 이해할 수 있다면 :) 다시 감사합니다
ejjyrex

1
나는 대답에 대한 Patashu의 시도에 박수를 보냅니다. 많은 사람들이 그의 설명을 이해 한 것 같지만 나는 그것을 잘 이해하지 못했습니다. 이미 말씀하신 내용을 추가 해주시면 감사하겠습니다.
deepak 2013 년

1
@deepak x,y2D 공간에서 위치가 튜플에 의해 표현된다고 상상해보십시오 . 각 쌍을 위해 di[i], dj[i]추가 그것은하는 x,y당신은거야 x,y하나에 의해 각 방향의 하나에 전치. 말이 돼?
Patashu 2013 년

64

Patashu의 설명을 따르기가 어렵다고 생각하는 사람들을 위해 명확히하려고 노력할 것입니다.

체스 판의 주어진 지점에서 가능한 모든 움직임을 고려하려고한다고 상상해보십시오.

di 및 dj 배열을 반복하여 di 값을 x 오프셋으로 해석하고 dj 값을 y 오프셋으로 해석하면 가능한 8 개 방향 각각을 다룹니다.

양수 x가 동쪽이고 양수 y가 남쪽이라고 가정하면 (Patashu의 답변에서와 같이) 다음과 같이 표시됩니다.

  | di / x | dj / y | 방향
-+ ------ + ------ + -----------
0 | 1 | 0 | 동쪽
1 | -1 | 0 | 서쪽
2 | 0 | 1 | 남쪽
3 | 0 | -1 | 북쪽
4 | 1 | 1 | 남동
5 | -1 | -1 | 북서
6 | 1 | -1 | 북동
7 | -1 | 1 | 남서부

diK 및 djK 배열은 Knight 조각에 대해 가능한 이동을 설정하는 동일한 방식으로 해석 될 수 있습니다. 체스에 익숙하지 않은 경우 기사는 L 패턴으로 이동합니다. 한 방향으로 두 개의 사각형을 이동 한 다음 그에 대해 직각으로 하나의 사각형을 이동합니다 (또는 그 반대).

  | diK / x | djK / y | 방향
-+ ------- + ------- + ----------------
0 | -2 | -1 | 서쪽 2 개, 북쪽 1 개
1 | -2 | 1 | 서쪽 2 개, 남쪽 1 개
2 | -1 | 2 | 서쪽 1 개, 남쪽 2 개
3 | 1 | 2 | 동쪽 1 개, 남쪽 2 개
4 | 2 | 1 | 동쪽 2 개, 남쪽 1 개
5 | 2 | -1 | 동쪽 2 개, 북쪽 1 개
6 | 1 | -2 | 동쪽 1 개, 북쪽 2 개
7 | -1 | -2 | 서쪽 1 개, 북쪽 2 개

1

정의 된 배열을 사용하여 모든 방향에서 가능한 이동량을 확인하는 작은 코드 스 니펫.

int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int movesPossible[8];
int move = 0;
int posx, posy; // position of the figure we are checking

for (int d=0; d<8; d++) {
  for (move = 1; board.getElt(posx+di[d]*move, posy+dj[d]*move)==EMPTY; move++) ;
  movesPossible[d] = move-1;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.