Thread: Strange Problem with Tetris

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

    Strange Problem with Tetris

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<windows.h>
    
    #define blockSize 16
    #define blockSide 4
    #define numType 7
    #define scrW 80
    #define scrH 50
    #define boardW 40
    #define boardH 45
    #define HstartPos 21
    #define VstartPos 4
    #define Mid ((40-bLent[type])/2)
    
    int bType[28] = {6,10,14,15,10,11,14,15,7,11,14,15,10,13,14,15,9,10,14,15,10,11,13,14,3,7,11,15};
    int bLent[7] = {2,2,2,3,3,3,1};
    
    enum GameEvent {
         ESCAPE       = VK_ESCAPE,
         MOVE_LEFT    = VK_LEFT,
         MOVE_RIGHT   = VK_RIGHT,
         ROTATE       = VK_UP,
         DROP         = VK_DOWN,
         EMPTY
    };
    
    void SetConsole(void);
    void goTo(unsigned x,unsigned y);
    void wScr(void);
    void Tetris(void);
    void Menu(void);
    void RotateBlock(int *rBlock);
    void moveBlock(int *mBlock,unsigned *x,unsigned *y);
    void SaveGrid(int *Grid,int *Block,unsigned x,unsigned y);
    void PrintGrid(int *Grid);
    int dropBlock(int *mBlock,int *Grid,int type);
    int StopBlock(int *Block,unsigned x,unsigned y,int *Grid);
    unsigned ShiftRight(int *Block);
    unsigned ShiftBottom(int *Block);
    unsigned Control(unsigned *x,unsigned *y,int *Block,int *Grid);
    unsigned RotateIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
    unsigned MoveLeftIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
    unsigned MoveRightIsPossible(int *Block,int *Grid,unsigned x,unsigned y);
    unsigned get_Key(void);
    unsigned get_Left(int *Block);
    
    int main() {
        SetConsole();
        Menu();
        return 0;
    }
    
    void SetConsole(void) {
         HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
         SMALL_RECT Size = {0,0,scrW - 1,scrH - 1};
         COORD wSize = {scrW,scrH};
         CONSOLE_CURSOR_INFO inf;
         GetConsoleCursorInfo(hOut,&inf);
         inf.bVisible = FALSE;
         SetConsoleCursorInfo(hOut,&inf);
         SetConsoleTitle("Tetris Game");
         SetConsoleWindowInfo(hOut,TRUE,&Size);
         SetConsoleScreenBufferSize(hOut,wSize);
    }
    
    void goTo(unsigned x,unsigned y) {
         HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
         COORD Pos = { x - 1 , y - 1 };
         SetConsoleCursorPosition(hOut,Pos);
    }
    
    void wScr(void) {
         HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
         COORD Def = { 0 , 0 };
         CONSOLE_SCREEN_BUFFER_INFO csbi;
         DWORD count;
         GetConsoleScreenBufferInfo(hOut,&csbi);
         FillConsoleOutputCharacter(hOut,' ',csbi.dwSize.X*csbi.dwSize.Y,Def,&count);
         SetConsoleCursorPosition(hOut,Def);
    }
    
    unsigned key_hit(void) {
             int i;
             for(i=ESCAPE;i<EMPTY;++i) if(GetAsyncKeyState(i)) return i;
             return EMPTY;
    }
    
    unsigned ShiftRight(int *Block) {
             int i,j,temp;
             for(i=blockSide-1;i<blockSize;i+=blockSide) if(Block[i]) return 0;
             for(i=0;i<blockSide;++i) {
                 temp = Block[blockSide-1+(i*blockSide)];
                 for(j=blockSide-1+(i*blockSide);j>(i*blockSide);--j) {
                     Block[j] = Block[j-1];
                 }
                 Block[i*blockSide] = temp;
             }
             return 1;
    }
    
    unsigned ShiftBottom(int *Block) {
             int i,j,temp;
             for(i=(blockSize-blockSide);i<blockSize;++i) if(Block[i]) return 0;
             for(i=0;i<blockSide;++i) {
                 temp = Block[blockSize-blockSide+i];
                 for(j=(blockSize-blockSide+i);j>i;j-=blockSide) {
                     Block[j] = Block[j-blockSide];
                 }
                 Block[i] = temp;
             }
             return 1;
    }
    
    void RotateBlock(int *rBlock) {
         int i,j,type;
         int *temp = (int*) calloc(blockSize,sizeof(int));
         for(i=0;!rBlock[i];++i);
         type = rBlock[i];
         for(i=0;i<blockSize;++i) {
             temp[i] = rBlock[i];
             rBlock[i] = 0;
         }
         for(i=0;i<blockSide;++i) {
             for(j=0;j<blockSide;++j) {
                 if(temp[(i*blockSide)+j]) rBlock[(3-j)*blockSide+i] = type;
             }
         }
         while(ShiftBottom(rBlock));
         while(ShiftRight(rBlock));
         free(temp);
    }
    
    unsigned get_Left(int *Block) {
             unsigned i,j;
             for(i=0;i<blockSide;++i) {
                 for(j=0;j<blockSide;++j) {
                     if(Block[(j*blockSide)+i]) break;
                 }
                 if(j!=blockSide) return i;
             }
             return 0;         
    }
    
    unsigned RotateIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
             unsigned i,j,pos = 1,*temp;
                  temp = (int*) calloc(blockSize,sizeof(int));
                  for(i=0;i<blockSize;++i) temp[i] = Block[i];
                  RotateBlock(temp);
                  for(i=0;i<blockSide;++i) {
                      for(j=0;j<blockSide;++j) {
                          if((temp[(j*blockSide)+i] && x + i < 21) || 
                             (temp[(j*blockSide)+i] && Grid[x+i-HstartPos+(y-6+j)*boardW])) {
                              pos = 0;
                          }
                      }
                  }
                  free(temp);
             return pos;
    }
    
    unsigned MoveLeftIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
             unsigned i,j;
             for(i=0;i<blockSide;++i) {
                 for(j=0;j<blockSide;++j) {
                     if(Block[(j*blockSide)+i]) break;
                 }
                 if(j!=blockSide) break;
             }
             for(j=0;j<blockSide;++j) {
                 if(Block[(j*blockSide)+i] && Grid[x+i-1-HstartPos+(y-6+j)*boardW]) return 0;
             }
             return 1;
    }
    
    unsigned MoveRightIsPossible(int *Block,int *Grid,unsigned x,unsigned y) {
             unsigned i;
             for(i=0;i<blockSide;++i) {
                 if(Block[(i*blockSide)+3] && Grid[x+blockSide-HstartPos+(y-6+i)*boardW]) return 0;
             }
             return 1;
    }
    
    unsigned Control(unsigned *x,unsigned *y,int *Block,int *Grid) {
         switch(key_hit()) {
             case VK_LEFT    : if( *x > (HstartPos - get_Left(Block)   ) && MoveLeftIsPossible(Block,Grid,*x,*y )) (*x)--;
                               break;
             case VK_RIGHT   : if( *x < (HstartPos + boardW - blockSide) && MoveRightIsPossible(Block,Grid,*x,*y)) (*x)++;
                               break;
             case VK_UP      : if(RotateIsPossible(Block,Grid,*x,*y)) RotateBlock(Block);
                               break;
             case VK_DOWN    :
                               break;
             case VK_ESCAPE  : return 0;
         }
         return 1;
    }
    
    void moveBlock(int *mBlock,unsigned *x,unsigned *y) {
         unsigned i,j;
         for(i=0;i<blockSide;++i) {
             for(j=0;j<blockSide;++j) {
                 if(mBlock[(i*blockSide)+j]) {
                     goTo((*x)+j,(*y)+i);
                     putc('X',stdout);
                 }
             }
         }
         Sleep(100);
         for(i=0;i<blockSide;++i) {
             for(j=0;j<blockSide;++j) {
                 if(mBlock[(i*blockSide)+j]) {
                     goTo((*x)+j,(*y)+i);
                     putc(' ',stdout);
                 }
             }
         }
    }
    
    void SaveGrid(int *Grid,int *Block,unsigned x,unsigned y) {
         unsigned i,j;
         for(i=0;i<blockSide;++i) {
             for(j=0;j<blockSide;++j) {
                 if(Block[(i*blockSide)+j]) Grid[x+j-HstartPos+(y-6+i)*boardW] = 1;
             }
         }
    }
    
    int StopBlock(int *Block,unsigned x,unsigned y,int *Grid) {
         unsigned i,j;
         for(i=0;i<blockSide;++i) {
             for(j=0;j<blockSide;++j) {
                 if(Block[(i*blockSide)+j] && Grid[x+j-HstartPos+(y-6+i+1)*boardW]) return 1; 
             }
         }
         return 0;
    }
    
    int dropBlock(int *mBlock,int *Grid,int type) {
         unsigned x = HstartPos + Mid - 1,y = VstartPos,i;     
         do {
             if(!Control(&x,&y,mBlock,Grid)) {
                 free(mBlock);
                 return 0;
             }
             if(StopBlock(mBlock,x,y,Grid)) break;
             moveBlock(mBlock,&x,&y);
         } while(y++!=scrH-VstartPos);
         SaveGrid(Grid,mBlock,x,y);
         free(mBlock);
         return 1;
    }
    
    void PrintGrid(int *Grid) {
         unsigned i,j;
         for(i=0;i<boardH;++i) {
             for(j=0;j<boardW;++j) {
                 if(Grid[(i*boardW)+j]) {
                     goTo(HstartPos+j,i+VstartPos+1);
                     printf("X");
                 }
             }
         }
    }
    
    void Tetris(void) {
        int *tBlock,type,i,j=0;
        int *Grid = (int*) calloc(boardH*boardW,sizeof(int));
        do {
            PrintGrid(Grid);
            type = rand() % 7;
            tBlock = (int*) calloc(blockSize,sizeof(int));
            for(i=(blockSide*type);i<(blockSide+(blockSide*type));++i) tBlock[bType[i]] = type;
        } while(dropBlock(tBlock,Grid,type));
        free(Grid);
    }
    
    void Menu(void) {
        int i;
        for(i=0;i<50;++i) {
            goTo(20,i+1);
            printf("=");
            goTo(61,i+1);
            printf("=");
        }
        for(i=0;i<40;++i) {
            goTo(21+i,50);
            printf("=");
        }
        Tetris();    
    }
    Hey guys, have a look at this program.
    This is a tetris game and it works, but there's something very strange when the game loops. The falling blocks will be sometimes delayed and then continue to fall again.
    This will happen all time and I don't know what caused it.
    Can someone tell me me how to fix it?

  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
    > Sleep(100);
    Sleep() only guarantees a minimum time period, not a maximum. You might occasionally find it sleeping for much longer.

    > int *Grid = (int*) calloc(boardH*boardW,sizeof(int));
    There's a lot of this going on, are you sure you're not leaking menory (use task manager / process explorer to watch your processes memory use).
    If you're leaking memory, you'll occasionally get the OS involved in some pretty heavy work.
    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. Strange problem with GETLINE
    By wco5002 in forum C++ Programming
    Replies: 13
    Last Post: 07-07-2008, 09:57 AM
  2. Strange problem
    By G4B3 in forum C Programming
    Replies: 6
    Last Post: 05-14-2008, 02:07 PM
  3. Strange problem with classes in header files
    By samGwilliam in forum C++ Programming
    Replies: 2
    Last Post: 02-29-2008, 04:55 AM
  4. Strange problem
    By ~Kyo~ in forum Game Programming
    Replies: 0
    Last Post: 02-14-2006, 10:35 PM