⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blockgame.cpp

📁 linux 下的 仿联众版俄罗斯方块游戏。qt3 实现。 具有 人机交互功能。 具有 对战模式。 喜欢玩俄罗斯方块的朋友们
💻 CPP
字号:
/*********************************************************************** *
 *
 *    linux版仿联众俄罗斯方块 v1.0
 *    该软件在GPL(GNU通用公共许可证)下发布
 *
 *    Copyright (C)   <codeky@126.com>
 *
 *   This source code is licensed under the GNU General Public License
 *
 ************************************************************************/

/*	完全采用纯C编写 方便移植。作者已经在单片机上实现。 codekey@126.com */

#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "blockgame.h"

static void ClrGame( BLOCK_GAME* pGame )  //
{
	_bS8 i=0,j=0;
	_bU32 curClock = GET_CUR_TIME();
	srand(curClock);
	/* 初始化游戏格子 */
	for(i=0;i<GAME_GRID_ROW;i++){
		for(j=0;j<GAME_GRID_COL;j++){
			pGame->GameGrid.Grid[i][j].bFillBlock=_bTrue;
		}
	}
	for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++){ /* 中间空白 */
		for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++){
			pGame->GameGrid.Grid[i][j].bFillBlock=_bFalse;
		}
	}
	pGame->GameBlock.nNextBlockType=rand()%7;
	pGame->GameBlock.nCurBlockType=pGame->GameBlock.nNextBlockType;
	pGame->lScore=0;
	pGame->bDirty=_bFalse;
}
// 应该只被调用一次
void InitGame( BLOCK_GAME* pGame )
{
	ClrGame(pGame);
	pGame->nGameStatus=eGameNormal;
	pGame->nGameTimer=0;
	pGame->nLostTimer=0;
	pGame->nWinTimer=0;
}

_bS8 NewGame( BLOCK_GAME* pGame )
{
	ClrGame(pGame);
	NewBlock(pGame);
	pGame->nGameStatus=eGameRun;
	pGame->nGameTimer++;
	return 0;
}
void PauseGame( BLOCK_GAME* pGame, _bBool pause )
{
	pGame->nGameStatus = pause;
}

void WinGame( BLOCK_GAME* pGame )
{
	ClrGame(pGame);
	pGame->bDirty= _bTrue;
	pGame->nGameStatus = eGameWin;
	pGame->nWinTimer+=1;
}

void GameOver( BLOCK_GAME* pGame )
{
	ClrGame(pGame);
	pGame->nGameStatus=eGameLost;
	pGame->nLostTimer+=1;
}

_bS8 NewBlock( BLOCK_GAME* pGame )
{
	_bS8 i=0,j=0;
	pGame->GameBlock.nCurBlockType=pGame->GameBlock.nNextBlockType;
	pGame->GameBlock.nCurBlockStatus=0;
	pGame->GameBlock.nNextBlockType=rand()%7;
	if(pGame->GameBlock.nNextBlockType==pGame->GameBlock.nCurBlockType)
		pGame->GameBlock.nNextBlockType=(pGame->GameBlock.nNextBlockType+1)%7;
	pGame->GameBlock.CurFirstBlock.row=GAME_FIRST_ROW-1;
	pGame->GameBlock.CurFirstBlock.col=(GAME_LAST_COL-GAME_FIRST_COL+1-4)/2+GAME_FIRST_COL;

	for(i=0;i<4;i++){
		for(j=0;j<4;j++){
			if(GameBlock[pGame->GameBlock.nCurBlockType][pGame->GameBlock.nCurBlockStatus][i][j]
				&pGame->GameGrid.Grid[pGame->GameBlock.CurFirstBlock.row+i][pGame->GameBlock.CurFirstBlock.col+j].bFillBlock)
			{
				return 0;
			}
		}
	}
	pGame->bDirty=_bFalse; //
	return 1;
}

/*  type = eMoveUp    上移 */
/*  type = eMoveDown  下移 */
/*  type = eMoveLeft  左移 */
/*  type = eMoveRigh  右移 */
_bBool MoveBlock( BLOCK_GAME* pGame, _bS8 nMoveMode)
{
	_bBool i=_bFalse,j=_bFalse;
	if(pGame->nGameStatus==eGameLost) return _bFalse;

	switch((enum eMoveMode)nMoveMode) {
	case eMoveUp:
		pGame->GameBlock.CurFirstBlock.row--;
		break;
	case eMoveDown:
		pGame->GameBlock.CurFirstBlock.row++;
		break;
	case eMoveLeft:
		pGame->GameBlock.CurFirstBlock.col--;
		break;
	case eMoveRight:
		pGame->GameBlock.CurFirstBlock.col++;
		break;
	case eMoveTurn:
		pGame->GameBlock.nCurBlockStatus=(pGame->GameBlock.nCurBlockStatus+1)%4;
		break;
	}
	for(i=0;i<4;i++) {
		for(j=0;j<4;j++) {
			if(GameBlock[pGame->GameBlock.nCurBlockType][pGame->GameBlock.nCurBlockStatus][i][j]
				&pGame->GameGrid.Grid[pGame->GameBlock.CurFirstBlock.row+i][pGame->GameBlock.CurFirstBlock.col+j].bFillBlock) {
				switch((enum eMoveMode)nMoveMode) {
				case eMoveUp:
					pGame->GameBlock.CurFirstBlock.row++;
					break;
				case eMoveDown:
					pGame->GameBlock.CurFirstBlock.row--;
					break;
				case eMoveLeft:
					pGame->GameBlock.CurFirstBlock.col++;
					break;
				case eMoveRight:
					pGame->GameBlock.CurFirstBlock.col--;
					break;
				case eMoveTurn:
					pGame->GameBlock.nCurBlockStatus=(pGame->GameBlock.nCurBlockStatus-1+4)%4;
					break;
				}
				return _bFalse;
			}
		}
	}
	return _bTrue;
}

_bBool TurnBlock( BLOCK_GAME* pGame )
{
	_bBool bOperated=_bTrue;
	if(pGame->nGameStatus==eGameLost) return _bFalse;
	if(!MoveBlock(pGame,eMoveTurn)) {/*旋转不成功*/
		bOperated = _bFalse;
	}
	if(!bOperated){
		if(MoveBlock(pGame,eMoveLeft)) {
			if(!MoveBlock(pGame,eMoveTurn)) {/*左移旋转不成功*/
				bOperated = _bFalse;
				MoveBlock(pGame,eMoveRight);
			}else
				bOperated = _bTrue;
		}
	}
	if(!bOperated) {
		if(MoveBlock(pGame,eMoveRight))	{
			if(!MoveBlock(pGame,eMoveTurn)) {/*右移旋转不成功*/
				bOperated = _bFalse;
				MoveBlock(pGame,eMoveLeft);
			}else
				bOperated = _bTrue;
		}
	}
	if(!bOperated) {
		if(MoveBlock(pGame,eMoveDown)) {
			if(!MoveBlock(pGame,eMoveTurn)) { /*下移旋转不成功*/
				bOperated = _bFalse;
				MoveBlock(pGame,eMoveUp);
			}else
				bOperated = _bTrue;
		}
	}
	if(!bOperated) {
		if(MoveBlock(pGame,eMoveUp)) {
			if(!MoveBlock(pGame,eMoveTurn)) { /*上移旋转不成功*/
				bOperated = _bFalse;
				MoveBlock(pGame,eMoveDown);
			}else
				bOperated = _bTrue;
		}
	}
	return bOperated;
}

void FixCurBlock(  BLOCK_GAME* pGame )
{
	_bS8 i=0,j=0;
	for(i=0;i<4;i++) {
		for(j=0;j<4;j++) {
			if(GameBlock[pGame->GameBlock.nCurBlockType][pGame->GameBlock.nCurBlockStatus][i][j]) {
				pGame->GameGrid.Grid[pGame->GameBlock.CurFirstBlock.row+i][pGame->GameBlock.CurFirstBlock.col+j].bFillBlock=_bTrue;//pGame->GameBlock.nCurBlockType+1;
				pGame->GameGrid.Grid[pGame->GameBlock.CurFirstBlock.row+i][pGame->GameBlock.CurFirstBlock.col+j].nBlockType = pGame->GameBlock.nCurBlockType;
			}
		}
	}
}

_bS8 AdjustGrid( BLOCK_GAME* pGame )
{
	_bS8 i=0,j=0,m=0;
	_bS8 nCountFull = 0;

	for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++) {
		_bBool bLineFull=_bTrue;
		for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++) {
			if(pGame->GameGrid.Grid[i][j].bFillBlock==_bFalse) {
				bLineFull=_bFalse;
				break;
			}
		}
		if(bLineFull){
			for(m=i;m>GAME_FIRST_ROW;m--) {
				for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++) {
					pGame->GameGrid.Grid[m][j].bFillBlock=pGame->GameGrid.Grid[m-1][j].bFillBlock;
					pGame->GameGrid.Grid[m][j].nBlockType=pGame->GameGrid.Grid[m-1][j].nBlockType;
				}
			}
			for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++) {
				pGame->GameGrid.Grid[GAME_FIRST_ROW][j].bFillBlock=_bFalse;
			}
			nCountFull=nCountFull+1;
		}
	}
	pGame->lScore+=(nCountFull*(nCountFull+1))/2;
	return nCountFull;
}
_bS8 AddLine( BLOCK_GAME* pGame, _bS8 nLineCount/*加行数*/)
{
	_bS8 n = nLineCount;
	_bS8 i=0,j=0;
	if(n>=4 || n<=0 ) return 0;
	if(pGame->nGameStatus==eGameLost) return 0;
	while( (n--)>0 && MoveBlock(pGame,eMoveUp) ); //移动当前块

	for( n=0;n<nLineCount;n++ ){ // 移动这么多次,
		for(i=GAME_FIRST_ROW;i<GAME_LAST_ROW;i++) {
			for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++) {
				pGame->GameGrid.Grid[i][j].bFillBlock=
					pGame->GameGrid.Grid[i+1][j].bFillBlock;
				pGame->GameGrid.Grid[i][j].nBlockType=
					pGame->GameGrid.Grid[i+1][j].nBlockType;
			}
		}
		for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++) {
			pGame->GameGrid.Grid[i][j].bFillBlock= _bTrue;
			pGame->GameGrid.Grid[i][j].nBlockType= rand()%7;
		} // 填充最后一行
		pGame->GameGrid.Grid[i][GAME_FIRST_COL+rand()%GAME_COL].bFillBlock= _bFalse;	// 只随机一个格子为空
		pGame->GameGrid.Grid[i][j].nBlockType= 0; //
	}
	pGame->bDirty=_bTrue;
	return 1; // 先 暂时 写为1,最好写增加了几行
}

void CopyGame( BLOCK_GAME* pDestGame, BLOCK_GAME* pSourGame )
{
	memcpy(pDestGame,pSourGame,sizeof(BLOCK_GAME));

}
void CopyGameGrid( GAME_GRID* pDestGrid, GAME_GRID* pSourGrid )
{

	memcpy(pDestGrid,pSourGrid,sizeof(GAME_GRID));
}
void CopyGameBlock( GAME_BLOCK* pDestBlock, GAME_BLOCK* pSourBlock )
{
	memcpy(pDestBlock,pSourBlock,sizeof(GAME_BLOCK));
}
void CopyGridAttr(GRID_ATTR* pDestAttr, GRID_ATTR* pSourAttr )
{
	memcpy(pDestAttr,pSourAttr,sizeof(GRID_ATTR));
}

void GetGridAttr( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
	GetFullRow(pGame,pGridAttr);
	GetIdleBank(pGame,pGridAttr);
	GetBank(pGame,pGridAttr);
	pGridAttr->nLastBlockFirstRow = pGame->GameBlock.CurFirstBlock.row;
	GetHighEdge(pGame,pGridAttr);
}

void GetFullRow( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
	_bS8 nFullCount=0;
	_bS8 i=0, j=0;
	_bBool bLineFull;

	for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++){
		bLineFull=_bTrue;//表示满了一行
		for( j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)	{
			if(!pGame->GameGrid.Grid[i][j].bFillBlock){
				bLineFull=_bFalse;
				break;
			}
		}
		if(bLineFull)nFullCount++;
	}
	pGridAttr->nFullRowCount=nFullCount;
}

void GetIdleBank( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr ) /* 计算无用的空格数 */
{
	_bS8 nIdleBankCount=0;
	_bS8 i=0, j=0;
	for( j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++){
		i=GAME_FIRST_ROW;
		while(i<=GAME_LAST_ROW && (!pGame->GameGrid.Grid[i][j].bFillBlock) ) i++; /* 找第一个填充格 */
		while(i<=GAME_LAST_ROW){
			if(!pGame->GameGrid.Grid[i++][j].bFillBlock)	nIdleBankCount+=1;
		}
	}
	pGridAttr->nIdleBankCount = nIdleBankCount;
}

void GetBank( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr) /* 计算从最高位置开始的所有空格数 */
{
	_bS8 nBankCount=0;
	_bS8 i=0, j=0;
	_bBool	bFind=_bFalse;

	for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++)	{
		for( j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)	{
			if(pGame->GameGrid.Grid[i][j].bFillBlock){
				bFind=_bTrue;
				break;
			}
		}
		if(bFind) break;
	}

	while(i<=GAME_LAST_ROW)	{
		for( j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)	{
			if(!pGame->GameGrid.Grid[i][j].bFillBlock){
				nBankCount++;
			}
		}
		i++;
	}
	pGridAttr->nBankCount = nBankCount;
}

void GetHighEdge(BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
	_bS8 i=0, j=0, m=0;
	_bS8 EdgeCount=0;
	_bS8 EdgeBankCount=0;
	_bS8 tmpBankCount=0;
	_bS8 MostHighEage=0;

	for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++){
		i=GAME_FIRST_ROW;
		while(i<=GAME_LAST_ROW && (!pGame->GameGrid.Grid[i][j].bFillBlock))i++;
		m = i;
		tmpBankCount=0;   /* 左边 */
		while(m<=GAME_LAST_ROW && (!pGame->GameGrid.Grid[m][j-1].bFillBlock) ){
			m++;
			tmpBankCount++;
			MostHighEage=(MostHighEage<tmpBankCount)?tmpBankCount:MostHighEage;
		}
		if(tmpBankCount>2){
			EdgeCount++;
			EdgeBankCount+=tmpBankCount;
		}
		m = i;
		tmpBankCount=0;   /* 右边 */
		while(m<=GAME_LAST_ROW && (!pGame->GameGrid.Grid[m][j+1].bFillBlock) ){
			m++;
			tmpBankCount++;
			MostHighEage=(MostHighEage<tmpBankCount)?tmpBankCount:MostHighEage;
		}
		if(tmpBankCount>2){
			EdgeCount++;
			EdgeBankCount+=tmpBankCount;
		}
	}
	pGridAttr->nHighEdgeCount=EdgeCount;
	pGridAttr->nHighEdgeGridCount=EdgeBankCount;
	pGridAttr->nMostHighEdgeHeight=MostHighEage;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -