Какое значение имеет инициализация массивов направлений ниже заданными значениями при разработке шахматной программы?

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 };

Что это на самом деле означает и для чего используется техника?

Ejjyrex
источник
5
Я часто использую d={0,1,0,-1,0}для этого: пары предметов d[i], d[i+1]дают мне четыре основных направления.
dasblinkenlight 03
14
Это на удивление хороший вопрос. ... Можно что-нибудь сделать с названием?
luser droog
7
Вы не подумали упомянуть, что этот код взят из шахматного движка? Также вы не думали сами посмотреть, как эти значения использовались?
trojanfoe
15
«у многих великих программистов есть эти четыре строчки [...]» - я придираюсь к этому вопросу, но если бы они были великими кодировщиками, их код не заставил бы вас задаться вопросом: «Что за конструкция ?!»
утнапистим 03
6
@utnapistim Когда вы пишете подавляющее большинство кода, вы правы, но здесь вы упускаете суть. Этот случай является законным исключением из этого правила. Если вы пишете код для соревнований и в условиях ограниченного времени, быстрое и грязное почти всегда лучше, чем чистое и поддерживаемое. В этом случае читаемым для вас, теперь на самом деле это все , что имеет значение. Хороший программист очень хорошо пишет в этом контексте непослушный, нечитаемый беспорядок , даже если большая часть их обычного кода хорошо читается и обслуживается.
Бен Ли

Ответы:

84

Это метод кодирования всех направлений в виде массивов - каждой пары di[i],dj[i] представляет собой другое направление.

Если мы представим, что у нас есть кусок в точке x, y, и мы хотим добавить к его x и значение y, чтобы переместить его в соседнее место, 1,0 - восток, -1,0 - запад, 0,1 юг, 0, -1 север и так далее.

(Здесь я сказал, что верхний левый угол равен 0,0, а нижний правый угол равен 4,4, и показано, какое перемещение будет совершать каждый индекс массивов из центральной точки X на уровне 2,2.)

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

Как он настроен, если вы выполняете ^1( ^выполняя побитовое XOR) с индексом, вы получаете противоположное направление - 0 и 1 - противоположности, 2 и 3 - противоположности и так далее. (Другой способ настроить его - повернуть по часовой стрелке, начиная с севера, затем^4 получить противоположное направление.)

Теперь вы можете проверить все направления из заданной точки, перебрав ваши diиdj массивы , вместо того, чтобы записывать каждое направление в отдельной строке (всего восемь!) (Только не забудьте выполнить проверку границ :))

diKи djKформируют все направления рыцарей вместо всех смежных направлений. Здесь ^1перевернется по одной оси, ^4даст противоположный прыжок коня.

.7.6.
0...5
..K..
1...4
.2.3.
Паташу
источник
3
что такое «направления рыцарей»?
Дэвид
4
Ох уж этот рыцарь.
Дэвид
1
Большое спасибо за ваш ответ ... Не могли бы вы связать меня или, возможно, показать мне какой-нибудь код, чтобы лучше проиллюстрировать это ... (Я немного новичок ... если вы могли понять :)
Еще
1
Я приветствую попытку Паташу дать ответ. Хотя кажется, что многие поняли его объяснение, я не смог его понять. Если кто-нибудь может дополнить уже сказанное, буду очень признателен.
deepak
1
@deepak Представьте, что позиция представлена x,yкортежем в 2D-пространстве. Для каждой пары di[i], dj[i]добавьте его, x,yи вы будете x,yтранспонированы в каждом направлении один за другим. Имеет ли это смысл?
Паташу
64

Для тех, кто считает объяснение Паташу трудным для понимания, я попытаюсь уточнить.

Представьте, что вы пытаетесь рассмотреть все возможные ходы из данной точки на шахматной доске.

Если вы в цикле перебираете массивы di и dj, интерпретируя значения di как смещения по x, а значения dj как смещения по y, вы охватываете каждое из 8 возможных направлений.

Предполагая, что положительный x - восток, а положительный 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 можно интерпретировать одинаково для определения возможных ходов коня. Если вы не знакомы с шахматами, конь движется по 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;
}
Дариуш
источник