Qual è il significato di inizializzare gli array di direzioni di seguito con valori dati quando si sviluppa un programma di scacchi?


106

Sono nuovo nella programmazione competitiva e ho notato spesso che molti dei grandi programmatori hanno queste quattro righe nel loro codice (in particolare in quelli che coinvolgono array):

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

Cosa significa veramente e per cosa viene utilizzata la tecnica?


5
Uso spesso d={0,1,0,-1,0}per questo: le coppie di oggetti per d[i], d[i+1]darmi quattro direzioni cardinali.
dasblinkenlight

14
Questa è una domanda sorprendentemente buona. ... Si può fare qualcosa per il titolo?
luser droog

7
Quindi non hai pensato di menzionare che questo codice proviene da un motore di scacchi? Inoltre non hai pensato di guardare te stesso come venivano usati questi valori?
trojanfoe

15
"molti dei grandi programmatori hanno queste quattro righe [...]" - Sto pignolando qui, ma se fossero grandi programmatori, il loro codice non ti farebbe chiedere "ma cos'è quel costrutto ?!"
utnapistim

6
@utnapistim Quando scrivi la maggior parte del codice, hai ragione, ma qui, ti manca il punto. Questo caso è un'eccezione legittima a questa regola. Se stai scrivendo codice per una competizione e hai un vincolo di tempo, veloce e sporco è quasi sempre meglio di pulito e manutenibile. In questo caso leggibile per te, ora è davvero tutto ciò che conta. Un grande programmatore scrive molto bene un pasticcio illeggibile e non mantenibile in questo contesto , anche se la maggior parte del loro codice normale è altamente leggibile e gestibile.
Ben Lee

Risposte:


84

Questa è una tecnica per codificare tutte le direzioni come array: ogni coppia di di[i],dj[i]è una direzione diversa.

Se immaginiamo di avere un pezzo in una posizione x, y, e vogliamo aggiungere alla sua x e al suo valore y per spostarlo in una posizione vicina, 1,0 è est, -1,0 è ovest, 0,1 è il sud, 0, -1 è il nord e così via.

(Qui ho detto che in alto a sinistra è 0,0 e in basso a destra è 4,4 e ho mostrato quale spostamento farà ogni indice degli array dal punto centrale, X, a 2,2.)

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

Nel modo in cui è impostato, se lo fai ^1( ^essendo XOR bit per bit) sull'indice ottieni la direzione opposta: 0 e 1 sono opposti, 2 e 3 sono opposti e così via. (Un altro modo per impostarlo è andare in senso orario partendo da nord, quindi ^4ti porta nella direzione opposta.)

Ora puoi testare tutte le direzioni da un dato punto eseguendo il loop sugli array die dj, invece di dover scrivere ogni direzione sulla propria riga (per otto in totale!) (Non dimenticare di controllare i limiti :))

diKe djKformare tutte le direzioni dei cavalieri invece di tutte le direzioni adiacenti. Qui, ^1ruoterà lungo un asse, ^4darà il salto del cavaliere opposto.

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

3
cosa sono le "direzioni dei cavalieri"?
David

4
Oh, quel tipo di cavaliere.
David

1
Grazie mille per la tua risposta .. Potresti collegarmi o forse mostrarmi un po 'di codice per illustrarlo meglio .. (Sono un po' alle prime armi ..se puoi capire :) Grazie ancora
ejjyrex

1
Plaudo al tentativo di risposta di Patashu. Anche se sembra che molti abbiano capito la sua spiegazione, io non sono stato in grado di capirla bene. Se qualcuno può aggiungere qualcosa a quanto già detto, gliene sarei molto grato.
Deepak

1
@deepak Immagina che una posizione sia rappresentata da una x,ytupla nello spazio 2D. Per ogni coppia di[i], dj[i]aggiungilo x,ye verrai x,ytrasposto in ciascuna direzione uno per uno. Ha senso?
Patashu

64

Per coloro che trovano difficile seguire la spiegazione di Patashu, cercherò di chiarire.

Immagina di provare a considerare ogni possibile mossa da un dato punto su una scacchiera.

Se si esegue il loop sugli array di e dj, interpretando i valori di come offset x ei valori dj come offset y, si copre ciascuna delle 8 direzioni possibili.

Supponendo che x positivo sia est e y positivo sia sud (come nella risposta di Patashu), ottieni quanto segue;

  | di / x | dj / y | Direzione
- + ------ + ------ + -----------
0 | 1 | 0 | est
1 | -1 | 0 | ovest
2 | 0 | 1 | Sud
3 | 0 | -1 | nord
4 | 1 | 1 | a sud-est
5 | -1 | -1 | Nord Ovest
6 | 1 | -1 | a nord-est
7 | -1 | 1 | a sud-ovest

Gli array diK e djK possono essere interpretati allo stesso modo per stabilire le possibili mosse per il pezzo Knight. Se non hai familiarità con gli scacchi, il Cavaliere si muove secondo uno schema a L: due caselle in una direzione e poi una casella ad angolo retto rispetto a quella (o viceversa).

  | diK / x | djK / y | Direzione
- + ------- + ------- + ----------------
0 | -2 | -1 | 2 ovest, 1 nord
1 | -2 | 1 | 2 ovest, 1 sud
2 | -1 | 2 | 1 ovest, 2 sud
3 | 1 | 2 | 1 est, 2 sud
4 | 2 | 1 | 2 est, 1 sud
5 | 2 | -1 | 2 est, 1 nord
6 | 1 | -2 | 1 est, 2 nord
7 | -1 | -2 | 1 ovest, 2 nord

1

Un piccolo frammento di codice per controllare la quantità di mosse possibili in tutte le direzioni, che utilizza gli array definiti.

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.