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

Я новичок в соревновательном программировании, и я часто замечал, что многие великие программисты имеют в своем коде эти четыре строки (особенно те, которые связаны с массивами):

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

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


person ejjyrex    schedule 03.05.2013    source источник
comment
Я часто использую для этого d={0,1,0,-1,0}: пары элементов для d[i], d[i+1] дают мне четыре стороны света.   -  person Sergey Kalinichenko    schedule 03.05.2013
comment
Это удивительно хороший вопрос. ... Можно ли что-то сделать с заголовком?   -  person luser droog    schedule 03.05.2013
comment
Я немного поработал над заголовком/подписью, но было бы лучше, если бы для этой группы массивов было какое-то имя. Есть?   -  person Rüppell's Vulture    schedule 03.05.2013
comment
@Rüppell'sVulture: отлично!!   -  person ejjyrex    schedule 03.05.2013
comment
@Rüppell'sVulture Да! Так-то лучше.   -  person luser droog    schedule 03.05.2013
comment
Так вы не подумали упомянуть, что этот код исходит от шахматного движка? Также вы не подумали посмотреть сами, как используются эти значения?   -  person trojanfoe    schedule 03.05.2013
comment
@trojanfoe Имейте в виду, что люди, которые пишут программы для соревновательного программирования, не думают о ремонтопригодности, удобочитаемости или ясности - им просто нужно написать это быстро, сделать его эффективным, а затем никогда больше не читать его :)   -  person Patashu    schedule 03.05.2013
comment
Если каждый имеет его в своей программе, его вряд ли нужно документировать или комментировать, точно так же, как мы не документируем, почему мы выбрали букву i для манекена цикла.   -  person Kaz    schedule 03.05.2013
comment
у многих великих кодеров есть эти четыре строки [...] - я здесь придираюсь, но если бы они были великими кодерами, их код не заставил бы вас задуматься, что это за конструкция?!   -  person utnapistim    schedule 03.05.2013
comment
@utnapistim Я не согласен. Я не думаю, что этот код действительно должен быть читабельным, это их решение. Его можно прочитать для них, это все, что имеет значение.   -  person max    schedule 08.05.2013
comment
@Max (Почти) весь код читается людьми, которые его написали, но со временем это исчезает. Лучший код не только идеально читается при создании, но и остается идеально читаемым даже через десять или более лет после того, как вы его написали. Даже парадигмы, которые вы обычно используете сейчас (то, что естественно и очевидно для вас при написании кода — например, ваши соглашения по кодированию), через несколько лет станут странным унаследованным кодом (не потому, что код меняется, а потому, что меняются лучшие практики). Чем меньше мысленных прыжков вам придется делать при чтении кода (например, задаваться вопросом, что это такое?), тем лучше.   -  person utnapistim    schedule 08.05.2013
comment
@utnapistim Когда вы пишете подавляющее большинство кода, вы правы, но здесь вы упускаете суть. Этот случай является законным исключением из этого правила. Если вы пишете код для конкурса и в условиях ограниченного времени, то «быстро-и-грязно» почти всегда лучше, чем «чисто-и-обслуживаемо». В этом случае читается для вас, теперь действительно это все, что имеет значение. Хороший кодер очень хорошо пишет неразборчивую и нечитаемую мешанину в этом контексте, даже если большая часть их обычного кода легко читается и удобна в сопровождении.   -  person Ben Lee    schedule 08.05.2013
comment
@BenLee - вы правы: я упустил этот момент :).   -  person utnapistim    schedule 08.05.2013


Ответы (3)


Это метод кодирования всех направлений в виде массивов — каждая пара 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.
person Patashu    schedule 03.05.2013
comment
что такое "рыцарские направления"? - person David; 03.05.2013
comment
Большое спасибо за ваш ответ .. Не могли бы вы связать меня или, возможно, показать мне какой-нибудь код, чтобы лучше проиллюстрировать это .. (я немного новичок .. если вы могли понять :) Еще раз спасибо - person ejjyrex; 03.05.2013
comment
Я приветствую попытку Паташу дать ответ. Хотя кажется, что многие поняли его объяснение, мне не удалось его понять. Если кто-то может добавить к уже сказанному, буду очень признателен. - person deepak; 03.05.2013
comment
@deepak Представьте, что позиция представлена ​​кортежем x,y в 2D-пространстве. Для каждой пары di[i], dj[i] добавьте ее к x,y, и вы получите x,y, транспонированные в каждом направлении одно за другим. Имеет ли это смысл? - person Patashu; 03.05.2013
comment
@Patashu Да, я думаю, теперь я понял. Меня больше всего смущали фигуры, которые вы нарисовали, и то, как вы их получили. Я наконец понял эти цифры. - person deepak; 03.05.2013

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

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

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

Предполагая, что положительный x - это восток, а положительный y - юг (как в ответе Паташу), вы получаете следующее:

  | di/x | dj/y | Direction
--+------+------+-----------
0 |   1  |   0  | east
1 |  -1  |   0  | west
2 |   0  |   1  | south 
3 |   0  |  -1  | north
4 |   1  |   1  | south-east
5 |  -1  |  -1  | north-west
6 |   1  |  -1  | north-east
7 |  -1  |   1  | south-west

Массивы diK и djK можно интерпретировать таким же образом, чтобы установить возможные ходы для фигуры коня. Если вы не знакомы с шахматами, конь ходит по схеме L — две клетки в одном направлении, а затем одна клетка под прямым углом к ​​этому (или наоборот).

  | diK/x | djK/y | Direction
--+-------+-------+----------------
0 |  -2   |  -1   | 2 west, 1 north
1 |  -2   |   1   | 2 west, 1 south
2 |  -1   |   2   | 1 west, 2 south
3 |   1   |   2   | 1 east, 2 south
4 |   2   |   1   | 2 east, 1 south
5 |   2   |  -1   | 2 east, 1 north
6 |   1   |  -2   | 1 east, 2 north
7 |  -1   |  -2   | 1 west, 2 north
person James Holderness    schedule 03.05.2013

Небольшой фрагмент кода для проверки количества возможных перемещений во всех направлениях, в котором используются определенные массивы.

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;
}
person Dariusz    schedule 29.05.2013