Каково значение инициализации массивов направлений ниже с заданными значениями при разработке шахматной программы?
Я новичок в конкурентном программировании, и я часто заметил, что многие из великих кодеров имеют эти четыре строки в своем коде (особенно в тех, которые связаны с массивами):
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 };
Что это действительно означает и для чего используется техника?
Ответы
Ответ 1
Это метод кодирования всех направлений в виде массивов - каждая пара 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.
Ответ 2
Для тех, кто считает, что объяснение Паташу затруднено, я попытаюсь разъяснить.
Представьте, что вы пытаетесь рассмотреть все возможные шаги из данной точки на шахматной доске.
Если вы перебираете массивы 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
Ответ 3
Небольшой фрагмент кода для проверки количества перемещений во всех направлениях, в котором используются определенные массивы.
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;
}