Qual é a importância de inicializar matrizes de direção abaixo com valores dados ao desenvolver o programa de xadrez?

106

Eu sou novo na programação competitiva e notei frequentemente que muitos dos grandes programadores têm essas quatro linhas em seus códigos (especialmente naqueles que envolvem matrizes):

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

O que isso realmente significa e para que é usada a técnica?

ejjyrex
fonte
5
Costumo usar d={0,1,0,-1,0}para isso: pares de itens para d[i], d[i+1]me dar quatro direções cardeais.
dasblinkenlight
14
Esta é uma pergunta surpreendentemente boa. ... Algo pode ser feito sobre o título?
luser droog
7
Então você não pensou em mencionar que esse código vem de um mecanismo de xadrez? Também não pensou em observar como esses valores estavam sendo usados?
trojanfoe
15
"muitos dos grandes programadores têm essas quatro linhas [...]" - estou criticando aqui, mas se eles fossem grandes programadores, seu código não faria você se perguntar "qual é essa construção ?!"
utnapistim
6
@utnapistim Ao escrever a grande maioria do código, você está certo, mas aqui, você está perdendo o ponto. Este caso é uma exceção legítima a essa regra. Se você está escrevendo um código para uma competição e sob uma restrição de tempo, rápido e sujo é quase sempre melhor do que limpar e manter. Neste caso legível para você, agora realmente é tudo o que importa. Um grande programador escreve muito bem uma bagunça ilegível que não pode ser mantida neste contexto , mesmo que a maior parte de seu código regular seja altamente legível e de fácil manutenção.
Ben Lee

Respostas:

84

Esta é uma técnica para codificar todas as direções como matrizes - cada par de di[i],dj[i]está em uma direção diferente.

Se imaginarmos que temos uma peça em um local x, y, e quisermos somar seus valores x e y para movê-la para um local próximo, 1,0 é leste, -1,0 é oeste, 0,1 é sul, 0, -1 é norte e assim por diante.

(Aqui, eu disse que o canto superior esquerdo é 0,0 e o canto inferior direito 4,4 e mostrei qual movimento cada índice das matrizes fará a partir do ponto central, X, em 2,2.)

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

Da forma como está configurado, se você fizer ^1( ^sendo XOR bit a bit) no índice, obterá a direção oposta - 0 e 1 são opostos, 2 e 3 são opostos e assim por diante. (Outra forma de configurá-lo é ir no sentido horário, começando no norte - então, ^4leva você na direção oposta.)

Agora você pode testar todas as direções a partir de um determinado ponto fazendo um loop sobre seus arrays die dj, em vez de precisar escrever cada direção em sua própria linha (para oito no total!) (Só não se esqueça de verificar os limites :))

diKe djKformar todas as direções dos cavaleiros em vez de todas as direções adjacentes. Aqui, ^1vai virar ao longo de um eixo, ^4vai dar o salto do cavalo oposto.

.7.6.
0...5
..K..
1...4
.2.3.
Patashu
fonte
3
o que são 'direções dos cavaleiros'?
David
4
Oh, esse tipo de cavaleiro.
David
1
Muito obrigado pela sua resposta .. Você poderia me vincular ou talvez me mostrar algum código para ilustrá-lo melhor .. (Eu sou um pouco novato .. se você pudesse entender :) Obrigado novamente
ejjyrex
1
Aplaudo a tentativa de Patashu de uma resposta. Embora pareça que muitos entenderam sua explicação, não fui capaz de entendê-la bem. Se alguém puder acrescentar algo ao que já foi dito, eu ficaria muito grato.
deepak
1
@deepak Imagine que uma posição é representada por uma x,ytupla no espaço 2D. Para cada par de, di[i], dj[i]adicione-o x,ye você será x,ytransposto em cada direção, um por um. Isso faz sentido?
Patashu
64

Para aqueles que acham a explicação de Patashu difícil de seguir, tentarei esclarecer.

Imagine que você está tentando considerar todos os movimentos possíveis a partir de um determinado ponto de um tabuleiro de xadrez.

Se você percorrer as matrizes di e dj, interpretando os valores di como deslocamentos x e os valores dj como deslocamentos y, você cobrirá cada uma das 8 direções possíveis.

Assumindo que x positivo é leste e y positivo é sul (como na resposta de Patashu), você obtém o seguinte;

  | di / x | dj / y | Direção
- + ------ + ------ + -----------
0 | 1 | 0 | leste
1 | -1 | 0 | oeste
2 | 0 | 1 | sul
3 | 0 | -1 | norte
4 1 | 1 | sudeste
5 | -1 | -1 | noroeste
6 1 | -1 | nordeste
7 -1 | 1 | sudoeste

As matrizes diK e djK podem ser interpretadas da mesma maneira para estabelecer os movimentos possíveis para a peça do Cavalo. Se você não estiver familiarizado com o xadrez, o Cavalo se move em um padrão L - duas casas em uma direção e, em seguida, uma casa perpendicular a ela (ou vice-versa).

  | diK / x | djK / y | Direção
- + ------- + ------- + ----------------
0 | -2 | -1 | 2 oeste, 1 norte
1 | -2 | 1 | 2 oeste, 1 sul
2 | -1 | 2 | 1 oeste, 2 sul
3 | 1 | 2 | 1 leste, 2 sul
4 2 | 1 | 2 leste, 1 sul
5 | 2 | -1 | 2 leste, 1 norte
6 1 | -2 | 1 leste, 2 norte
7 -1 | -2 | 1 oeste, 2 norte
James Holderness
fonte
1

Um pequeno trecho de código para verificar a quantidade de movimentos possíveis em todas as direções, que usa os arrays definidos.

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