?
Solved

Problem with Loops!

Posted on 2005-05-08
4
Medium Priority
?
293 Views
Last Modified: 2010-04-01
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.........
0
Comment
Question by:hauntedfury
3 Comments
 
LVL 4

Accepted Solution

by:
furqanchandio earned 2000 total points
ID: 13953246
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
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 13985219
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
 
LVL 14

Expert Comment

by:wayside
ID: 15622406
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

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question