📄 blockgame.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 + -