Thread: Tetris

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    4

    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^^

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So, how do you THINK you should do it?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    You could rewrite case left as:
    Code:
    return (l->x > 0 && Board[l->x-1][l->y] != 'X'); // 1 if true, 0 if false

  4. #4
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    Then case right is this:
    Code:
    return (l->x < 0 && Board[l->x+1][l->y] != 'X');
    and case down i dont know

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    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.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    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^^
    Last edited by estoyperdida; 01-24-2008 at 01:18 PM.

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    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.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Jan 2008
    Posts
    4
    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?
    Last edited by estoyperdida; 01-25-2008 at 12:28 PM.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    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]".
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Game Idea (Tetris Maze)
    By SlyMaelstrom in forum Game Programming
    Replies: 13
    Last Post: 06-07-2006, 05:48 PM
  2. how to write a Tetris [newbie]
    By lifeisendless4m in forum C Programming
    Replies: 2
    Last Post: 10-12-2004, 09:38 PM
  3. ARGHARHGAHRHGH Help with Tetris
    By KneeGrow in forum Tech Board
    Replies: 3
    Last Post: 09-09-2004, 11:40 PM
  4. Test my new tetris game
    By PJYelton in forum Game Programming
    Replies: 6
    Last Post: 04-19-2003, 05:21 PM
  5. AGS Tetris Clone
    By Damascus in forum Game Programming
    Replies: 1
    Last Post: 03-07-2003, 05:17 PM