📄 blockgame.c
字号:
/*-----------------------------------------------------------------俄罗斯方块游戏-*/
/*----------------------------------------------write by codekey, codekey@126.com-*/
/*-------------------------------------------------------------------------2008-3-*/
/*---------------------------------------------欢迎使用和修改,但需保留原作者信息-*/
/*--------------------------------------------------------------------------------*/
#include <reg52.h>
#include <stdlib.h>
#include <STRING.H>
#include "BlockGame.h"
/*--------------------------------------------------------------------------------*/
void InitGame( BLOCK_GAME* pGame )
{
UINT8 i;
/* 初始化游戏格子 */
for(i=0;i<GAME_GRID_ROW;i++){
pGame->GameGrid.Grid[i]=0xE007;
}
for(i=0;i<3;i++){
pGame->GameGrid.Grid[i]=0xFFFF;
pGame->GameGrid.Grid[GAME_GRID_ROW-i-1]=0xFFFF;
}
pGame->GameBlock.nNextBlockType=rand()%7;
}
BOOL NewGame( BLOCK_GAME* pGame )
{
InitGame(pGame);
NewBlock(pGame);
return 0;
}
void GameOver( BLOCK_GAME* pGame )
{
NewGame(pGame);
}
BOOL NewBlock( BLOCK_GAME* pGame )
{
static UINT8 gc=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;
gc++;
if(gc>=6)
{
pGame->GameBlock.nNextBlockType=1;
gc=0;
}
// need a better algorithm or a better evaluating function
// to make cmputer to run as an expert.
pGame->GameBlock.nFirstBlockRow=GAME_FIRST_ROW-1;
pGame->GameBlock.nFirstBlockCol=(GAME_LAST_COL-GAME_FIRST_COL+1-4)/2+GAME_FIRST_COL;
BuildBlocks(pGame);
return BlockGridConsistent(pGame);
}
/* 判断方格是否可以容纳方块 */
BOOL BlockGridConsistent( BLOCK_GAME* pGame )
{
UINT8 i;
UINT16 tmp;
for(i=0;i<4;i++)
{
tmp=(pGame->GameBlock.BlocksInfo>>(i*4))&0x000F;
tmp=tmp<<pGame->GameBlock.nFirstBlockCol;
if( (pGame->GameGrid.Grid[i+pGame->GameBlock.nFirstBlockRow]&tmp)!=0x0 )
{
return 0;
}
}
return 1;
}
/* 生成方块 */
void BuildBlocks( BLOCK_GAME* pGame ) /*之所以采取这种方式,为了减少ram存储空间*/
{
switch(pGame->GameBlock.nCurBlockType)
{
case 0: /*一种状态*/
pGame->GameBlock.BlocksInfo=0x0660;
break;
case 1: /*两种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
case 2:
pGame->GameBlock.BlocksInfo=0x00F0;
break;
case 1:
case 3:
pGame->GameBlock.BlocksInfo=0x2222;
break;
}
break;
case 2: /*两种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
case 2:
pGame->GameBlock.BlocksInfo=0x4620;
break;
case 1:
case 3:
pGame->GameBlock.BlocksInfo=0x3600;
break;
}
break;
case 3: /*两种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
case 2:
pGame->GameBlock.BlocksInfo=0x2640;
break;
case 1:
case 3:
pGame->GameBlock.BlocksInfo=0x6300;
break;
}
break;
case 4: /*四种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
pGame->GameBlock.BlocksInfo=0x2260;
break;
case 1:
pGame->GameBlock.BlocksInfo=0x0710;
break;
case 2:
pGame->GameBlock.BlocksInfo=0x3220;
break;
case 3:
pGame->GameBlock.BlocksInfo=0x4700;
break;
}
break;
case 5: /*四种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
pGame->GameBlock.BlocksInfo=0x2230;
break;
case 1:
pGame->GameBlock.BlocksInfo=0x1700;
break;
case 2:
pGame->GameBlock.BlocksInfo=0x6220;
break;
case 3:
pGame->GameBlock.BlocksInfo=0x0740;
break;
}
break;
case 6: /*四种状态*/
switch(pGame->GameBlock.nCurBlockStatus)
{
case 0:
pGame->GameBlock.BlocksInfo=0x0720;
break;
case 1:
pGame->GameBlock.BlocksInfo=0x2320;
break;
case 2:
pGame->GameBlock.BlocksInfo=0x2700;
break;
case 3:
pGame->GameBlock.BlocksInfo=0x2620;
break;
}
break;
default: break;
}
}
/*--移动方块----------------*/
/* type = eMoveUp 上移 */
/* type = eMoveDown 下移 */
/* type = eMoveLeft 左移 */
/* type = eMoveRigh 右移 */
BOOL MoveBlock( BLOCK_GAME* pGame, UINT8 nMoveMode)
{
switch((enum eMoveMode)nMoveMode)
{
case eMoveUp:
pGame->GameBlock.nFirstBlockRow--;
break;
case eMoveDown:
pGame->GameBlock.nFirstBlockRow++;
break;
case eMoveRight:
pGame->GameBlock.nFirstBlockCol++;
break;
case eMoveLeft:
pGame->GameBlock.nFirstBlockCol--;
break;
case eMoveTurn:
pGame->GameBlock.nCurBlockStatus=(pGame->GameBlock.nCurBlockStatus+1)%4;
BuildBlocks(pGame);
break;
}
if(!BlockGridConsistent(pGame))
{
switch((enum eMoveMode)nMoveMode)
{
case eMoveUp:
pGame->GameBlock.nFirstBlockRow++;
break;
case eMoveDown:
pGame->GameBlock.nFirstBlockRow--;
break;
case eMoveLeft:
pGame->GameBlock.nFirstBlockCol++;
break;
case eMoveRight:
pGame->GameBlock.nFirstBlockCol--;
break;
case eMoveTurn:
pGame->GameBlock.nCurBlockStatus=(pGame->GameBlock.nCurBlockStatus-1+4)%4;
BuildBlocks(pGame);
break;
}
return 0;
}
return 1;
}
/* 扩展功能-旋转方块,尽可能保证旋转成功 */
BOOL TurnBlock( BLOCK_GAME* pGame )
{
BOOL bOperated=myTrue;
if(!MoveBlock(pGame,eMoveTurn)) /*旋转不成功*/
{
bOperated = myFalse;
}
if(!bOperated)
{
if(MoveBlock(pGame,eMoveLeft))
{
if(!MoveBlock(pGame,eMoveTurn)) /*左移旋转不成功*/
{
bOperated = myFalse;
MoveBlock(pGame,eMoveRight);
}
else
bOperated = myTrue;
}
}
if(!bOperated)
{
if(MoveBlock(pGame,eMoveRight))
{
if(!MoveBlock(pGame,eMoveTurn)) /*右移旋转不成功*/
{
bOperated = myFalse;
MoveBlock(pGame,eMoveLeft);
}
else
bOperated = myTrue;
}
}
if(!bOperated)
{
if(MoveBlock(pGame,eMoveDown))
{
if(!MoveBlock(pGame,eMoveTurn)) /*下移旋转不成功*/
{
bOperated = myFalse;
MoveBlock(pGame,eMoveUp);
}
else
bOperated = myTrue;
}
}
if(!bOperated)
{
if(MoveBlock(pGame,eMoveUp))
{
if(!MoveBlock(pGame,eMoveTurn)) /*上移旋转不成功*/
{
bOperated = myFalse;
MoveBlock(pGame,eMoveDown);
}
else
bOperated = myTrue;
}
}
return bOperated;
}
/*-固定方块在方格上-*/
void FixCurBlock( BLOCK_GAME* pGame )
{
UINT8 i;
UINT16 tmp;
for(i=0;i<4;i++)
{
tmp=pGame->GameBlock.BlocksInfo;
tmp=(tmp>>i*4)&0x000F;
tmp=tmp<<pGame->GameBlock.nFirstBlockCol;
pGame->GameGrid.Grid[pGame->GameBlock.nFirstBlockRow+i] =
pGame->GameGrid.Grid[pGame->GameBlock.nFirstBlockRow+i]|tmp;
}
}
/*-消满行-*/
BOOL AdjustGrid( BLOCK_GAME* pGame )
{
UINT8 i=0,m=0;
BOOL bAdjusted=0;
for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++)
{
if(pGame->GameGrid.Grid[i]==0xFFFF)
{
for(m=i;m>GAME_FIRST_ROW;m--){
pGame->GameGrid.Grid[m]=pGame->GameGrid.Grid[m-1];
}
pGame->GameGrid.Grid[0]=myFalse;
bAdjusted=1;
}
}
return bAdjusted;
}
/*--------------------------------------------------------------------------------*/
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( BLOCK_ATTR* pDestBlock, BLOCK_ATTR* pSourBlock )
{
memcpy(pDestBlock,pSourBlock,sizeof(BLOCK_ATTR));
}
void CopyGridAttr(GRID_ATTR* pDestAttr, GRID_ATTR* pSourAttr )
{
memcpy(pDestAttr,pSourAttr,sizeof(GRID_ATTR));
}
/*--------------------------------------------------------------------------------*/
void GetGridAttr( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
pGridAttr->nLastBlockFirstRow = pGame->GameBlock.nFirstBlockRow;
GetFullRow(pGame,pGridAttr);
GetIdleBank(pGame,pGridAttr);
GetGridHigh(pGame,pGridAttr);
GetHighEdge(pGame,pGridAttr);
}
void GetGridHigh( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
UINT8 i=0;
for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++)
{
if(pGame->GameGrid.Grid[i]&0x1FF8){
break;
}
}
pGridAttr->nGrideHeight = GAME_LAST_ROW-i+1;
}
void GetFullRow( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
UINT8 nFullCount=0;
UINT8 i=0;
nFullCount=0;
for(i=GAME_FIRST_ROW;i<=GAME_LAST_ROW;i++)
{
if(pGame->GameGrid.Grid[i]==0xFFFF)
{
nFullCount++;
}
}
pGridAttr->nFullRowCount=nFullCount;
}
/* 计算无用的空格数 */
void GetIdleBank( BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
UINT8 nIdleBankCount=0;
UINT8 i=0, j=0;
nIdleBankCount=0;
for( j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)
{
i=GAME_FIRST_ROW;
while(i<=GAME_LAST_ROW
&& (0x0000==(pGame->GameGrid.Grid[i]&(0x0001<<j))) )
i++; // 找第一个填充格
while(i<=GAME_LAST_ROW){
if( !(pGame->GameGrid.Grid[i++]>>j&0x01) ) nIdleBankCount+=1;
}
}
pGridAttr->nIdleBankCount = nIdleBankCount;
}
/* 计算高边 */
void GetHighEdge(BLOCK_GAME* pGame, GRID_ATTR* pGridAttr )
{
UINT8 i, j, m;
UINT8 EdgeCount;
UINT8 tmpBankCount;
UINT8 MostHighEage;
EdgeCount = 0;
MostHighEage = 0;
for(j=GAME_FIRST_COL;j<=GAME_LAST_COL;j++)
{
i=GAME_FIRST_ROW;
while( (i<=GAME_LAST_ROW)
&& (0x0==(pGame->GameGrid.Grid[i]&(0x0001<<j))) )i++;
m = i;
tmpBankCount=0; /* 左边 */
while( (m<=GAME_LAST_ROW)
&& (0x0==(pGame->GameGrid.Grid[m]&(0x0001<<(j-1)))) )
{
m++;
tmpBankCount++;
MostHighEage=(MostHighEage<tmpBankCount)?tmpBankCount:MostHighEage;
}
if(tmpBankCount>2){
EdgeCount++;
}
m = i;
tmpBankCount=0; /* 右边 */
while( (m<=GAME_LAST_ROW)
&& (0x0==(pGame->GameGrid.Grid[m]&(0x0001<<(j+1)))) )
{
m++;
tmpBankCount++;
MostHighEage=(MostHighEage<tmpBankCount)?tmpBankCount:MostHighEage;
}
if(tmpBankCount>2){
EdgeCount++;
}
}
pGridAttr->nHighEdgeCount=EdgeCount;
pGridAttr->nMostHighEdgeHeight=(0==EdgeCount)?0:MostHighEage;
}
/*--------------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -