www.pudn.com > HGE_game_damo.rar > TetrisLogic.cpp


////  http://dotlive.cnblogs.com/  
// TetrisLogic.cpp: implementation of the TetrisLogic class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "TetrisLogic.h" 
#include  
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
TetrisLogic::TetrisLogic(IGameEngine* pGE):GameLogic(pGE) 
{ 
	byte nGameBoxCell[10][4][5][5]= 
	{ 
		{//id = 0 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 1 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{1,1,1,1,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{1,1,1,1,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 2 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,1,1,0,0}, 
				{0,1,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,1,1,0,0}, 
				{0,1,0,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 3 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,1,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,0,1,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,1,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,0,1,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 4 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,1,0}, 
				{0,1,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,1,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,1,0}, 
				{0,1,1,1,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 5 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,1,0}, 
				{0,0,0,1,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,1,0,0,0}, 
				{0,1,1,1,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,1,1,0}, 
				{0,0,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 6 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,1,1,1,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,1,1,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,1,1,1,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,1,1,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 7 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 8 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}  
		}, 
		{//id = 9 
			{//state =0 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =1 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =2 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}, 
			{//state =3 
				{0,0,0,0,0}, 
				{0,0,0,0,0}, 
				{0,0,1,0,0}, 
				{0,0,0,0,0}, 
				{0,0,0,0,0} 
			}  
		} 
	}; 
 
	memcpy(  (void*)m_nGameBoxCell, (void*)nGameBoxCell, 10*4*5*5 ); 
 
//	Init(); 
} 
 
TetrisLogic::~TetrisLogic() 
{ 
 
} 
 
INT TetrisLogic::GameStep( float fTimeEscape )  
{ 
	m_nLogicTimer = m_nLogicTimer>100000?m_nLogicTimer-100000:m_nLogicTimer ; 
	INT n = m_nLogicTimer/m_fFallingSpeed ; 
	m_nLogicTimer += fTimeEscape*1000; 
	INT n2 = m_nLogicTimer/m_fFallingSpeed ; 
	if ( n2>n ) 
	{ 
		GameInput(KeyDown,n2-n); 
	} 
	return 0; 
} 
 
int TetrisLogic::GetBoxCell(int nBoxid,int nState,int x,int y) 
{ 
	if (nBoxid>=0&&nBoxid<10 
		&&nState>=0&&nState<4 
		&&x>=0&&x<5 
		&&y>=0&&y<5 
		) 
	{ 
		return m_nGameBoxCell[nBoxid][nState][y][x]; 
	} 
	return -1; 
} 
 
BOOL TetrisLogic::TestHit(TetrisBox stTmpBox) 
{ 
	for (int x=0;x<5;x++) 
	{ 
		for (int y=0;y<5;y++) 
		{ 
			if (1==GetBoxCell(stTmpBox.m_nBoxID,stTmpBox.m_nState,x,y)) 
			{ 
				if (1==GameStage(stTmpBox.m_ptPosition.x+x-2,stTmpBox.m_ptPosition.y+y-2)) 
				{ 
					return TRUE; 
				} 
			} 
		} 
	} 
 
	return FALSE; 
} 
 
INT TetrisLogic::GameInput( INT nKeyCode ,int nStep)  
{ 
	TetrisBox tmpBox = m_stFallingBox; 
	switch(nKeyCode) 
	{ 
	case KeyTurn: 
		tmpBox.m_nState = (tmpBox.m_nState+1)%4; 
// 		tmpBox.m_nState = (tmpBox.m_nState+3)%4; 
		break; 
 	case KeyRight: 
		tmpBox.m_ptPosition.x ++; 
 		break; 
 	case KeyLeft: 
		tmpBox.m_ptPosition.x --; 
 		break; 
	case KeyDown: 
		tmpBox.m_ptPosition.y ++; 
		break; 
// 	case KeyDown: 
// 		break; 
	} 
 
	if (!TestHit(tmpBox)) 
	{ 
		m_stFallingBox = tmpBox; 
	} 
	else 
	{ 
		if (KeyDown == nKeyCode) 
		{ 
			BoxDone(); 
		} 
	} 
	 
	return 0;	 
} 
 
void TetrisLogic::BoxDone() 
{ 
	for (int x=0;x<5;x++) 
	{ 
		for (int y=0;y<5;y++) 
		{ 
			if (1 == GetBoxCell(m_stFallingBox.m_nBoxID,m_stFallingBox.m_nState, x, y )) 
			{ 
				int dx = m_stFallingBox.m_ptPosition.x+x-2; 
				int dy = m_stFallingBox.m_ptPosition.y+y-2; 
				if(dx<10&&dx>=0&&dy<30&&dy>=0) 
					m_nGameStage[dx][dy] = 1; 
			} 
		} 
	} 
	 
	//check record 
	CheckScore(); 
 
	//reset fallbox to next 
	//get next 
	m_stFallingBox = m_stNextBox; 
	m_stNextBox.m_nBoxID = GetRadomType(); 
 
	return; 
} 
 
void TetrisLogic::Init()  
{ 
	m_nLogicTimer = 0; 
	 
	m_stFallingBox.m_nBoxID = GetRadomType(); 
	m_stFallingBox.m_nState = 0; 
	m_stFallingBox.m_ptPosition.y = 0; 
	m_stFallingBox.m_ptPosition.x = 4; 
 
	m_stNextBox.m_nBoxID = GetRadomType(); 
	m_stNextBox.m_nState = 0; 
	m_stNextBox.m_ptPosition.y = 0; 
	m_stNextBox.m_ptPosition.x = 4; 
	 
	memset ( m_nGameStage, 0, 30*10* sizeof(byte) ); 
	 
	m_fFallingSpeed = 1000; 
	 
	m_nScore = 100; 
	 
} 
 
int TetrisLogic::GetRadomType()  
{ 
	return m_pGE->IGE_GetRandomInt(0,6); 
} 
 
byte TetrisLogic::GameStage( int x,int y ) const 
{ 
	if(x<10&&x>=0&&y<30&&y>=0) 
		return m_nGameStage[x][y]; 
	return 1; 
} 
 
void TetrisLogic::CheckScore()  
{ 
	int nV = 0; 
	int nF = 0; 
	int x,y; 
	int nFI[5] = {-1,-1,-1,-1,-1}; 
	for ( y=30-1;y>=0;y--) 
	{ 
		BOOL bFull = (1==m_nGameStage[0][y]); 
		BOOL bEmpty = !bFull; 
		for (x=1; (bFull || bEmpty) && x<10 ;x++) 
		{ 
			if (1!=m_nGameStage[x][y]) 
			{ 
				bFull = FALSE; 
			} 
			else 
			{ 
				bEmpty = FALSE; 
			} 
		} 
		 
		if (bEmpty) 
		{ 
			nV = y; 
			break; 
		} 
 
		if ( bFull ) 
		{ 
			nFI[nF] = y; 
			nF ++; 
		} 
	} 
 
	if (nF>0) 
	{ 
		int k = 1; 
		for (y=nFI[0]-1;y>nV;y--) 
		{ 
			if (y==nFI[k]) 
			{ 
				k++; 
			} 
			else 
			{ 
				for (x=0;x<10;x++) 
				{ 
					m_nGameStage[x][y+k]=m_nGameStage[x][y]; 
				} 
			} 
		} 
		for (;k>0;k--) 
		{ 
			for (x=0;x<10;x++) 
			{ 
				m_nGameStage[x][nV+k]=0; 
			} 
		} 
	} 
 
	m_nScore = m_nScore + nF*nF*100 + (nF-1)*10; 
} 
 
void TetrisLogic::PrintScore()  
{ 
	char str[50] = {0}; 
	sprintf(str,"Score:%20d", m_nScore); 
	m_pGE->IGE_DrawText(0,32,0xFFFF00FF,str); 
} 
 
void TetrisLogic::DrawLandEdge()  
{ 
	for(int x=-1;x<11;x++) 
	{ 
		m_pGE->IGE_DrawABoxCell(x,-1,0xffffff00,0); 
		m_pGE->IGE_DrawABoxCell(x,30,0xffffff00,0); 
	} 
	 
	for (int y=-1;y<31;y++) 
	{ 
		m_pGE->IGE_DrawABoxCell(-1,y,0xffffff00,0); 
		m_pGE->IGE_DrawABoxCell(10,y,0xffffff00,0); 
	} 
} 
 
void TetrisLogic::DrawLand()  
{ 
	for(int x=0;x<10;x++) 
	{ 
		for (int y=0;y<30;y++) 
		{ 
			if ( m_nGameStage[x][y]==1) 
			{ 
				m_pGE->IGE_DrawABoxCell(x,y,0xff00ff00,0); 
			} 
		} 
	} 
} 
 
void TetrisLogic::DrawBox()  
{ 
	TetrisBox stTmpBox = GetFallingBox(); 
	for (int x=0;x<5;x++) 
	{ 
		for (int y=0;y<5;y++) 
		{ 
			if (1==GetBoxCell(stTmpBox.m_nBoxID,stTmpBox.m_nState,x,y)) 
			{ 
				m_pGE->IGE_DrawABoxCell(stTmpBox.m_ptPosition.x+x-2,stTmpBox.m_ptPosition.y+y-2,0xff00ff00,0); 
			} 
		} 
	} 
} 
 
void TetrisLogic::DrawNextBox()  
{ 
	TetrisBox stTmpBox = m_stNextBox; 
	for (int x=0;x<5;x++) 
	{ 
		for (int y=0;y<5;y++) 
		{ 
			if (1==GetBoxCell(stTmpBox.m_nBoxID,stTmpBox.m_nState,x,y)) 
			{ 
				m_pGE->IGE_DrawABoxCell(15+x-2,5+y-2,0xff0000ff,0); 
			} 
		} 
	} 
} 
 
void TetrisLogic::Render()  
{ 
	DrawNextBox(); 
	DrawBox(); 
	DrawLand(); 
	DrawLandEdge(); 
	PrintScore(); 
}