Thread: Shape collision and board matrix in tetris clone c++

  1. #1
    Registered User
    Join Date
    Feb 2012
    Posts
    26

    Shape collision and board matrix in tetris clone c++

    I need help from stopping shapes from going right through other shapes. Someone said I needed a board matrix, but I have no Idea how to set that up.

    Right now I have all movement and roation done and have a random generator to randomaly put shapes on canvas/grid.

    Here is the code:
    Code:
    //Dark GDK - The Game Creators - www.thegamecreators.com
    
    //the wizard has created a very simple project that uses Dark GDK
    //it contains the basic code for a GDK application
    
    //whenever using Dark GDK you must ensure you include the header file
    #include "DarkGDK.h"
    #include <cstdlib>
    #include <ctime>
    
    
    //Global
    int Block_Size=20; 
    int grid[20][10];
    //colors
    const DWORD Red = dbRGB(255,0,0);
    const DWORD Green = dbRGB(0,255,0);
    const DWORD Blue = dbRGB(0,0,255);
    const DWORD Magenta = dbRGB(255,0,255);
    const DWORD Black = dbRGB(0,0,0);
    const DWORD White = dbRGB(255,255,255);
    const DWORD Yellow = dbRGB(255,255,0);
    const DWORD Cyan = dbRGB(0,255,255);
    const DWORD Orange = dbRGB(255,165,0);
    const DWORD Grey = dbRGB(177,177,177);
    //end colors
    //end global
    
    //Classes
    
    class Block {
    private:
        DWORD color;
        //int blocks[4];
    public:
        int x,y;
        Block();
        Block(int, int, DWORD);
        void draw();
        void move(int, int);
        void clear();
        void rotation(int,int);
        
    };
    Block::Block(){
    x = 0;
    y = 0;
    color = White;
    }
    //Methods (Block)
    void Block::rotation(int px , int py)
    {
        int xp, yp;
    
        xp=px-py+y;
        yp=px+py-x;
    
        x=xp;
        y=yp;
        dbInk(color, Grey);
        draw();
    
    }
    
    Block::Block(int X, int Y, DWORD COLOR)
    {
        x=X;
        y=Y;
        color=COLOR;
    }
    
    void Block::draw()
    {
        int x1, y1, x2, y2;
        x1=x*Block_Size;
        y1=y*Block_Size;
        x2=x1+Block_Size;
        y2=y1+Block_Size;
    
    //    dbInk(color, Black);
        dbBox(x1,y1,x2,y2);
    }
    
    void Block::clear()
    {
    
        dbInk(Grey, Grey);
        //dbBox(x1,y1,x2,y2);
        draw();
    }
    
    void Block::move(int dx, int dy)
    {
        x=x+dx;
        y=y+dy;
        dbInk(color, Grey);
        draw();
    }
    
    //End Method (Block)
    
    class Shape {
    
    private:
        Block blocks[4];
        //int pos[8];
    public:
        int pos[8];
        DWORD color;
        Shape();
        void make_ishape();
        void make_oshape();
        void make_jshape();
        void make_lshape();
        void make_tshape();
        void make_zshape();
        void make_sshape();
        void move_shape(int,int);
        void draw_shape();
        bool col(int,int);
        bool colnew(int,int);
        void rotate_shape();
        //void rotate_zshape();
        //void rot(int,int);
        
    };
    //Methods (Shape)
    Shape::Shape() {
    blocks[0] = Block(0,0, White);
    blocks[1] = Block(0,0, White);
    blocks[2] = Block(0,0, White);
    blocks[3] = Block(0,0, White);
    }
    bool Shape::col(int dx, int dy)
    {
        for (int i=0; i<=4; i++)
        {
            if (blocks[i].y + dy > 19 || blocks[i].x + dx < 0 || blocks[i].x +dx > 9)
            {
                return false;
            }
            
        }
        return true;
    }
    bool Shape::colnew(int dx, int dy)
    {
        for (int i=0; i<=4; i++)
        {
            if (blocks[i].y + dy > 19)
            {
                return false;
            }
            
        }
        return true;
    }
    
    
    
    void Shape::make_ishape()
    {
        blocks[0] = Block(pos[0],pos[1],Blue);
        blocks[1] = Block(pos[2],pos[3],Blue);
        blocks[2] = Block(pos[4],pos[5],Blue);
        blocks[3] = Block(pos[6],pos[7],Blue);
        
    }
    void Shape::make_oshape()
    {
        blocks[0] = Block(pos[0],pos[1],Green);
        blocks[1] = Block(pos[2],pos[3],Green);
        blocks[2] = Block(pos[4],pos[5],Green);
        blocks[3] = Block(pos[6],pos[7],Green);
        
    }
    void Shape::make_jshape()
    {
        blocks[0] = Block(pos[0],pos[1],Yellow);
        blocks[1] = Block(pos[2],pos[3],Yellow);
        blocks[2] = Block(pos[4],pos[5],Yellow);
        blocks[3] = Block(pos[6],pos[7],Yellow);
        
    }
    void Shape::make_lshape()
    {
        blocks[0] = Block(pos[0],pos[1],Orange);
        blocks[1] = Block(pos[2],pos[3],Orange);
        blocks[2] = Block(pos[4],pos[5],Orange);
        blocks[3] = Block(pos[6],pos[7],Orange);
        
    }
    void Shape::make_tshape()
    {
        blocks[0] = Block(pos[0],pos[1],Cyan);
        blocks[1] = Block(pos[2],pos[3],Cyan);
        blocks[2] = Block(pos[4],pos[5],Cyan);
        blocks[3] = Block(pos[6],pos[7],Cyan);
        
    }
    void Shape::make_zshape()
    {
        blocks[0] = Block(pos[0],pos[1],Red);
        blocks[1] = Block(pos[2],pos[3],Red);
        blocks[2] = Block(pos[4],pos[5],Red);
        blocks[3] = Block(pos[6],pos[7],Red);
        
    }
    /*/void Shape::rotate_zshape()
    {
        blocks[0] = Block(pos[0],pos[1],Red);
        blocks[1] = Block(pos[2],pos[3],Red);
        blocks[2] = Block(pos[4],pos[5],Red);
        blocks[3] = Block(pos[6],pos[7],Red);
    }
        /*/
    void Shape::make_sshape()
    {
        blocks[0] = Block(pos[0],pos[1],Magenta);
        blocks[1] = Block(pos[2],pos[3],Magenta);
        blocks[2] = Block(pos[4],pos[5],Magenta);
        blocks[3] = Block(pos[6],pos[7],Magenta);
        
    }
    void Shape::draw_shape()
    {
        for (int i=0; i<4; i++)
        {
            blocks[i].draw();
        }
    }
    
    void Shape::move_shape(int dx, int dy)
    {
        for (int i=0; i<4; i++)
        {
            blocks[i].clear();
        }
        for (int i=0; i<4; i++)
        {
            blocks[i].move(dx,dy);
        }
    }
    
    void Shape::rotate_shape()
    {
        for (int i=0; i<4; i++)
        {
            blocks[i].clear();
        }
        for (int i=0; i<4; i++)
        {
            blocks[i].rotation(blocks[1].x,blocks[1].y);
    
        }
        
    }
    
    class I_Shape: public Shape{
    public:
        I_Shape(int,int);
        
    private:
        DWORD color;
        //int pos[8];
    };
    
    //Methods (I_Shape)
    
    
    I_Shape::I_Shape(int x, int y):Shape()
    {
    
        color=Blue;
        pos[0]=x-1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x+1;
        pos[5]=y;
        pos[6]=x+2;
        pos[7]=y;
        make_ishape(); //makes I_Shape
    }
    
    
    class O_Shape: public Shape{
    public:
        O_Shape(int,int);
    private:
        DWORD color;
    };
    O_Shape::O_Shape(int x, int y):Shape()
    {
        color=Red;
        pos[0]=x;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y-1;
        pos[4]=x+1;
        pos[5]=y-1;
        pos[6]=x+1;
        pos[7]=y;
        make_oshape(); //makes O_Shape
    
    }
    
    class J_Shape: public Shape{
    public:
        J_Shape(int,int);
    private:
        DWORD color;
    };
    J_Shape::J_Shape(int x, int y):Shape()
    {
        color=Yellow;
        pos[0]=x-1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x+1;
        pos[5]=y;
        pos[6]=x+1;
        pos[7]=y-1;
        make_jshape(); //makes I_Shape
    }
    
    class L_Shape: public Shape{
    public:
        L_Shape(int,int);
    private:
        DWORD color;
    };
    L_Shape::L_Shape(int x, int y):Shape()
    {
        color=Orange;
        pos[0]=x+1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x-1;
        pos[5]=y;
        pos[6]=x-1;
        pos[7]=y-1;
        make_lshape(); //makes L_Shape
    }
    
    class T_Shape: public Shape{
    public:
        T_Shape(int,int);
    private:
        DWORD color;
    };
    T_Shape::T_Shape(int x, int y):Shape()
    {
        color=Cyan;
        pos[0]=x-1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x;
        pos[5]=y-1;
        pos[6]=x+1;
        pos[7]=y;
        make_tshape(); //makes T_Shape
    }
    
    class Z_Shape: public Shape{
    public:
        Z_Shape(int,int);
        //Rotate_Z(int,int);
    private:
        DWORD color;
    };
    Z_Shape::Z_Shape(int x, int y):Shape()
    {
        color=Red;
        pos[0]=x-1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x;
        pos[5]=y+1;
        pos[6]=x+1;
        pos[7]=y+1;
        make_zshape(); //makes Z_Shape
        
    }
    //new code 
    
    Shape* random()
    {
        int x=3;
        int y=1;
        Shape *currentshape;
        unsigned seed = time(0);
    
        srand(seed);
    
        int random = 1 + rand() % 6;
        switch (random)
        {
        case 1:
            currentshape = new I_Shape(x,y);
            break;
        case 2:
            currentshape = new L_Shape(x,y);
            break;
        case 3:
            currentshape = new J_Shape(x,y);
            break;
        case 4:
            currentshape = new Z_Shape(x,y);
            break;
        case 5:
            currentshape = new T_Shape(x,y);
            break;
        case 6:
            currentshape = new O_Shape(x,y);
            break;
        }
            return currentshape;
    }
    
    
    /*/class S_Shape: public Shape{
    public:
        S_Shape(int,int);
    private:
        DWORD color;
    };
    S_Shape::S_Shape(int x, int y):Shape()
    {
        color=Magenta;
        pos[0]=x-1;
        pos[1]=y;
        pos[2]=x;
        pos[3]=y;
        pos[4]=x;
        pos[5]=y+1;
        pos[6]=x-1;
        pos[7]=y+1;
        make_sshape(); //makes S_Shape
    }/*/
    
    // the main entry point for the application is this function 
    //(MAIN)
    void DarkGDK ( void )
    {
        dbInk(Grey,Grey);
        dbBox(0,0,200,400);
        
        //I_Shape First(3,1);
        //O_Shape First(3,1);
        //J_Shape First(3,1);
        //L_Shape First(3,1);
        //T_Shape First(3,1);
        //Z_Shape First(3,1);
        Shape *currentshape;
        currentshape=random();
        currentshape->draw_shape();
        
        // turn on sync rate and set maximum rate to 1 fps
        dbSyncOn   ( );
        dbSyncRate (1);
        //First.draw_shape();
        //First.move_shape(5,4);
        
    
        // our main loop
        while ( LoopGDK ( ) )
        { 
            
            if (grid[20][10]!=Grey)
            {
                if (dbLeftKey())
                {
                    if (currentshape->col(-1,0))
                    {    
                    currentshape->move_shape(-1,0);
                    }
                }
                if (dbRightKey())
                {
                    if (currentshape->col(1,0))
                    {
                    currentshape->move_shape(1,0);
                    }
                }    
    
            
                if (dbDownKey())
                {
                    if (currentshape->col(0,1))
                    {
                    currentshape->move_shape(0,1);        
                    }
                }
                else if (currentshape->col(0,1))
                    {
                    currentshape->move_shape(0,1);        
                    }
                else
                {
                    currentshape=random();
                }
                if (dbUpKey())
                {
                //    if (First.col(0,1))
                //    {
                    currentshape->rotate_shape();        
                //    }
                }
            }
            
            // update the screen
            dbSync ( );
            //dbWaitKey();
        }
        
        
        // return back to windows
        return;
    }

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    What happened with randomly generating shapes? You left out the S shape?

    Again though, with this problem, I'm not going to outright tell you how to do it because I believe this is a projects that someone should do because they want to do it, not because they have some stupid assignment to write it. Just like I wouldn't help you paint a masterpiece, or make a musical composition, tetris is perhaps more of an art than an exact science.

    Okay, lets put it this way, please please PLEASE come up with at least one description as to how you could solve the problem. Ignore for the moment that you don't quite have the C++ knowledge required, and just describe the beginnings of how you could perhaps go about it. You get that far and I'll help a little more. Or perhaps someone else will be more generous.

    And please please, don't just go by some vague details of what someone else said for how to solve it. You're not a mindless zombie. What is important for you is to clean out the cobwebs in the problem solving areas of your brain, and start thinking long and hard about possible solutions. It doesn't matter if the ideas don't quite work, it's the thought process that is important.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    To be honest, you should be prototyping your algorithm away from your mainline code.

    That is, you should be able to express in say 50 lines of ASCII ART what you're trying to express in 500+ lines. Making 8 shapes and all the movement code is irrelevant to the problem at hand (and we're not interested (or indeed able) to download a whole graphics library just to test your code for ourselves). Everyone can run ASCII art programs, and it allows you to really focus on the issue at hand.

    How does
    ###
    #

    Fit on top of
    ##
    ###
    ?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 7
    Last Post: 04-02-2008, 10:27 AM
  2. Pong Clone Collision Allegro
    By gillypie in forum C++ Programming
    Replies: 1
    Last Post: 12-29-2007, 02:42 AM
  3. First attempt at tetris clone...which api should I use?
    By RealityFusion in forum Game Programming
    Replies: 7
    Last Post: 10-11-2005, 02:06 PM
  4. AGS Tetris Clone
    By Damascus in forum Game Programming
    Replies: 1
    Last Post: 03-07-2003, 05:17 PM
  5. Tetris clone?
    By Fool in forum Game Programming
    Replies: 4
    Last Post: 08-26-2001, 04:39 AM