0

I am trying to shift the contents of a 2d array down when implementing Tetris in C. This is to move the blocks down. The code works but its not moving elements once only, See the image for the problem(The number in the top left corner is the random number that determines the block type). Any help appreciated. Below is the array shifting code:

//Declare size of board
    int board [22][10] = {};

 //Shift down
    for(i=2;i<20;i++)
    {
        for(z=1;z<10;z++)
        {
            board[i+1][z] = board[i][z];
        }
    }

http://i61.tinypic.com/xlb58g.jpg

Crckr Hckr
  • 11
  • 1
  • 2
  • 1
    `board[i+1][z] = board[i][z];` You are overwriting `board[i+1][z]` without storing what was there before - is this intended? – Filipe Gonçalves May 31 '14 at 13:45
  • So what does your code do for cells at `i=2`? How does their value change when you shift down? – hyde May 31 '14 at 13:46
  • Also, use debugger, follow what the code does in your head for a few iterations. It'd be very good for your learning, if you can figure this out yourself, instead of someone telling you what the problem is... – hyde May 31 '14 at 13:50
  • I don't get it what you mean Filipe, I guess that could be the problem. i=2 because the first two rows are meant to be hidden. – Crckr Hckr May 31 '14 at 13:51
  • Why do you start at `z=1` instead of `z=0`? Is there nothing interesting in the first column? Or is that again not a visible item... – Floris May 31 '14 at 14:15

1 Answers1

4

Whenever you shift the contents of an array, you must work in the opposite direction then the shifting. In your case, you need to invert the direction of your outer loop:

int board [22][10] = {};

for(i = 20; i-- > 2; ) {
    for(z=1; z<9; z++) {
        board[i+1][z] = board[i][z];
    }
}

This allows the row of unused values to rise up in the array like a bubble.


Edit:
The code above was written to match the apparent intended behavior of the code posted in the question. If the entire array is to be moved, use this code:

for(i = sizeof(board)/sizeof(*board) - 1; i--; ) {
    for(z = 0; z < sizeof(*board)/sizeof(**board); z++) {
        board[i+1][z] = board[i][z];
    }
}
cmaster - reinstate monica
  • 38,891
  • 9
  • 62
  • 106
  • It shows improvement, however it still gives the problem of multiple lines and not just moving the block at once. – Crckr Hckr May 31 '14 at 13:55
  • Is it possible that the bounds you have given are wrong? Your code tried to move the lines 3-20 to the lines 2-19. That means, that lines 0, 1, and 21 are not touched at all, and line 20 is only copied but not overwritten. My code replicates this intended behavior. If you want to shift the entire array, use `for(i = sizeof(board)/sizeof(*board) - 1; i-- > 0; )` – cmaster - reinstate monica May 31 '14 at 14:04
  • Same thing with the horizontal loop: if you want to shift entire lines, use `for(z = 0; z < sizeof(*board)/sizeof(**board); z++)`. – cmaster - reinstate monica May 31 '14 at 14:06
  • I have added the entire code, please tell me what's wrong. Thanks. – Crckr Hckr May 31 '14 at 14:22
  • First thing you need to learn is to divide your work into nice, small, self-contained functions. You `main()` is 139 lines long, you won't even fit that on a full-HD monitor turned upright. A good length of a function is between ten and twenty lines, fifty being the tolerable maximum. Once you get the game divided into small tractable chunks, you shouldn't feel any urge anymore to resort to the `goto` statement which is considered harmful since the 1970s. This will help you to understand much better, what your program is actually doing. – cmaster - reinstate monica May 31 '14 at 15:03