Tetris

• 01-23-2008
estoyperdida
Tetris
Hi!!

I have done this:
Code:

```int MovAllowed(Block * l,int where) { switch(where) { case left: if(l->x>0) // if(Board[l->x-1][l->y]!='X') //If the movement towards the left side not this blocked by another card { return 1; } return 0; case right: case down:```
I have done `case left`, but i don't know how can i do case right and down.
Thanks^^
• 01-23-2008
matsp
So, how do you THINK you should do it?

--
Mats
• 01-23-2008
robatino
You could rewrite case left as:
Code:

`return (l->x > 0 && Board[l->x-1][l->y] != 'X'); // 1 if true, 0 if false`
• 01-23-2008
estoyperdida
Then case right is this:
Code:

`return (l->x < 0 && Board[l->x+1][l->y] != 'X');`
and case down i dont know :(
• 01-23-2008
dwks
It's not difficult.
• centre: Board[l->x][l->y]
• left: Board[l->x - 1][l->y]
• right: Board[l->x + 1][l->y]
• down: Board[l->x][l->y + 1]
• up: Board[l->x][l->y - 1]
• upper left: left: Board[l->x - 1][l->y - 1]
• /* ... */

That's assuming you have it set up like I'm assuming. :)
• 01-24-2008
estoyperdida
Thank you so much <3 , you are great!!

I have another dude...
I have this
Code:

```// movement of block down void downblock(block * l) {   int i;   for(i=0;i<4;i++)       l->Bl[i].y++; }```
Then, is this the movement right and left?
Code:

```// movement of left block void leftblock(block * l) {   int i;   for(i=0;i<4;i++)       l->Bl[i ].x--; } // movement of right block void rightblock(block * l) {   int i;   for(i=0;i<4;i++)       l->Bl[i ].x++; }```
Code:

``` //GLOBALS typedef struct strBlock {   int x; //Position board   int y; } Block; /* The structure Card, is a form with four blocks */ typedef struct strCard {   int type;   Block Bl[4];  //Each card is 4 blocks } Card;```

Thanks^^
• 01-24-2008
dwks
Yes, what you have is correct.

However, it might be more economical to have a function like this:
Code:

```void move_block(const block *l, int x, int y) {     int i;     for(i = 0; i < 4; i ++) {         l->Bl[i ].x += x;         l->Bl[i ].y += y;     } }```
Then you can just call move_block(l, 0, 1) to move a block (0,1), or downwards, etc.

Or, if you can't wrap your head around 0, 1 meaning downwards, you could use some #defines or an enum to do the job for you -- perhaps something like this.
Code:

```typedef enum {     DIR_UP,     DIR_LEFT,     DIR_RIGHT,     DIR_DOWN } direction; void get_dir_values(direction dir, int *x, int *y) {     switch(direction) {     case DIR_UP:         *x = -1, *y = 0;         break;     /* ... */     } } void move_block(const block *l, direction dir) {     int i, x, y;     get_dir_values(dir, &x, &y);         for(i = 0; i < 4; i ++) {         l->Bl[i ].x += x;         l->Bl[i ].y += y;     } }```
Then again, maybe that's just too much code. :)
• 01-25-2008
estoyperdida
thank u for such a great code dwks^^ you are fabulous!

My last (LAST) dude:
Code:

```void CheckLines()  { int count_lines=0;         int i,j,h,count_block;         for(j = 0; j < 16; j++) {                 for(i = 0; i < 10; i++) {                         if(Board[j][i] != 0) {                                 count_block++;                         }                 }                 if(count_block == 10) {                                       count_lines++;                         for(h = j; h > 0; h--) {                                 for(i = 0; i < 10; i++) {                                         Board[h][i] = Board[h][i-1];                                 }                         }                 }         } }```
But when i play with the game, when I do a line, the line doesn't dissapear, I don't Know what is wrong :(, someone can help me?
• 01-30-2008
dwks
Sorry I took so long to reply, I haven't been online recently.

Code:

```                                for(i = 0; i < 10; i++) {                                         Board[h][i] = Board[h][i-1];                                 }```
What's going to happen when i is zero? You're going to be accessing Board[h][0-1]. Whoops. That's before the beginning of the array.

I also have a suggestion for your algorithm. Right now, for every row that is deleted, you shift every row above it downwards. (Well, that's what you're trying to do.) But this is a bit inefficient when there are two or more rows that are to be deleted.

Here's an alternative algorithm. Set a counter to zero. When you delete a row, increment the counter. For every row, shift the row upwards by the number of rows specified by counter. This works because if only one row was deleted, you'll be shifting every row down by 1, just as you want; but if two were deleted, you'll shift every row by 2.

Anyway, something like this:
Code:

```#define WIDTH 10 #define HEIGHT 16 /* set a row to consist of all empty blocks */ void clear_row(int row) {     int x;     for(x = 0; x < WIDTH; x ++) Board[x][row] = 0; } /* shift the row "from" to the row "to" */ void shift_row(int from, int to) {     int x;     for(x = 0; x < WIDTH; x ++) {         Board[x][to] = Board[x][from];     } } /* remove rows that are full of blocks */ void remove_blocks() {     int x, y, removed = 0, redo = 0;     /* start at the bottom and work upwards */     for(y = HEIGHT - 1; y >= 0; y --) {         /* only shift the row if a previous row has been deleted */         if(removed) {             /* shifting would underflow, so clear the row instead */             if(y - removed < 0) clear_row(y);             else shift_row(y, y - removed);         }         for(x = 0; x < WIDTH; x ++) {             if(Board[x][y] == 0) break;  /* the space is empty */         }         /* scanned the whole row without finding an empty space */         if(x == WIDTH) {             removed ++;             y --;  /* examine the current row again */         }     } }```
The algorithm needs a little more explanation. When you delete a row, you need to examine that same row again, once you shift the new row into the new position. Why? Well, because when you delete the row, you increment the counter, and so the counter is refering to a different row than the row you just checked. This new row needs to be checked as well, but on the next iteration of the loop, the new row will appear in the same place, into the row you just deleted. It's kind of hard to explain. I think my algorithm works, but of course I haven't had a chance to test it.

Also, in future, it would help if you explained in more detail what was happening instead of just saying "the line doesn't [disappear]". :)