Click here to Skip to main content
15,895,471 members
Articles / Multimedia / DirectX

Falling Blocks

Rate me:
Please Sign up or sign in to vote.
4.95/5 (11 votes)
17 Apr 2008CPOL 271.3K   9.2K   72  
A game written using Visual C++ and DirectX.
// BlockList.cpp: implementation of the CBlockList class.
//
//////////////////////////////////////////////////////////////////////

#include <windows.h>
#include <assert.h>
#include "BlockList.h"

extern void DisplayBlock(SBlock Block);
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBlockList::SNODE::SNODE() 
{
	pNext = NULL;
}

CBlockList::CBlockList()
{
	// Add a dummy to avoid checking Head Null condition.
	m_pListHead = new SNODE;
	if (m_pListHead == NULL) {
		OutputDebugString("CBlockList::CBlockList():Memory allocation failed\n");
		return ;
	}
	m_pListHead->Block.nX = m_pListHead->Block.nY = 0;
}

CBlockList::~CBlockList()
{
	SNODE* pCurr = m_pListHead;
	while (m_pListHead) {
		m_pListHead = m_pListHead->pNext;
		delete pCurr;
		pCurr = m_pListHead;
	}
}

//////////////////////////////////////////////////////////////////////
//   Insert Block in order of the X coordinate so that it will be 
//   easy to detect complete lines of block for later removal.
//////////////////////////////////////////////////////////////////////
bool CBlockList::Insert(const SBlock Block)
{
	SNODE* pCurr=m_pListHead->pNext;
	SNODE* pPrev=m_pListHead;
	SNODE* pInsertNode = new SNODE;
	if (pInsertNode == NULL) {
		OutputDebugString("bool CBlockList::Insert(SBlock Block):Memory allocation failed\n");
		return false;
	}
	pInsertNode->Block=Block;
	
	//Traverse the list and check if there is any block in given row
	while (pCurr && Block.nY != pCurr->Block.nY && Block.nY > pCurr->Block.nY) {
		pPrev=pCurr;
		pCurr = pCurr->pNext;
	}
	
	if (pCurr && Block.nY == pCurr->Block.nY) {  // There are block in the given row
		while (pCurr && Block.nY == pCurr->Block.nY && Block.nX > pCurr->Block.nX) {
			
			pPrev=pCurr;
			pCurr = pCurr->pNext;
		}
		
		// Two blocks cannot have the same coordinates
		if (pCurr)
			assert(!((pCurr->Block.nX == Block.nX) && (pCurr->Block.nY == Block.nY)));  
		
		pPrev->pNext = pInsertNode;
		pInsertNode->pNext = pCurr;
	} 
	else {
		pPrev->pNext = pInsertNode;
		pInsertNode->pNext = pCurr;
		
	}
	return true;
}

//////////////////////////////////////////////////////////////////////
//   Traverse the list and dump all the blocks to the debugger
//////////////////////////////////////////////////////////////////////
void CBlockList::dbgDisplay()
{
	SNODE* pCurr = m_pListHead->pNext;
	while (pCurr) {
		short nCurrY = pCurr->Block.nY;
		while (pCurr && nCurrY == pCurr->Block.nY) {
			char szMsg[100];
			wsprintf(szMsg,"[X:%02d,Y:%02d]",pCurr->Block.nX, pCurr->Block.nY);
			OutputDebugString(szMsg);
			pCurr=pCurr->pNext;
		}
		OutputDebugString("\n");
	}
}

//////////////////////////////////////////////////////////////////////
//  Adds the Block to the end of the list
//  Useful for the Shape where inserting it in order will
//  loose the block around which the rotation is based.
//  Rotation is based around the given block number
//////////////////////////////////////////////////////////////////////
bool CBlockList::Add(const SBlock Block)
{
	SNODE* pCurr = m_pListHead;
	while (pCurr->pNext)
		pCurr= pCurr->pNext;
	pCurr->pNext = new SNODE;
	if (pCurr->pNext == NULL)
		return false;
	pCurr->pNext->Block=Block;
	return true;
}

////////////////////////////////////////////////////////
// Display call the global Display defined in Main code
// to render the blocks
///////////////////////////////////////////////////////
void CBlockList::Display(short nX, short nY)
{
	SNODE* pCurr = m_pListHead->pNext;
	while (pCurr) {
		SBlock Block = pCurr->Block;
		Block.nX += nX;
		Block.nY += nY;
		::DisplayBlock(Block);
		pCurr= pCurr->pNext;
	};
}

////////////////////////////////////////////////////////
// Returns true if the give location already 
// contains a block
///////////////////////////////////////////////////////
bool CBlockList::IsOccupied(short nX, short nY)
{
	SNODE* pCurr= m_pListHead->pNext;
	while (pCurr) {
		if (pCurr->Block.nX == nX && pCurr->Block.nY == nY) 
			return true;
		pCurr = pCurr->pNext;
	}
	return false;
}


////////////////////////////////////////////////////
// Free all the nodes in the list.
////////////////////////////////////////////////////
void CBlockList::Destroy()
{
	SNODE* pCurr = m_pListHead->pNext;
	m_pListHead->pNext = NULL;
	while (pCurr) {
		SNODE* pDel = pCurr;
		pCurr= pCurr->pNext;
		delete pDel;
	};
}





By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions