2009-03-14 22 views
17

Sto programmando un clone di Tetris e nel mio gioco memorizzo i miei blocchi di tetromino come array di blocchi 4x4. Ora devo essere in grado di ruotare le posizioni dei numeri interi negli array in modo da ottenere un blocco tetris ruotato. Non posso semplicemente ruotare la texture perché tutto il mio rilevamento delle collisioni, ecc. È stato progettato per funzionare con l'array 2D. Il gioco è scritto in C# usando XNA.Come ruotare una matrice 2D di numeri interi

Come posso ruotare il mio array 2D di ints di 90 gradi in senso orario/antiorario.

Ecco come viene memorizzato il mio blocco "L" come esempio.

0 1 0 0 
0 1 0 0 
0 1 1 0 
0 0 0 0 

Grazie per il vostro aiuto.

+0

Sia C# e C++? –

risposta

29

Se si tratta di un array 2D, è possibile implementare la rotazione copiando diversi ordini di accesso alla matrice.

cioè, per una rotazione oraria, prova:

int [,] newArray = new int[4,4]; 

for (int i=3;i>=0;--i) 
{ 
    for (int j=0;j<4;++j) 
    { 
     newArray[j,3-i] = array[i,j]; 
    } 
} 

antioraria è simile.

+0

Buona soluzione, ma eccessivo dato il dominio del problema. –

+0

testare questo codice ora ... –

+0

Sto votando questo, dovrebbe essere contrassegnato come la soluzione. Non sei sicuro di cosa intendi con rde6173, a meno che tu non stia garantendo la memorizzazione di 4 array di orientamento. – Ricket

4

Se si desidera ruotare un blocco di 4 x 4, basta spostare le posizioni:

A B C A 
C D D B 
B D D C 
A C B A 

Ogni A si sposta alla prossima A, e lo stesso per B, C e D.

/-----\ 
    |  | 
    |  V 
    A B C A 
/->C D>D B--\ 
| B D D C | 
| A C B A | 
| |^ | 
| | | | 
\----/ \----/  
+0

Penso che la tua immagine sia un po 'spenta, non sai esattamente cosa stai cercando di chiarire con esso e le frecce sembrano puntare b -> c e a -> c piuttosto che supportare le tue istruzioni. fmsf, crescere. – Ricket

+0

@Ricket, grazie, corretto. –

6

Nel tetris classico ci sono pochissime permutazioni di oggetti. Avrei semplicemente una matrice costante per ogni "tetromino", in ciascuna delle 4 posizioni, e una logica semplice per scegliere quella appropriata in base all'input.

Perché sprecare i cicli della CPU cercando di ruotarlo?

+0

La matematica è così semplice in questo caso, probabilmente è altrettanto veloce ruotare come sarebbe fare la ricerca di permutazione basata sulla posizione di blocco corrente + posizione. –

+0

È ridicolo. –

+0

Inoltre, aggiungo che dal punto di vista del gameplay e del design, potrebbe essere meglio avere delle rotazioni preimpostate. Cosa fai quando ottieni il pezzo lungo 4x1? Se lo ruotate due volte, dovrebbe essere davvero uno spazio pieno sul lato (quale sarebbe se si utilizza la matematica pura)? –

11

Non ruotare i pezzi con il codice. È sufficiente memorizzare una serie di diversi orientamenti del pezzo e scorrere attraverso di essi quando il pezzo viene ruotato. Non è necessario ruotarli dinamicamente in un gioco Tetris.

Poiché il dominio del problema è Tetris, scoprirete che un algoritmo di rotazione causa effetti indesiderati, come il lungo e sottile Tetronimo che non si alterna tra due posizioni (come nella realtà).

+0

-1; Non vi è alcun vantaggio per la memorizzazione di 4 orientamenti di ciascun pezzo piuttosto che solo la rotazione. Dovresti concentrarti a rispondere alla sua domanda, senza scoraggiarlo, a meno che non stia commettendo un errore critico; che certamente non è. – Ricket

+0

Ci sarebbe voluto molto meno tempo per scrivere un ciclo for double come suggerito sopra. –

+4

Ricket, facile sul tono lì. Ho aggiornato la mia risposta per indicare perché la rotazione è una cattiva idea in questo caso. – Jon

1

Vorrei memorizzare (x, y) le coordinate delle "celle" e utilizzare la matrice di rotazione per ruotarle. Vedere Drawing a Rotated Rectangle per esempio. Probabilmente devi arrotondare il risultato all'incremento di 0.5 più vicino. Codice

0

js sia in senso orario che in senso antiorario:

function arrRotation90(arr, clockwise) { 
      var arr_rotated = []; 
      for (var i = 0; i < arr[0].length; i++) { 
       arr_rotated[i] = []; 
      } 
      if (clockwise) { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[arr[i].length-1-j][i] = arr[i][j]; 
        } 
       } 
      } else { 
       for (var i = 0; i < arr.length; i++) { 
        for (var j = 0; j < arr[i].length; j++) { 
         arr_rotated[j][arr.length - 1 - i] = arr[i][j]; 
        } 
       } 
      } 
      return arr_rotated; 
     } 
Problemi correlati