Thread: switch problem, pressing key restores the previous move

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    44

    switch problem, pressing key restores the previous move

    Hi, problem is as follows:
    This is a tetris clone game which I'm doing for my laboratory subject of Programming and Data structures. I'm using a switch to performs actions according to every key that is needed.
    To exit the game I've chosen escape key, implemented it into switch, however pressing escape doesn't instantly quit the program but instead moves a block back one row higher (in an array)
    Here's the code,
    The function with switch is called anim, and there is one condiction for exit in the main function:
    Code:
    #include "primlib.h"
    #include "pieces.inl"
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    
    #define blockSize 15 
    #define boardWidth 15 
    #define boardHeight 25 
    #define interval 40000 /*time interval preventing from instant loop execution*/
    
    int gamespace[boardWidth][boardHeight]; /*array used to store information about blocks*/
    int counter_x, /*x-position counter*/
        counter_y; /* y-position counter*/
    int pivotX; /*counter used to find the horizontal position of pivot block in the pieces.inl definitions*/
    int pivotY; /*counter used to find the vertical position of pivot block in the pieces.inl definitions*/
    
    void draw(void); /*drawing grounded blocks*/
    int check(int horizontal, int vertical, int rot_coordinate, int blockType);/*checks whether a move is possible, and draws appropriate variant*/
    void groundSave(int horizontal, int vertical, int rot_coordinate, int blockType);/*memorizing blocks that hit the "ground"*/
    int anim(int blockType);/*rotation and left/right/down movement(according to which key is pressed)*/
    void check_delete(void); /*removing a row that is full*/
    void gameover(void); /*when block reaches the top line of the gamespace, ends loop execution and displays GAME OVER */
    
    int main()
    {
        int blockType, 
            randomBlock; /* randomBlock - randomized type of the next falling block   */
        if(initGraph())
            exit(3);
        /* generating seed for randomizing process */
        srand(time(NULL));
        /* Randomizing the type of the first block */
        randomBlock=(int)(rand()%7);
        /* Borders of the game field */
        filledRect(((screenWidth()-1)-boardWidth*blockSize)/2-6,(screenHeight()-1)-blockSize*boardHeight,((screenWidth()-1)-boardWidth*blockSize)/2-1,screenHeight()-1,BLUE);
        filledRect(((screenWidth()-1)+boardWidth*blockSize)/2+6,(screenHeight()-1)-blockSize*boardHeight,((screenWidth()-1)+boardWidth*blockSize)/2+1,screenHeight()-1,BLUE);
        /* main loop */
        while(1)
        {
            blockType=randomBlock;
            /* Randomizing the upcoming type of block */
            randomBlock=(int)(rand()%7);
            /* creating animation for block, if any of them reaches top, returns 1 and finishes the game */
            if(anim(blockType)==1)
            {
                gameover();
                return 0;
            }else if(anim(blockType)==2)
            {
                return 0;
            }
            /*removing a row that is full*/
            check_delete();
        }
    }
    /* ###################################################################### */
    void draw(void) /*drawing grounded blocks*/
    {    
        for(counter_x=0;counter_x<boardWidth;counter_x++)
            for(counter_y=0;counter_y<boardHeight;counter_y++)
                if(gamespace[counter_x][counter_y]!=0)
                {
                    /*the filling of the grounded block*/
                    filledRect(((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*counter_x,(screenHeight()-1)-blockSize*(boardHeight-counter_y),((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(counter_x+1),(screenHeight()-1)-blockSize*(boardHeight-(counter_y+1)),GREEN);
    
                    /*the border*/
                    rect(((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*counter_x,(screenHeight()-1)-blockSize*(boardHeight-counter_y),((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(counter_x+1),(screenHeight()-1)-blockSize*(boardHeight-(counter_y+1)),BLUE);
                }
    }
    /* ###################################################################### */
    int check(int horizontal, int vertical, int rot_coordinate, int blockType)/*checks whether a move is possible, and draws appropriate variant*/
    /*horizontal/vertical - current X/Y position of the falling block, rot_coordinate - initially 0, modified by player in 'anim' function by pressing SDLK_SPACE; 
    return 0 if the block is out of the gamespace 
    return 1 if the drawing is successful
    return 2 if the space in the gamespace is occupied by other block*/
    {    
        /* determining position of pivot block */    
        for(pivotX=0;pivotX<4;pivotX++)
            for(pivotY=0;pivotY<4;pivotY++)
                if(pieces[blockType][rot_coordinate][pivotY][pivotX]==2) 
                    goto end;
        end:
        for(counter_x=0;counter_x<4;counter_x++)
            for(counter_y=0;counter_y<4;counter_y++)
            {
                /* block position is unacceptable */
                if((pieces[blockType][rot_coordinate][counter_y][counter_x]!=0)&&((horizontal-pivotX+counter_x>=boardWidth)||(horizontal-pivotX+counter_x<0))) return 0;
                /* the place in the gamespace is occupied*/
                if((pieces[blockType][rot_coordinate][counter_y][counter_x]!=0)&&(((vertical-pivotY+counter_y>=boardHeight))||(gamespace[horizontal-pivotX+counter_x][vertical-pivotY+counter_y]!=0))) return 2;
            }
        /* redrawing the internal area of the gamespace */
        filledRect(((screenWidth()-1)-boardWidth*blockSize)/2,(screenHeight()-1)-blockSize*boardHeight,((screenWidth()-1)+boardWidth*blockSize)/2,screenHeight()-1,BLACK);
        /* draw the content of the game field */
        draw();
        
        /* drawing the falling blocks*/
        for(counter_x=0;counter_x<4;counter_x++)
            for(counter_y=0;counter_y<4;counter_y++)
                if(pieces[blockType][rot_coordinate][counter_y][counter_x]!=0)
                {
                    filledRect(((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(horizontal-pivotX+counter_x),(screenHeight()-1)-blockSize*(boardHeight-(vertical-pivotY+counter_y)),((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(horizontal+counter_x-pivotX+1),(screenHeight()-1)-blockSize*(boardHeight-(vertical+counter_y-pivotY+1)),WHITE);
    
                    rect(((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(horizontal-pivotX+counter_x),(screenHeight()-1)-blockSize*(boardHeight-(vertical-pivotY+counter_y)),((screenWidth()-1)-boardWidth*blockSize)/2+blockSize*(horizontal+counter_x-pivotX+1),(screenHeight()-1)-blockSize*(boardHeight-(vertical+counter_y-pivotY+1)),BLUE);
                }
        updateScreen();
        return 1;
    }
    /* ###################################################################### */
    void groundSave(int horizontal, int vertical, int rot_coordinate, int blockType)/*memorizing blocks that hit the "ground"*/
    /* horizontal/vertical - current X/Y position of the falling block, rot_coordinate - initially 0, modified by player in 'anim' function by pressing SDLK_SPACE*/
    {
        /* looking for the position of the central module of the block */
        for(pivotX=0;pivotX<4;pivotX++)
            for(pivotY=0;pivotY<4;pivotY++)
                if(pieces[blockType][rot_coordinate][pivotY][pivotX]==2) 
    
        /*Update of the gamespace array*/
        for(counter_x=0;counter_x<4;counter_x++)
                for(counter_y=0;counter_y<4;counter_y++)
                if(pieces[blockType][rot_coordinate][counter_y][counter_x]!=0)
        /*saving new elements into the ground array*/
        gamespace[horizontal-pivotX+counter_x][vertical-pivotY+counter_y]=1;
    }
    /* ###################################################################### */
    int anim(int blockType)/*rotation and left/right/down movement(according to which key is pressed)*/
    /*returns 1 if the game cannot be continued; 0 otherwise*/
    {
        int KEY; /* KEY - variable being SDL code for the pressed button*/
        int vertical=1, /* current Y position of the block, set to 1(top of the gamespace)*/
        horizontal=boardWidth/2, /* current X position of the block(middle of the gamespace)*/
        rotation=0, /*rotational parameter of the block*/
        support; /* support - supporting counter of a loop */
        
        if(check(horizontal,vertical,rotation,blockType)==2) return 1;
        /*if satisfied, the gameover function is called*/
    
        while(1)
        {
            support=0;
            for (support=0;support<10;support++)
            {
                /* slowing down the loop execution */
                usleep(interval);
                /* the code of pressed button is ascribed to KEY */
                KEY=pollkey();
                switch (KEY)
                {
                    /* pressing space, rotation of the block */
                    case SDLK_SPACE:
                    /*checking if it is possible to rotate*/
                    if((rotation==3)&&(check(horizontal,vertical+1,0,blockType)==1))
                    {
                        rotation=0;
                    }
                    else if((rotation!=3)&&(check(horizontal,++vertical,++rotation,blockType)!=1))
                    {
                        rotation--;
                        vertical--;
                    }
                break;
                    /* pressing left arrow */
                    case SDLK_LEFT: if(check(--horizontal,vertical,rotation,blockType)!=1) horizontal++;
                break; 
                    /* pressing right arrow */
                    case SDLK_RIGHT: if(check(++horizontal,vertical,rotation,blockType)!=1) horizontal--;
                break;
                    /* pressing down arrow - moving the block down instantly, and performing groundSave */
                    case SDLK_DOWN:
                    while(check(horizontal,++vertical,rotation,blockType)==1);
                         groundSave(horizontal,--vertical,rotation,blockType);
                    return 0;
                break;
                    case SDLK_ESCAPE:
                    return 2;
                break;
                default:
                break;
                }
            if (support==9)
            {    /*when another move downwards isn't possible then it is saved by groundSave function*/
                if(check(horizontal,++vertical,rotation,blockType)==2)
                {
                    groundSave(horizontal,--vertical,rotation,blockType);
                    return 0;
                }
              }
            }
        }
        return 0;
    }
    /* ###################################################################### */
    void check_delete(void) /*removing a row that is full*/
    {
        /*decreaseX - support X-direction counter*/
        /*decreaseY - support Y-direction counter*/
        int decreaseX,decreaseY;
        /* checks if any row is not full */
        for(counter_y=1;counter_y<boardHeight;counter_y++)
        {
            for(counter_x=0;counter_x<boardWidth;counter_x++)
            {
                if(gamespace[counter_x][counter_y]==0) break;
            }
    
            /* modifying the gamespace array so that the data of any visible FULL row are substituted by the data of the one-above row and re-drawn immediately on the screen*/
            if(counter_x==boardWidth)
            {
                for(decreaseY=counter_y;decreaseY>=0;decreaseY--)/*going through Y to the top*/
                    for(decreaseX=0;decreaseX<boardWidth;decreaseX++)
                        if(decreaseY!=0)
                            gamespace[decreaseX][decreaseY]=gamespace[decreaseX][decreaseY-1];
                        else
                            gamespace[decreaseX][decreaseY]=0;
            }
        }
    }
    /* ###################################################################### */
    void gameover(void) /*when block reaches the top line of the gamespace, ends loop execution and displays GAME OVER */
    {
        filledRect(0,0,screenWidth()-1,screenHeight()-1,BLACK);
        textout(250,100,"GAME OVER",WHITE);
        updateScreen();
        getkey();
    }
    /* ###################################################################### */

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
            if(anim(blockType)==1)
            {
                gameover();
                return 0;
            }else if(anim(blockType)==2)
    Well if you press escape, and return 2, then the first if will call anim(), but the if will fail, so it calls anim() again.

    Perhaps
    Code:
    result = anim(blockType);
    if ( result == 1 ) {
    } else if ( result == 2 ) {
    }
    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: 4
    Last Post: 07-16-2011, 06:08 PM
  2. Pressing a key to display a new bmp
    By batman123 in forum Game Programming
    Replies: 2
    Last Post: 01-10-2005, 05:08 PM
  3. Pressing A Button on Dos..
    By yakabod in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 01-30-2003, 07:46 AM
  4. How to tell when pressing escape?
    By Shadow12345 in forum C++ Programming
    Replies: 16
    Last Post: 05-25-2002, 07:24 AM
  5. Pressing a button in another app
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 03-11-2002, 12:53 PM