📄 russionblock.cpp
字号:
// RussionBlock.cpp: implementation of the CRussionBlock class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BB.h"
#include "RussionBlock.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
DOWNKEY* CRussionBlock::button[COL_BLOCK_COUNT];
DOWNKEY CRussionBlock::dk[ROW_BLOCK_COUNT];
DOWNKEY CRussionBlock::downkey[ROW_BLOCK_COUNT];
CRussionBlock::CRussionBlock()
{
::memset(m_pos,0,4*sizeof(POS));
::memset(m_oldpos,0,4*sizeof(POS));
m_btype=-1;
m_bstatus=0;
m_bpaste=0;
}
CRussionBlock::CRussionBlock(int ntype,int nstatus)
{
//H0
//H1
//H2
//H3
//M:0--1--2--3
m_btype=ntype;
m_bstatus=nstatus;
m_bpaste=FALSE;
if(ntype>=0)
{
int index=mask_pos[m_btype]+m_bstatus;
::memcpy(m_pos,init_pos+4*index,4*sizeof(POS));
::memcpy(m_oldpos,m_pos,4*sizeof(POS));
}
}
CRussionBlock::CRussionBlock(const CRussionBlock &block)
{
m_btype=block.m_btype;
m_bstatus=block.m_bstatus;
m_bpaste=FALSE;
::memcpy(m_pos,block.m_pos,4*sizeof(POS));
::memcpy(m_oldpos,m_pos,4*sizeof(POS));
}
CRussionBlock::~CRussionBlock()
{
}
//FALSE表示碰撞
BOOL CRussionBlock::CheckBump(BYTE Face[][ROW_BLOCK_COUNT+2])
{
if(Face[m_pos[0].row][m_pos[0].col]>0)
return FALSE;
if(Face[m_pos[1].row][m_pos[1].col]>0)
return FALSE;
if(Face[m_pos[2].row][m_pos[2].col]>0)
return FALSE;
if(Face[m_pos[3].row][m_pos[3].col]>0)
return FALSE;
return TRUE;
}
void CRussionBlock::Rot1()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
m_pos[0].row-=2;
++m_pos[0].col;
--m_pos[1].row;
--m_pos[2].col;
++m_pos[3].row;
m_pos[3].col-=2;
break;
case 1:
m_bstatus=2;
m_pos[0].row+=2;
m_pos[0].col-=2;
++m_pos[1].row;
--m_pos[1].col;
--m_pos[3].row;
++m_pos[3].col;
break;
case 2:
m_bstatus=3;
--m_pos[0].row;
m_pos[0].col+=2;
++m_pos[1].col;
++m_pos[2].row;
m_pos[3].row+=2;
--m_pos[3].col;
break;
case 3:
m_bstatus=0;
++m_pos[0].row;
--m_pos[0].col;
--m_pos[2].row;
++m_pos[2].col;
m_pos[3].row-=2;
m_pos[3].col+=2;
break;
default:
ASSERT(FALSE);
break;
}
}
void CRussionBlock::Rot2()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
--m_pos[0].row;
--m_pos[0].col;
m_pos[1].row-=2;
++m_pos[2].row;
--m_pos[2].col;
break;
case 1:
m_bstatus=2;
++m_pos[0].row;
m_pos[1].row+=2;
--m_pos[1].col;
--m_pos[2].row;
--m_pos[3].col;
break;
case 2:
m_bstatus=3;
--m_pos[1].row;
++m_pos[1].col;
m_pos[2].row+=2;
++m_pos[3].row;
++m_pos[3].col;
break;
case 3://?
m_bstatus=0;
++m_pos[0].col;
++m_pos[1].row;
m_pos[2].row-=2;
++m_pos[2].col;
--m_pos[3].row;
break;
default:
ASSERT(FALSE);
break;
}
}
void CRussionBlock::Rot3()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
++m_pos[0].row;
--m_pos[0].col;
--m_pos[1].row;
--m_pos[2].col;
m_pos[3].row-=2;
break;
case 1:
m_bstatus=2;
--m_pos[0].row;
++m_pos[1].row;
--m_pos[1].col;
m_pos[3].row+=2;
--m_pos[3].col;
break;
case 2:
m_bstatus=3;
m_pos[0].row+=2;
++m_pos[1].col;
++m_pos[2].row;
--m_pos[3].row;
++m_pos[3].col;
break;
case 3:
m_bstatus=0;
m_pos[0].row-=2;
++m_pos[0].col;
--m_pos[2].row;
++m_pos[2].col;
++m_pos[3].row;
break;
default:
ASSERT(FALSE);
break;
}
}
void CRussionBlock::Rot4()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
++m_pos[0].row;
--m_pos[0].col;
--m_pos[1].row;
--m_pos[2].row;
break;
case 1:
m_bstatus=2;
++m_pos[3].row;
--m_pos[3].col;
break;
case 2:
m_bstatus=3;
++m_pos[1].row;
++m_pos[2].row;
--m_pos[3].row;
++m_pos[3].col;
break;
case 3:
m_bstatus=0;
--m_pos[0].row;
++m_pos[0].col;
break;
default:
ASSERT(FALSE);
break;
}
}
void CRussionBlock::Rot5()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
--m_pos[0].row;
++m_pos[0].col;
--m_pos[1].row;
++m_pos[1].col;
++m_pos[2].row;
++m_pos[3].row;
break;
case 1:
m_bstatus=2;
++m_pos[0].row;
--m_pos[0].col;
--m_pos[1].row;
++m_pos[1].col;
--m_pos[2].row;
--m_pos[3].row;
break;
case 2:
m_bstatus=3;
--m_pos[0].row;
--m_pos[1].col;
++m_pos[3].row;
--m_pos[3].col;
break;
case 3:
m_bstatus=0;
++m_pos[0].row;
m_pos[1].row+=2;
--m_pos[1].col;
--m_pos[3].row;
++m_pos[3].col;
break;
default:
ASSERT(FALSE);
break;
}
}
void CRussionBlock::Rot6()
{
switch(m_bstatus)
{
case 0:
m_bstatus=1;
m_pos[0].row+=2;
--m_pos[1].row;
++m_pos[1].col;
++m_pos[3].row;
--m_pos[3].col;
break;
case 1:
m_bstatus=2;
--m_pos[0].row;
++m_pos[1].row;
++m_pos[2].col;
++m_pos[3].col;
break;
case 2:
m_bstatus=3;
--m_pos[0].row;
++m_pos[0].col;
++m_pos[2].row;
--m_pos[2].col;
m_pos[3].row-=2;
break;
case 3:
m_bstatus=0;
--m_pos[0].col;
--m_pos[1].col;
--m_pos[2].row;
++m_pos[3].row;
break;
default:
ASSERT(FALSE);
break;
}
}
//只有down会导致paste
BOOL CRussionBlock::Down(BYTE Face[][ROW_BLOCK_COUNT+2])
{
if(!m_bpaste)
{
BOOL oldstatus=m_bstatus;
POS oldpos[4];
::memcpy(oldpos,m_pos,4*sizeof(POS));
--m_pos[0].row;
--m_pos[1].row;
--m_pos[2].row;
--m_pos[3].row;
if(CheckBump(Face)==FALSE)//碰撞
{
m_bstatus=oldstatus;
::memcpy(m_pos,oldpos,4*sizeof(POS));
m_bpaste=TRUE;
return FALSE;
}
else
{
::memcpy(m_oldpos,oldpos,4*sizeof(POS));
return TRUE;
}
}
return FALSE;
}
BOOL CRussionBlock::GoLeft(BYTE Face[][ROW_BLOCK_COUNT+2])
{
if(!m_bpaste)
{
BOOL oldstatus=m_bstatus;
POS oldpos[4];
::memcpy(oldpos,m_pos,4*sizeof(POS));
--m_pos[0].col;
--m_pos[1].col;
--m_pos[2].col;
--m_pos[3].col;
if(CheckBump(Face)==FALSE)//碰撞
{
m_bstatus=oldstatus;
::memcpy(m_pos,oldpos,4*sizeof(POS));
return FALSE;
}
else
{
::memcpy(m_oldpos,oldpos,4*sizeof(POS));
return TRUE;
}
}
return FALSE;
}
BOOL CRussionBlock::GoRight(BYTE Face[][ROW_BLOCK_COUNT+2])
{
if(!m_bpaste)
{
BOOL oldstatus=m_bstatus;
POS oldpos[4];
::memcpy(oldpos,m_pos,4*sizeof(POS));
++m_pos[0].col;
++m_pos[1].col;
++m_pos[2].col;
++m_pos[3].col;
if(CheckBump(Face)==FALSE)//碰撞
{
m_bstatus=oldstatus;
::memcpy(m_pos,oldpos,4*sizeof(POS));
return FALSE;
}
else
{
::memcpy(m_oldpos,oldpos,4*sizeof(POS));
return TRUE;
}
}
return FALSE;
}
//DEL COLORREF CRussionBlock::GetColor()
//DEL {
//DEL COLORREF color[7]={RGB(200,200,0),RGB(51,204,102),RGB(255,0,255),
//DEL RGB(255,0,0) ,RGB(0,230,0),RGB(0,60,255),RGB(160,130,100)};
//DEL return color[m_btype];
//DEL }
/*inline BOOL CRussionBlock::GetType()
{
return m_btype;
}*/
int CRussionBlock::Fitness(BYTE Face1[][ROW_BLOCK_COUNT+2]
, UINT top[ROW_BLOCK_COUNT+2],UINT uitop,int& nMove)
{
/*CRussionBlock cur(*this);
BOOL bSrcStatus=cur.m_bstatus;
int nMax=0x80000000,nScore;
int nStatus=0,nMove1=0;
do
{
nScore=cur.GetScore(Face1,top,nMove1);
nScore-=(abs(nMove1)*100);
if(nScore>nMax)
{
nMove=nMove1;
nStatus=cur.m_bstatus;
nMax=nScore;
}
cur.Rotation();
}
while(cur.m_bstatus!=bSrcStatus);
return nStatus;*/
return 0;
}
//Face[][ROW_BLOCK_COUNT+2],top[ROW_BLOCK_COUNT+2]
int CRussionBlock::GetScore(BYTE Face[][ROW_BLOCK_COUNT+2]
, UINT top[ROW_BLOCK_COUNT+2], int& nMove,int& nClrNum,BYTE clr[4])
{
int i,j,nScore=0,nMaxScore=0x80000000;
const BYTE full[ROW_BLOCK_COUNT+2]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
int nClrNum1=0,nNull=0,/*ntoper=0*/nSub=0,nLeftSub=0,nRightSub=0,nLeftCol,nRightCol;
int CheckCol[4]={0,0,0,0},/*CheckRow[4]={0,0,0,0},*/ClearScore[2]={0,1300}
,NullScore[4]={0,1500,2000,1500},SubScore[4]={0,0,1000,8000};
UINT top1[ROW_BLOCK_COUNT+2];
BYTE clr1[4]={255,255,255,255};
bool chk=false;
UINT uMinDown,uDown;
CRussionBlock cur(*this);
int L_empty,R_empty;
L_empty=cur.m_pos[0].col-1;
R_empty=ROW_BLOCK_COUNT-cur.m_pos[3].col;
while((L_empty+R_empty)>=0)
{
//ntoper=0;
nScore=0;
uMinDown=0xFFFFFFFF;
nNull=nClrNum1=0;
nLeftCol=ROW_BLOCK_COUNT;
nRightCol=1;
::memcpy(top1,top,(ROW_BLOCK_COUNT+2)*sizeof(UINT));
::memset(CheckCol,0,4*sizeof(int));
//::memset(CheckRow,0,4*sizeof(int));
::memset(clr1,0xFF,4*sizeof(BYTE));
for(i=0;i<4;i++)
cur.m_pos[i].col+=R_empty;//向右
for(i=0;i<4;i++)
{
uDown=cur.m_pos[i].row-top[cur.m_pos[i].col]-1;
if(uDown<uMinDown)
uMinDown=uDown;
}
for(i=0;i<4;i++)
cur.m_pos[i].row-=uMinDown;
for(i=0;i<4;i++)
{
nScore-=(cur.m_pos[i].row*700);
Face[cur.m_pos[i].row][cur.m_pos[i].col]=1;
if(top1[cur.m_pos[i].col]<UINT(cur.m_pos[i].row))
top1[cur.m_pos[i].col]=UINT(cur.m_pos[i].row);
}
int cutoff=cur.CutOff();
for(i=0;i<cutoff;i++)
{
if(::memcmp(Face[cur.m_pos[i].row],full,ROW_BLOCK_COUNT+2)==0)
{
++nClrNum1;
if(nClrNum1%2==0 && cur.m_pos[i].row<clr1[nClrNum1-2])//将放第偶数行并且比前一行小
{
clr1[nClrNum1-1]=clr1[nClrNum1-2];
clr1[nClrNum1-2]=cur.m_pos[i].row;
}
else
clr1[nClrNum1-1]=cur.m_pos[i].row;
}
}
if(nClrNum1>1)//真正擦两行以上,马上返回
{
nMove=R_empty;
nClrNum=nClrNum1;
::memcpy(clr,clr1,4*sizeof(BYTE));
for(i=0;i<4;i++)
Face[cur.m_pos[i].row][cur.m_pos[i].col]=0;
return 0;
}
nScore+=ClearScore[nClrNum1];//擦除不可能超过2
for(i=0;i<4;i++)
{
nNull=0;
chk=false;
for(j=0;j<4&&!chk;j++)
{
if(CheckCol[j]==cur.m_pos[i].col)
chk=true;
}
if(!chk)
{
CheckCol[i]=cur.m_pos[i].col;
int to=((cur.m_pos[i].row-6)>0)?cur.m_pos[i].row-6:0;
for(j=cur.m_pos[i].row-1;j>to && nNull<=3;--j)
{
if(Face[j][cur.m_pos[i].col]<=0)
{
nNull++;
if(j==cur.m_pos[i].row-1)
nScore-=3000;//遮新洞扣3000分,要擦两条以上才能弥补
}
}
if(nNull>3)
nNull=3;
nScore-=NullScore[nNull];
nLeftSub=top1[CheckCol[i]-1]-top1[CheckCol[i]];
nRightSub=top1[CheckCol[i]]-top1[CheckCol[i]+1];
if(nLeftSub>0 && nRightSub<0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -