How to Rotate a 2D Array of Integers

17,727

Solution 1

If they're a 2D array, you can implement rotation by copying with different array access orders.

i.e., for a clockwise rotation, try:

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

Counter-clockwise is similar.

Solution 2

Don't rotate the pieces with code. Just store an array of the different piece orientations and cycle through them when the piece is rotated. There's no need to dynamically rotate them in a Tetris game.

As the problem domain is Tetris, you will find that a rotation algorithm causes undesirable effects, such as the long thin Tetronimo not alternating between two positions (as it does in the real thing).

Solution 3

In classic tetris there are very few permutations of objects. I would simply have a constant array for each "tetromino," at each of the 4 positions, and simple logic to choose the appropriate one based on input.

Why waste CPU cycles trying to rotate it?

Solution 4

If you want to rotate a 4 x 4 block, you just move the positions:

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

Each A moves to the next A, and the same for B, C and D.

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

Solution 5

int[,] source = { { 1,2,3 }, {4,5,6 }, { 7,8,9} };
int[,] result = new int[3,3];
var rows = source.GetLength(0);
var cols = source.GetLength(1);

for (var r=0; r<rows; r++)
{
    for (var c = 0; c < cols; c++)
    {
        result[r, c] = source[rows - 1 - c, r];
    }
}
Share:
17,727

Related videos on Youtube

Brock Woolf
Author by

Brock Woolf

I predominantly code in Objective-C (Cocoa Touch) and C# (.net) I write games and utility software and do iPhone and iPad development. More here: BrockWoolf.com.

Updated on February 07, 2020

Comments

  • Brock Woolf
    Brock Woolf over 4 years

    I am programming a Tetris clone and in my game I store my tetromino blocks as 4x4 arrays of blocks. I now need to be able to rotate the integer positions in the arrays so that I get a rotated tetris block. I cannot simply rotate the texture because all my collision detection, etc has been designed to work with the 2D array. The game is written in C# using XNA.

    How can i possibly rotate my 2D array of ints by 90 degrees clockwise/counter clockwise.

    Here is how my 'L' block is stored as an example.

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

    Thanks for your help.

  • Reed Copsey
    Reed Copsey about 15 years
    The math is so simple in this case, it's probably just as fast to rotate it as it would be to do the permutation search based on the current block style + position.
  • Matt Howell
    Matt Howell about 15 years
    I'd also add that from a gameplay and design point-of-view, it might be better to have pre-set rotations. What do you do when you get the long 4x1 piece? If you rotate it twice, should it really be one full space over to the side (which it would be if you use pure math)?
  • Ryan Emerle
    Ryan Emerle about 15 years
    Good solution, but overkill given the problem domain.
  • Ricket
    Ricket about 15 years
    CPU cycles are not an issue in this case. Do not try to overoptimize by thinking about "wasting CPU cycles". Whether you store 4 different permutations and select one, or loop through and rotate the array, either way will be so minimal a time span that it won't matter at all. Down vote.
  • Ricket
    Ricket about 15 years
    -1; There is no advantage to storing 4 orientations of each piece rather than just rotating. You should be focused on answering his question, not discouraging him, unless he's making a critical mistake; which he certainly is not.
  • Brock Woolf
    Brock Woolf about 15 years
    I have a 2.4GHz Core 2 Duo processor, not to mention that a double for loop that checks an integer is doing a comparison of 8 bytes times 16. That's almost nothing at all for the CPU. Plus what if I one day wanted a 5x5 matrix? I'd have to recode it all.
  • Ricket
    Ricket about 15 years
    I think your picture is a little off, not sure exactly what you're trying to clarify with it and the arrows seem to point b -> c and a -> c rather than supporting your instructions. fmsf, grow up.
  • Ricket
    Ricket about 15 years
    I am voting this up, it should be marked as the solution. Not sure what you mean rde6173, unless you too are vouching for storing 4 orientation arrays.
  • Reed Copsey
    Reed Copsey about 15 years
    That's what he's suggesting. There are advantages to that, but this answers the question directly - I wasn't trying to suggest alternate designs.
  • Jon
    Jon about 15 years
    Ricket, easy on the tone there. I have updated my answer to indicate why rotation is a bad idea in this case.
  • Reed Copsey
    Reed Copsey about 15 years
    No problem :) Glad I can help.
  • Ian
    Ian almost 15 years
    It's not about the time it takes you to write as a developer, it's all about the time it takes to execute. Remember, compilers might be good at optimising loops, but they're even better when it comes to constants.
  • devilcrack
    devilcrack about 14 years
    I agree with Jon, I've just been contemplating this problem myself. If you rotate the array, the blocks don't rotate the same way as they do in the original game. They appear to rotate around the centre.
  • Merlyn Morgan-Graham
    Merlyn Morgan-Graham over 12 years
    This is not overkill as it will save manual labor of producing those pre-transformed arrays, and will be extensible to non-tetraminos if further work is put into the game beyond basic tetris. (Will +1 tomorrow when my votes reset :)
  • devsaw
    devsaw over 10 years
    It's up to the programmer whether he wants to rotate the piece or store it as 4 orientation arrays.There's not that much labour in writing out 7 * 4 pieces.I would prefer rotating though.
  • StepUp
    StepUp about 7 years
    Reed, please, be very kind, see my question stackoverflow.com/questions/42496192/…