Page 1 of 1

'Tetris' source code

Posted: Sat Feb 14, 2004 3:59 pm
by Mit
Heres a simple tetris game i knocked out recently .. It isnt complete (no scores, no game over, only one piece) and has a few lil bugs in it, but some of ya might find it interesting/useful to look thru.. I'll finish it up properly and include it in the arcade.dll sometime soon.

(Total coding time : 22 minutes. I actually timed it :) ) (And amazingly some ppl on the web actually charge for the source code!! )

Code: Select all


// 'Tetris' Arcade game.code by Mit

#include <Windows.h>

extern "C"
{

#include <StandardDef.h>
#include "Interface.h"
#include "Tetris.h"
}

#define		TETRIS_PIECE_ROWS		3
#define		TETRIS_PIECE_COLS		3

#define		TETRIS_BOX_HEIGHT		210
#define		TETRIS_BOX_ROWS			15
#define		TETRIS_BLOCK_HEIGHT		(TETRIS_BOX_HEIGHT/TETRIS_BOX_ROWS)

#define		TETRIS_BOX_WIDTH		200
#define		TETRIS_BOX_COLS			8
#define		TETRIS_BLOCK_WIDTH		(TETRIS_BOX_WIDTH/TETRIS_BOX_COLS)

#define		TETRIS_BLOCK_SPOTS		(TETRIS_BOX_COLS*TETRIS_BOX_ROWS)

int		mnBlocksBoxX = 100;			// Top left screen coord of the playing region
int		mnBlocksBoxY = 20;

BYTE	mabTetrisSpots[TETRIS_BOX_ROWS][ TETRIS_BOX_COLS ];

BYTE	mabCurrentBlockShape[TETRIS_PIECE_ROWS][TETRIS_PIECE_COLS];

int		mnCurrentBlockPosX = 4;
int		mnCurrentBlockPosY = 1;
ulong	mulNextMovePieceTime = 0;
ulong	mulMoveDelayTime = 1000;
ulong	mulNormalMoveDelayTime = 1000;


//-------------------------------------------------
// Function : TetrisCanMoveTo
//   Checks that a position is valid for the current piece
//-------------------------------------------------
BOOL TetrisCanMoveTo( int nMoveToX, int nMoveToY )
{
int		nX, nY;
int		nPieceX, nPieceY;

	nX = nMoveToX - 1;
	nY = nMoveToY - 1;
	
	for ( nPieceY = 0; nPieceY < 3; nPieceY++ )
	{
		for ( nPieceX = 0; nPieceX < 3; nPieceX++ )
		{
			if ( mabCurrentBlockShape[ nPieceY ][ nPieceX ] )
			{
				if ( ( (nY + nPieceY) >= TETRIS_BOX_ROWS ) ||
					 ( (nX + nPieceX) >= TETRIS_BOX_COLS ) ||
					 ( (nX + nPieceX) < 0 ) ||
					 ( (nY + nPieceY) < 0 ) )
				{
					return( FALSE );
				}
				if ( mabTetrisSpots[ nY + nPieceY ][ nX + nPieceX ] != 0 )
				{
					return( FALSE );
				}
			}
		}
	}
	return( TRUE );
}

//-------------------------------------------------
// Function : TetrisRotatePiece
//   Rotates the current piece
//-------------------------------------------------
void TetrisRotatePiece( void )
{
BYTE	mabCopyShape[TETRIS_PIECE_ROWS][TETRIS_PIECE_COLS];

	memcpy( &mabCopyShape[0][0], &mabCurrentBlockShape[0][0], TETRIS_PIECE_ROWS*TETRIS_PIECE_COLS*sizeof(BYTE) );
	// Fun fun.. manually change the position of the blockparts to rotate it
	mabCurrentBlockShape[0][0] = mabCopyShape[2][0];
	mabCurrentBlockShape[0][1] = mabCopyShape[1][0];
	mabCurrentBlockShape[0][2] = mabCopyShape[0][0];
	mabCurrentBlockShape[1][0] = mabCopyShape[2][1];
	mabCurrentBlockShape[1][1] = mabCopyShape[1][1];
	mabCurrentBlockShape[1][2] = mabCopyShape[0][1];
	mabCurrentBlockShape[2][0] = mabCopyShape[2][2];
	mabCurrentBlockShape[2][1] = mabCopyShape[1][2];
	mabCurrentBlockShape[2][2] = mabCopyShape[0][2];

	// Check the rotated piece is in a valid position. If not, restore the original rotation
	if ( TetrisCanMoveTo( mnCurrentBlockPosX, mnCurrentBlockPosY ) == FALSE )
	{
		memcpy( &mabCurrentBlockShape[0][0], &mabCopyShape[0][0], TETRIS_PIECE_ROWS*TETRIS_PIECE_COLS*sizeof(BYTE) );
	}
}

//-------------------------------------------------
// Function : TetrisDrawBlock
//   Draws a single block on the playing area
//-------------------------------------------------
void TetrisDrawBlock( int nLayer, int nX, int nY,ulong ulCol )
{
	nX *= TETRIS_BLOCK_WIDTH;
	nY *= TETRIS_BLOCK_HEIGHT;

	nX += mnBlocksBoxX;
	nY += mnBlocksBoxY;

	InterfaceRect( 1, nX, nY, TETRIS_BLOCK_WIDTH, TETRIS_BLOCK_HEIGHT, ulCol );
	InterfaceRect( 2, nX, nY, 2, TETRIS_BLOCK_HEIGHT, 0x80D0D0D0 );
	InterfaceRect( 2, nX, nY, TETRIS_BLOCK_WIDTH, 2, 0x80D0D0D0 );
	InterfaceRect( 2, nX + TETRIS_BLOCK_WIDTH - 2, nY, 2, TETRIS_BLOCK_HEIGHT, 0x80101010 );
	InterfaceRect( 2, nX,  nY + TETRIS_BLOCK_HEIGHT - 2, TETRIS_BLOCK_WIDTH, 2, 0x80101010 );
}

//-------------------------------------------------
// Function : TetrisCheckRowComplete
//  Returns TRUE if the specified row is full of blocks
//-------------------------------------------------
BOOL TetrisCheckRowComplete( int nY )
{
int	nX;

	for ( nX = 0; nX < TETRIS_BOX_COLS; nX++ )
	{
		// If any of the blocks in the row are not filled, the line is not complete
		if ( mabTetrisSpots[ nY ][ nX ] == 0 )
		{
			return( FALSE );
		}
	}
	return( TRUE );
}

//-------------------------------------------------
// Function : TetrisRemoveRow
//  Removes the specified row and moves the other rows down
//-------------------------------------------------
void TetrisRemoveRow( int nY )
{
int		nLoop;
int		nX;

	for ( nLoop = nY; nLoop > 0; nLoop-- )
	{
		for ( nX = 0; nX < TETRIS_BOX_COLS; nX++ )
		{
			mabTetrisSpots[ nLoop ][ nX ] =  mabTetrisSpots[ nLoop-1 ][ nX ];
		}	
	}
}



//-------------------------------------------------
// Function : TetrisStorePiece
//  Puts the current piece into the background blocks
//-------------------------------------------------
void TetrisStorePiece( void )
{
int		nX;
int		nY;
int		nPieceX;
int		nPieceY;

	nX = mnCurrentBlockPosX - 1;
	nY = mnCurrentBlockPosY - 1;
	for ( nPieceY = 0; nPieceY < TETRIS_PIECE_ROWS; nPieceY++ )
	{
		for ( nPieceX = 0; nPieceX < TETRIS_PIECE_COLS; nPieceX++ )
		{
			if ( mabCurrentBlockShape[ nPieceY ][ nPieceX ] != 0 )
			{
				mabTetrisSpots[ nY + nPieceY ][ nX + nPieceX ] = mabCurrentBlockShape[ nPieceY ][ nPieceX ];
			}
		}
	}
	// Now check for any complete rows and remove em
	for ( nY = TETRIS_BOX_ROWS-1; nY > 0; nY-- )
	{
		if ( TetrisCheckRowComplete( nY ) == TRUE )
		{
			TetrisRemoveRow( nY );
			nY++;
		}
	}
}

//-------------------------------------------------
// Function : TetrisUpdate
//  Main update function called every frame. Draws the game and moves the current piece if neccessary
//-------------------------------------------------
void TetrisUpdate( void )
{
int		nX;
int		nY;
int		nBlockX;
int		nBlockY;
ulong	ulTick = GetTickCount();

	InterfaceRect( 1, mnBlocksBoxX, mnBlocksBoxY, TETRIS_BOX_WIDTH, TETRIS_BOX_HEIGHT, 0xFF000060 );

	// Draw all the blocks in place
	for ( nY = 0; nY < TETRIS_BOX_ROWS; nY++ )
	{
		for ( nX = 0; nX < TETRIS_BOX_COLS; nX++ )
		{
  			switch( mabTetrisSpots[ nY ][ nX ] )
			{
			case 1:
				TetrisDrawBlock( 2,nX, nY, 0xFFD03010 );
				break;
			default:
				break;
			}
		}
	}

	// Draw the current block
	for ( nY = 0; nY < 3; nY++ )
	{
		for ( nX = 0; nX < 3; nX++ )
		{
			nBlockX = (mnCurrentBlockPosX - 1 + nX);
			nBlockY = (mnCurrentBlockPosY - 1 + nY);
			switch( mabCurrentBlockShape[ nY ][ nX ] )
			{
			case 1:
				TetrisDrawBlock( 2, nBlockX, nBlockY, 0xFFD03010 );
				break;
			}
		}
	}

	// Update the current blocks position if the time has run out.
	if ( mulNextMovePieceTime < ulTick )
	{
		mulNextMovePieceTime = ulTick + mulMoveDelayTime;
		if ( TetrisCanMoveTo( mnCurrentBlockPosX, mnCurrentBlockPosY + 1 ) == TRUE )
		{
			mnCurrentBlockPosY++;
		}
		else
		{
			if ( mnCurrentBlockPosY == 1 )
			{
				// Game Over!!!
			}
			else
			{		// Spawn a new piece
				// First copy the existing
				TetrisStorePiece();
				mnCurrentBlockPosY = 1;
				mnCurrentBlockPosX = 4;
				mulMoveDelayTime = mulNormalMoveDelayTime;
			}	
		}
	}
}


//-------------------------------------------------
// Function : TetrisInitGraphics
//  Initialisation function for the game
//-------------------------------------------------
void TetrisInitGraphics( void )
{
	ZeroMemory( mabTetrisSpots, sizeof( BYTE ) * TETRIS_BLOCK_SPOTS );
	mabTetrisSpots[ TETRIS_BOX_ROWS-1][0] = 1;

	ZeroMemory( mabCurrentBlockShape, sizeof( BYTE ) * TETRIS_PIECE_ROWS * TETRIS_PIECE_COLS );
	mabCurrentBlockShape[ 1 ][ 0 ] = 1;
	mabCurrentBlockShape[ 1 ][ 1 ] = 1;
	mabCurrentBlockShape[ 1 ][ 2 ] = 1;
	mabCurrentBlockShape[ 2 ][ 2 ] = 1;
}


//-------------------------------------------------
// Function : TetrisFreeGraphics
//  DeInitialisation function for the game
//-------------------------------------------------
void TetrisFreeGraphics( void )
{
}


//-------------------------------------------------
// Function : TetrisKeydown
//   Called when a key is pressed
//-------------------------------------------------
BOOL TetrisKeyDown( short key )
{
	if ( key == VK_LEFT )
	{
		if ( TetrisCanMoveTo( mnCurrentBlockPosX - 1, mnCurrentBlockPosY ) == TRUE )
		{
			mnCurrentBlockPosX--;
		}
	}
	if ( key == VK_UP )
	{
		TetrisRotatePiece();
	}

	if ( key == VK_DOWN )
	{
		mulMoveDelayTime = 50;
		mulNextMovePieceTime = 0;
	}

	if ( key == VK_RIGHT )
	{
		if ( TetrisCanMoveTo( mnCurrentBlockPosX + 1, mnCurrentBlockPosY ) == TRUE )
		{
			mnCurrentBlockPosX++;
		}
	}
	return( FALSE );
}


BOOL TetrisKeyUp( short key )
{
	return( FALSE );
}

:/

Posted: Tue Feb 17, 2004 11:02 am
by Fudrake
public class Speech {
public static void main(String[] args){
byte thing=1;
short thing1=1;
int thing2=1;
long thing3=1;
float thing4=1;
double thing5 = 1.0;
System.out.println("Sometimes, I laugh at myself, why try to learn C++, then take a big U-turn then learn Java? It's nice to know proper C coding is quite similar to that of Java, but I just had to leave it for the great advantages (and the disadvantages) of Java. Persuaded by my brother I was, and now I can do not much other than to declare classes, like this class \"Speech\", print things out, do simple loops, prove to the world that 1+0.2+0.2+0.2 doesn't equal 1.6.....it equals a random floating point number like " + (thing5+0.2+0.2+0.2)+"...... and I like to do stupid programs that repeats words over and over again ");

for(int c=0;;){
System.out.print("and again");
}
}
}

Posted: Tue Feb 17, 2004 1:01 pm
by Mattizme
Darn you Mit - you've made me sit down and make my own now :P

Posted: Sat Feb 21, 2004 1:43 pm
by Kaezon
ONLY 22 minutes?!? Jeeze, doing php i cant crank out that much unless it's a good day :P

Posted: Sat Feb 21, 2004 8:19 pm
by Mattizme
Kaezon, he does it for a living. he has allt he time int he world to do that :P

Posted: Tue Feb 24, 2004 10:21 pm
by Kaezon
lol, cool, that's what I plan to do in the future :D siting at a comp screen all day typing code.

Posted: Wed Feb 25, 2004 2:33 am
by Knoxjoey
yep i want too do it too :)

Posted: Wed Feb 25, 2004 3:55 pm
by Fudrake
Me too probs. But probably with Java, or some other language if I get to learn it.......

Java's portable :)
Java's object oriented :)
Java's simple :)
Java's Garbage Collection :)
Java's Garbage Collection is too automatic :(
Java's slooooooooooooooooooow :(
Java's still coooooooooool :)

Posted: Thu Feb 26, 2004 7:05 am
by hedgehog
it's no entire works of shakespeare, but i s'pose it'll have to do ;)