Problem with Loops!

I am developing a Tetris Game as my OOP Project using Win32 SDK .
The problem i am facing is that first of all the game just takes up all of the CPU and after 1-2 mins its just gets Stuck...........I have checked the loops but they cant be wrong as they seem to work fine for the first 3-5 iterations but then suddenly the game gets stuck

The code is as follows :



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CODE
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream.h>
#include <windows.h>
#include "Resource.h"

HWND hwnd;
HDC dc,memDC;
HBITMAP MainBMP;
HINSTANCE hInst;
int MAX_X=23,MAX_Y=27;

CONST ID_TIMER=1;
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////

class Block
{
private:
      bool block[4][4];
      int x,y;
      int maxX;
public:
      Block();
      Block(int type);
      Block(int type,int xc,int yc);
      int getX();
      void setX(int xc);
      int getY();
      void setY(int yc);
      void setBlockType(int type);
      void Rotate();
      void Draw(int xc,int yc);
      void fillZeros();
      void Print();
      void moveLeft();
      void moveRight();
      void moveDown();
      void setIndex(int i,int j,bool k);
      bool getIndex(int i,int j);
      int getMaxX();
};

int Block::getMaxX()
{
return maxX;
}
void Block::setIndex(int i,int j,bool k)
{
      block[i][j]=k;
}
bool Block::getIndex(int i,int j)
{
      return block[i][j];
}

void Block::moveLeft()
{
      if(x>0)
      x--;
}
void Block::moveRight()
{
      if(x<(23-maxX))
      x++;
}
void Block::moveDown()
{
      if(y<23)
      y++;
}

void Block::Rotate()
{
      bool temp[4][4];
      
      for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            {
                  temp[j][3-i]=block[i][j];
            }
            for(i=0;i<4;i++)
                  for(int j=0;j<4;j++)
                        block[i][j]=temp[i][j];
}

Block::Block(int type,int xc,int yc)
{
      x=xc;
      y=yc;
      fillZeros();
      setBlockType(type);
}

Block::Block(int type)
{
      x=0;y=0;
      fillZeros();
      setBlockType(type);
}

void Block::setBlockType(int type)
{
      fillZeros();
      switch(type)
      {
      case 1:
            block[2][0]=1;
            block[2][1]=1;
            block[3][0]=1;
            block[3][1]=1;
            maxX=2;
            break;
      case 2:
            block[3][0]=1;
            maxX=1;
            break;
      case 3:
            block[0][0]=1;
            block[0][1]=1;
            block[0][2]=1;
            block[1][1]=1;
            block[2][1]=1;
            block[3][1]=1;
            maxX=3;
            break;
      case 4:
            *(*(block+0)+0)=1;
            *(*(block+1)+0)=1;
            *(*(block+2)+0)=1;
            
            *(*(block+0)+1)=1;
            break;
      case 5:
            *(*(block+0)+2)=1;
            *(*(block+1)+2)=1;
            *(*(block+2)+2)=1;
            
            *(*(block+0)+1)=1;
            
            break;
      case 6:
            *(*(block+1)+1)=1;
            *(*(block+1)+2)=1;
            
            *(*(block+2)+2)=1;
            break;
      case 7:
            *(*(block+1)+0)=1;
            *(*(block+1)+1)=1;
            *(*(block+1)+2)=1;
            
            *(*(block+0)+1)=1;
            *(*(block+2)+1)=1;
            break;
      case 8:
            *(*(block+2)+0)=1;
            *(*(block+2)+1)=1;
            *(*(block+2)+2)=1;
            
            *(*(block+0)+1)=1;
            *(*(block+1)+1)=1;
            break;
      case 9:
            *(*(block+0)+0)=1;
            *(*(block+0)+1)=1;
            *(*(block+0)+2)=1;
            
            *(*(block+1)+1)=1;
            *(*(block+2)+1)=1;
            break;
      case 10:
            block[1][1]=1;
            block[1][2]=1;
            block[2][1]=1;
            block[2][2]=1;
            break;
      }
      
}

Block::Block()
{
      x=0;
      y=0;
      fillZeros();
      setBlockType(1);
      
}

void Block::fillZeros()
{
      for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            {
                  block[i][j]=0;
            }
}

void Block::Print()
{
      cout<<"Position : ("<<x<<","<<y<<")"<<endl;;
      for(int i=0;i<4;i++)
      {
            for(int j=0;j<4;j++)
            {
                  cout<<*(*(block+i)+j)<<" ";
            }
            cout<<endl;
      }
}

int Block::getX()
{
      return x;
}

void Block::setX(int xc)
{
      x=xc;
}

int Block::getY()
{
      return y;
}

void Block::setY(int yc)
{
      y=yc;
}


class Maze
{
private:
      int **maze;
      int len,wid;
public:
      Maze();
      Maze(int length,int width);
      void fillZeros();
      void Print();
      void setIndex(int,int,int);
      int getIndex(int,int);
      void insertBlock(Block b);
      void deleteRow(int n);
};

void Maze::deleteRow(int n)
{
      for(int i=n;i>0;i--)
            for(int j=0;j<23;j++)
            {
            setIndex(j,i,getIndex(j,i-1));
            }

}

void Maze::insertBlock(Block block)
{
int x=block.getX();
int y=block.getY();

for(int i=0;i<4;i++)
      for(int j=0;j<4;j++)
      {
      setIndex(x+j,y+i,block.getIndex(i,j));
      }

}
Maze::Maze()
{
      len=25;
      wid=10;
      maze=new int*[len];
      for(int i=0;i<len;i++)
            *(maze+i)=new int[wid];
      fillZeros();
}


Maze::Maze(int length,int width)
{
      len=length;
      wid=width;
      maze=new int*[len];
      for(int i=0;i<len;i++)
            *(maze+i)=new int[wid];
      
      fillZeros();
}

void Maze::Print()
{
      for(int i=0;i<len;i++)
      {
            for(int j=0;j<wid;j++)
            {
                  cout<<*(*(maze+i)+j)<<" ";
            }
            cout<<endl;
      }
}
void Maze::fillZeros()
{
      for(int i=0;i<len;i++)
            for(int j=0;j<wid;j++)
            {
                  *(*(maze+i)+j)=0;
            }
}

void Maze::setIndex(int r,int c,int v)
{
      *(*(maze+r)+c)=v;
}
int Maze::getIndex(int r,int c)
{
      return *(*(maze+r)+c);
}


class Tetris
{
private:
      Maze tetrisMaze;
      Block currentBlock;
      Block nextBlock;
      int state;
public:
      Tetris();
      generateRandomBlock();
      void Main();
      void Game(int param);
      void Run(int state,int param);
      void sendMessage(int mess);
      void checkHit();
      void setState(int st);
      int getState();
      
      
};

void Tetris::setState(int st)
{
state=st;
}
int Tetris::getState()
{
return state;
}
      
void Tetris::checkHit()
{
int check=1;
for(int i=0;i<27;i++)
{
      for(int j=0;j<23;j++)
      {
      if(tetrisMaze.getIndex(j,i)==0)
            {
            check=0;
            break;
            }
            else
            {
            check=1;
            }
      }
      if(check==1)
            {
            tetrisMaze.deleteRow(i);            
            }
      
}

}
// Key=1 for Space (ASCII-32)
// Key=2 for Left (ASCII-37)
// Key=3 for Right (ASCII-39)
// Key=4 for Down (ASCII-40)
// Key=5 For ESC (ASCII-27)
void Tetris::sendMessage(int mess)
{
      switch(mess)
      {
      case 1:
            currentBlock.Rotate();
            break;
      case 2:
            currentBlock.moveLeft();
            break;
      case 3:
            currentBlock.moveRight();
            break;
      case 4:
            currentBlock.moveDown();
            break;
      case 5:
            break;
            
      }
}


Tetris::Tetris():tetrisMaze(23,27),currentBlock(1,0,0)
{
      
      //for(int i=0;i<23;i++)
      //      for(int j=22;j<27;j++)
      //            tetrisMaze.setIndex(i,j,1);
}
HDC          hdcMem;
HBITMAP      hbmMem;
HANDLE       hOld;

PAINTSTRUCT  ps;
HDC          hdc;

      int tx=0,ty=0;
void Tetris::Game(int param)
{
      MainBMP=LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP2));
      memDC=CreateCompatibleDC(dc);
      SelectObject(memDC, MainBMP);
      
      hdc=GetDC(hwnd);

      hdcMem = CreateCompatibleDC(hdc);
    hbmMem = CreateCompatibleBitmap(hdc,530, 620);
    hOld   = SelectObject(hdcMem, hbmMem);
      
      BitBlt(hdcMem,0,0,530,620,memDC,0,0,SRCCOPY);

      MainBMP=LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP3));
      memDC=CreateCompatibleDC(dc);
      SelectObject(memDC, MainBMP);


      
      // Draw Moving Block
      for(int i=0;i<4;i++)
            for(int j=0;j<4;j++)
            {
                  if(currentBlock.getIndex(i,j)==1)
                  {
                        tx=j*20+30+(currentBlock.getX()*20);
                        ty=i*20+30+(currentBlock.getY()*20) ;
                        BitBlt(hdcMem,tx,ty,20,20,memDC,0,0,SRCCOPY);
                  }
            }
      // End drawring Moving Box
            
      // Draw Boxes overlay
            for(i=0;i<MAX_Y;i++)
                  for(int j=0;j<MAX_X;j++)
                  {
                        if(tetrisMaze.getIndex(j,i)==1)
                        {
                              tx=j*20+30;
                              ty=i*20+30;
                              BitBlt(hdcMem,tx,ty,20,20,memDC,0,0,SRCCOPY);
                        }
                  }
      // End Drawing Boxes Overlay
                  
      
      BitBlt(hdc, 0, 0,530,620, hdcMem, 0, 0, SRCCOPY);
      DeleteDC(memDC);
      DeleteDC(hdc);
      DeleteDC(hdcMem);
      ReleaseDC(hwnd,hdc);
      
      // Move Block
      if(param==1)
      {
            if(currentBlock.getY()<23)
                  currentBlock.setY(currentBlock.getY()+1);
             else
             {
                   tetrisMaze.insertBlock(currentBlock);
                   currentBlock.setX(0);
                   currentBlock.setY(0);
             }
      }
      // End Moving block
      checkHit();
                  
}

void Tetris::Main()
{
      
      dc=GetDC(hwnd);
      MainBMP=LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
      memDC=CreateCompatibleDC(dc);
      SelectObject(memDC, MainBMP);
      BitBlt(dc, 1, 1, 600, 600, memDC, 0, 0, SRCCOPY);
      DeleteDC(memDC);
      
}

void Tetris::Run(int state,int param)
{
      switch(state)
      {
      case 1:
            Main();
            break;
      case 2:
            Game(param);
            break;
      }
}

Tetris tetris;

LRESULT CALLBACK WndProc(HWND hWnd , UINT message , WPARAM wParam , LPARAM lParam)
{
      int virtual_code=0;
      int state=0;
      int xPos = LOWORD(lParam);  // horizontal position of cursor
      int yPos = HIWORD(lParam);  // vertical position of cursor
      switch(message){
            
      case WM_KEYUP:
      
            virtual_code = (int)wParam;
            // Key=1 for Space (ASCII-32)
            // Key=2 for Left (ASCII-37)
            // Key=3 for Right (ASCII-39)
            // Key=4 for Down (ASCII-40)
            // Key=5 For ESC (ASCII-27)

            switch(wParam)
            {
            case VK_SPACE:
                  tetris.sendMessage(1);
                  SendMessage(hwnd,WM_PAINT,0,0);
                  break;
            case VK_LEFT:
                  tetris.sendMessage(2);
                  SendMessage(hwnd,WM_PAINT,0,0);
                  break;
            case VK_RIGHT:
                  tetris.sendMessage(3);
                  SendMessage(hwnd,WM_PAINT,0,0);
                  break;
            case VK_DOWN:
                  tetris.sendMessage(4);
                  SendMessage(hwnd,WM_PAINT,0,0);
                  break;
            case VK_ESCAPE:
                  tetris.sendMessage(5);
                  break;
                  
            }
            return 0;
            break;
            case WM_ERASEBKGND:
                  return 1;
                  break;
            case WM_PAINT:
                  state=tetris.getState();
                  switch(state)
                  {
                  case 1:
                        tetris.Main();
                        break;
                  case 2:
                        tetris.Game(1);
                        break;
                  case 3:
                        MessageBox(hwnd,"Thank you for Playing!","TetriX",1);
                        exit(0);
                        break;      
                  }
                  break;
                  case WM_CLOSE:
                        PostQuitMessage(0);
                        return 0;
                        
                  case WM_LBUTTONUP:
                        
                        if((xPos>190&&xPos<325)&&(yPos>345&&yPos<380))
                        {
                              MessageBox(hwnd,"Start Game!","TetRiX",0);
                              tetris.setState(2);
                        }
                        if((xPos>190&&xPos<325)&&(yPos>396&&yPos<432))
                        {
                              MessageBox(hwnd,"TetriX!\nProject of OOP!","TetRiX",0);
                        }
                        if((xPos>212&&xPos<310)&&(yPos>450&&yPos<486))
                        {
                              MessageBox(hwnd,"Bubyez!","TetRiX",0);
                              exit(0);
                        }
                        
                        break;
                  
                  case WM_TIMER:
                  SendMessage(hwnd,WM_PAINT,1,1);      
                  break;
                  /*state=tetris.getState();
                        switch(state)
                        {
                        case 1:
                              tetris.Main();
                              break;
                        case 2:
                              tetris.Game(1);
                              //SendMessage(hwnd,WM_PAINT,1,1);
                              break;
                        case 3:
                              MessageBox(hwnd,"Thank you for Playing!","TetriX",1);
                              exit(0);
                              break;      
                        }
                        break;
                        */
                        
      }
    return DefWindowProc(hWnd,message,wParam,lParam);
}

///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

INT WINAPI WinMain( HINSTANCE hinst, HINSTANCE hint, LPSTR lp, INT i)
{
      
      int ret=0;
      // Create A Window Class Structure
      WNDCLASSEX wc;
      wc.cbClsExtra = 0;
      wc.cbSize = sizeof(wc);
      wc.cbWndExtra = 0;
      wc.hbrBackground = NULL;
      wc.hCursor = NULL;
      wc.hIcon = NULL;
      wc.hIconSm = NULL;
      wc.hInstance = GetModuleHandle(NULL);
      wc.lpfnWndProc = WndProc;
      wc.lpszClassName = "VK3D";
      wc.lpszMenuName = NULL;
      wc.style = CS_VREDRAW|CS_HREDRAW|CS_OWNDC;
      hInst=hinst;
            tetris.setState(1);
              // Register Window Class
              RegisterClassEx(&wc);
              // Create Window
              HWND hWnd = CreateWindowEx(0,"VK3D","TetriX",WS_OVERLAPPEDWINDOW, 0,0,530,620,NULL,NULL,wc.hInstance,0);
              hwnd = hWnd;
              ShowWindow(hWnd,SW_SHOW);
              // Message Loop
              MSG msg;
              ret=SetTimer(hwnd,ID_TIMER, 100,NULL);
              while(true){
                    if(PeekMessage(&msg,hWnd,0,0,PM_REMOVE)){
                          if(msg.message==WM_QUIT)break;
                          TranslateMessage(&msg);
                          DispatchMessage(&msg);
                         
                    }
              }
             
              return 0;
}

Hope u can help me.........
hauntedfuryAsked:
Who is Participating?
 
furqanchandioCommented:
hi

game getting stuck appears to be memory problems


void Tetris::Main()
{
     
==>     dc=GetDC(hwnd);
     MainBMP=LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1));
     memDC=CreateCompatibleDC(dc);
     SelectObject(memDC, MainBMP);
     BitBlt(dc, 1, 1, 600, 600, memDC, 0, 0, SRCCOPY);
     DeleteDC(memDC);
     
}


where r u releasing this context  i have pointed out by arrow

_____________________
yes i would like to add you cant call this game tetris because anything that ends with "tris" is a trademark of Tetris


0
 
PaulCaswellCommented:
Can I suggest you break Game into two, one to redraw that is called on the WM_PAINT message and one to actually do the intelligence that is done on timer. I'd suspect that posting a WM_PAINT message on timer to achieve this will break just as you describe or at least get you into deep kaka later down the line. This method is clearly a hack that should be removed at the earliest opportunity.

I'd also suggest you post a link to this question in the Games arena.

Paul
0
 
waysideCommented:
No comment has been added to this question in more than 21 days, so it is now classified as abandoned..
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: furqanchandio

Any objections should be posted here in the next 4 days. After that time, the question will be closed.

wayside
EE Cleanup Volunteer
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.