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

📄 skyblue_rectview.cpp

📁 利用人工智能的经典算法实现迷宫游戏;里面的A星(a*)算法可以很方便的移植到应用程序中
💻 CPP
📖 第 1 页 / 共 3 页
字号:
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
void CSkyblue_RectView::RectDown()
{
	IsBottom();
	if (!m_isBottom)
	{
		//清除以前的方块
		int x1,x2,x3,x4,y1,y2,y3,y4;
		x1 = ActiveStatus[0][0];
		x2 = ActiveStatus[1][0];
		x3 = ActiveStatus[2][0];
		x4 = ActiveStatus[3][0];
		y1 = ActiveStatus[0][1];
		y2 = ActiveStatus[1][1];
		y3 = ActiveStatus[2][1];
		y4 = ActiveStatus[3][1];
		GameStatus[x1][y1]=MAP_STATE_EMPTY;
		GameStatus[x2][y2]=MAP_STATE_EMPTY;
		GameStatus[x3][y3]=MAP_STATE_EMPTY;
		GameStatus[x4][y4]=MAP_STATE_EMPTY;
		InvalidateCurrent();

		//方块下落
		ActiveStatus[0][0] += 1;
		ActiveStatus[1][0] += 1;
		ActiveStatus[2][0] += 1;
		ActiveStatus[3][0] += 1;
		GameStatus[x1+1][y1]=MAP_STATE_NOT_EMPTY;
		GameStatus[x2+1][y2]=MAP_STATE_NOT_EMPTY;
		GameStatus[x3+1][y3]=MAP_STATE_NOT_EMPTY;
		GameStatus[x4+1][y4]=MAP_STATE_NOT_EMPTY;

		InvalidateCurrent();
	}
}

	
/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:当前方块下降加速,左移,右移
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
void CSkyblue_RectView::RectArrow(int m_Type)
{
	//获取当前下坠物4个小方块的位置坐标
	int x1,x2,x3,x4,y1,y2,y3,y4;
	x1 = ActiveStatus[0][0];
	x2 = ActiveStatus[1][0];
	x3 = ActiveStatus[2][0];
	x4 = ActiveStatus[3][0];
	y1 = ActiveStatus[0][1];
	y2 = ActiveStatus[1][1];
	y3 = ActiveStatus[2][1];
	y4 = ActiveStatus[3][1];

	//对不同的移动命令指示进行分类实现
	switch(m_Type)
	{
	case LEFT:
		//对每种不同的移动命令指示特性作相应的可移动分析
		if ( (ActiveStatus[0][1]>0) && IsLeftLimit() && !m_isBottom)
		{
			//清原来的方块
			GameStatus[x1][y1]=MAP_STATE_EMPTY;
			GameStatus[x2][y2]=MAP_STATE_EMPTY;
			GameStatus[x3][y3]=MAP_STATE_EMPTY;
			GameStatus[x4][y4]=MAP_STATE_EMPTY;

		//	InvalidateCurrent();
			//添加新的移动后数据状态
			ActiveStatus[0][1] -= 1;
			ActiveStatus[1][1] -= 1;
			ActiveStatus[2][1] -= 1;
			ActiveStatus[3][1] -= 1;
			GameStatus[x1][y1-1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x2][y2-1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x3][y3-1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x4][y4-1]=MAP_STATE_NOT_EMPTY;

			InvalidateCurrent();
		}
		break;

	case RIGHT:
		if ( (ActiveStatus[3][1]< m_iCol-1) && IsRightLitmit() && !m_isBottom)
		{
			//清原来的方块
			GameStatus[x1][y1]=MAP_STATE_EMPTY;
			GameStatus[x2][y2]=MAP_STATE_EMPTY;
			GameStatus[x3][y3]=MAP_STATE_EMPTY;
			GameStatus[x4][y4]=MAP_STATE_EMPTY;

		//	InvalidateCurrent();
			//添加新的移动后数据状态
			ActiveStatus[0][1] += 1;
			ActiveStatus[1][1] += 1;
			ActiveStatus[2][1] += 1;
			ActiveStatus[3][1] += 1;
			GameStatus[x1][y1+1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x2][y2+1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x3][y3+1]=MAP_STATE_NOT_EMPTY;
			GameStatus[x4][y4+1]=MAP_STATE_NOT_EMPTY;
			
			InvalidateCurrent();
		}
		break;

	case DOWN:
		RectDown();
		break;
	}
}

/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:判断当前方块是否已到底,并且销行等相关的工作
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
void CSkyblue_RectView::IsBottom()
{
	//到底有两种概念:1是已到底部,2是下面碰到了另外的方块
	int x1,x2,x3,x4;
	int x,xx,yy,i;

	x1 = ActiveStatus[0][0];
	x2 = ActiveStatus[1][0];
	x3 = ActiveStatus[2][0];
	x4 = ActiveStatus[3][0];


	//是否为底部的判断
	//1。到达游戏区域的底部
	//2。与接触面正下方的小方块区域为被占用状态
	if (x1>=m_iRow-1 || x2>=m_iRow-1 || x3>=m_iRow-1 || x4>=m_iRow-1)
		m_isBottom = TRUE;
	else
	{
		for (i=0;i<4;i++)
		{
			if (InterFace[m_currentRect][i] > -1)
			{//取当前下坠物有接触面的方块

				//获取有接触面的小方块的编号
				x=InterFace[m_currentRect][i];
				//根据编号获取ActiveStatus中该小方块的整下方的坐标
				xx=ActiveStatus[x][0]+1;
				yy=ActiveStatus[x][1];
				//判断该接触面整下方的小方块区域是否为被占用状态
				if (GameStatus[xx][yy]==MAP_STATE_NOT_EMPTY)
					m_isBottom = TRUE;
			}
		}
	}

	BOOL m_bIsSucced;
	int k,j;
	int m_iMuch=0; //本次销掉的行数

	//计分规则:一次销掉一行,加100分,一次销掉两行,加400分,三行,900分
	//例如销掉x行,则分数为:x*(x*100)

	if (m_isBottom)
	{
		//判断是否已得分
		for (i=0;i<m_iRow;i++)
		{
			m_bIsSucced = TRUE;
			for (j=0;j<m_iCol;j++)
				if (GameStatus[i][j]==MAP_STATE_EMPTY)
					m_bIsSucced = FALSE;
			
			//如果得分,则销掉此行
			if (m_bIsSucced)
			{
				for (k=i;k>0;k--)
					for (j=0;j<m_iCol;j++)
						GameStatus[k][j] = GameStatus[k-1][j];
				//第1行清零
				for (j=0;j<m_iCol;j++)
					GameStatus[0][j]=MAP_STATE_EMPTY;

				m_iMuch += 1;
			}
		}
		
		if (m_iMuch>0)
		{
			m_iPerformance += m_iMuch * m_iMuch * 100;
			//刷新游戏区域
			CRect rect1(m_iStartY, m_iStartX, m_iStartY+300, m_iStartX+360);
			//InvalidateRect(&rect1);
			
			//刷新分数区域
			CRect rect2(m_iStartY+320, m_iStartX+180, m_iStartY+440, m_iStartX+200);
			//InvalidateRect(&rect2);
			Invalidate(FALSE);
		}

	}

}

/* * * * * * * * * * * * * * * * * * * * * * * * *
*
*  名称:OnKeyDown
*
*  功能:处理用户的输入,方块的左,右移,加速及变形
*
*  最后修改时间:2005.8.6
*
* * * * * * * * * * * * * * * * * * * * * * * * */
void CSkyblue_RectView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	switch(nChar)
	{
	case VK_LEFT:
		RectArrow(LEFT);
		break;
	case VK_RIGHT:
		RectArrow(RIGHT);
		break;
	case VK_UP:
		RectChange();
		break;
	case VK_DOWN:
		RectArrow(DOWN);
		break;
	}

	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:方块是否还可以左移
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
BOOL CSkyblue_RectView::IsLeftLimit()
{

	int x1,x2,x3,x4,y1,y2,y3,y4;
	x1 = ActiveStatus[0][0];
	x2 = ActiveStatus[1][0];
	x3 = ActiveStatus[2][0];
	x4 = ActiveStatus[3][0];
	y1 = ActiveStatus[0][1];
	y2 = ActiveStatus[1][1];
	y3 = ActiveStatus[2][1];
	y4 = ActiveStatus[3][1];

	//根据当前下坠物的具体形态,分析判断其是否有向左移动的空间
	switch(m_currentRect)
	{
		/*
		|
		   |
	       |   "1"字形形态类型,判断其四个方块的正左边都没有任何物件(空间没有被占据)
		   |

		 */
	case 1:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1] || GameStatus[x4][y4-1])
			return FALSE;
		break;
	case 11:
		if (GameStatus[x1][y1-1])
			return FALSE;
		break;
	case 2:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
			return FALSE;
		break;
	case 3:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
			return FALSE;
		break;
	case 31:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 32:
		if (GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 33:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x4][y4-1])
			return FALSE;
		break;
	case 4:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x4][y4-1])
			return FALSE;
		break;
	case 41:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
			return FALSE;
		break;
	case 5:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 51:
		if (GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 6:
		if (GameStatus[x1][y1-1] || GameStatus[x3][y3-1] || GameStatus[x4][y4-1])
			return FALSE;
		break;
	case 61:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
			return FALSE;
		break;
	case 62:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 63:
		if (GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 7:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 71:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
			return FALSE;
		break;
	case 72:
		if (GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
			return FALSE;
		break;
	case 73:
		if (GameStatus[x1][y1-1] || GameStatus[x4][y4-1])
			return FALSE;
		break;
	}

	return TRUE;			
}

/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:方块是否还可以右移
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
BOOL CSkyblue_RectView::IsRightLitmit()
{

	int x1,x2,x3,x4,y1,y2,y3,y4;
	x1 = ActiveStatus[0][0];
	x2 = ActiveStatus[1][0];
	x3 = ActiveStatus[2][0];
	x4 = ActiveStatus[3][0];
	y1 = ActiveStatus[0][1];
	y2 = ActiveStatus[1][1];
	y3 = ActiveStatus[2][1];
	y4 = ActiveStatus[3][1];
	
	switch(m_currentRect)
	{
	case 1:
		if (GameStatus[x1][y1+1] || GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 11:
		if (GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 2:
		if (GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 3:
		if (GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 31:
		if (GameStatus[x1][y1+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 32:
		if (GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 33:
		if (GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 4:
		if (GameStatus[x1][y1+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 41:
		if (GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 5:
		if (GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 51:
		if (GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 6:
		if (GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 61:
		if (GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 62:
		if (GameStatus[x1][y1+1] || GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 63:
		if (GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 7:
		if (GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 71:
		if (GameStatus[x1][y1+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 72:
		if (GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	case 73:
		if (GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
			return FALSE;
		break;
	}

	return TRUE;
			

}


/* * * * * * * * * * * * * * * * * * * * * *
* 内部函数:方块的变形
*
* 最后修改日期:2005.8.6
* * * * * * * * * * * * * * * * * * * * * */
void CSkyblue_RectView::RectChange()
{
	//先预先变形,然后判断变形后的方块是否有空间,如有足够空间,则进行实际变形,否则不变
	int xx1,xx2,xx3,xx4,yy1,yy2,yy3,yy4;
	int m_lscurrentRect;
	
	CString lsStr;
	
	int x1,x2,x3,x4,y1,y2,y3,y4;
	x1 = ActiveStatus[0][0];
	x2 = ActiveStatus[1][0];
	x3 = ActiveStatus[2][0];
	x4 = ActiveStatus[3][0];
	y1 = ActiveStatus[0][1];
	y2 = ActiveStatus[1][1];
	y3 = ActiveStatus[2][1];
	y4 = ActiveStatus[3][1];

	//变形后位置在数组中的存放顺序仍需遵循先左后右,在同一列中先上后下
	xx1=x1; xx2=x2; xx3=x3; xx4=x4; yy1=y1; yy2=y2; yy3=y3; yy4=y4;
	switch(m_currentRect)
	{
	case 1:
		xx1=x1+1; yy1=y1-1; xx3=x3-1; yy3=y3+1; xx4=x4-2; yy4=y4+2;
		m_lscurrentRect = 11;
		break;
	case 11:
		xx1=x1-1; yy1=y1+1; xx3=x3+1; yy3=y3-1; xx4=x4+2; yy4=y4-2;
		m_lscurrentRect = 1;
		break;
	case 2:
		m_lscurrentRect=2; 
		break;
	case 3:
		xx1=x1-2; yy1=y1+1; xx4=x4-1; yy4=y4;
		m_lscurrentRect = 31;
		break;
	case 31:
		xx1=x1+1; yy1=y1-1; 
		m_lscurrentRect = 32;
		break;
	case 32:
		xx1=x1+1; yy1=y1; xx4=x4+2; yy4=y4-1;
		m_lscurrentRect=33;
		break;
	case 33:
		xx4=x4-1; yy4=y4+1;
		m_lscurrentRect=3;
		break;
	case 4:
		xx1=x1+2; yy1=y1-1; xx3=x3+1; yy3=y3-1; xx4=x4-1;
		m_lscurrentRect = 41;
		break;
	case 41:
		xx1=x1-2; yy1=y1+1; xx3=x3-1; yy3=y3+1; xx4=x4+1;
		m_lscurrentRect = 4;
		break;
	case 5:
		xx1=x1-1; xx2=x2-2; yy2=y2+1; xx3=x3+1; yy4=y4+1;
		m_lscurrentRect = 51;
		break;
	case 51:
		xx1=x1+1; xx2=x2+2; yy2=y2-1; xx3=x3-1; yy4=y4-1;
		m_lscurrentRect = 5;
		break;
	case 6:
		xx2=x1+1; yy2=y2-1; xx3=x3-1; xx4=x4-2; yy4 = yy4+1;
		m_lscurrentRect = 61;
		break;
	case 61:
		xx3=x3+2; yy3=y3-1; xx4=x4+2; yy4=y4-1;
		m_lscurrentRect = 62;
		break;
	case 62:
		xx1=x1+1; yy1=y1-1; xx3=x3-2; yy3=y3+1; xx4=x4-1;
		m_lscurrentRect = 63;
		break;
	case 63:
		xx1=x1-2; yy1=y1+1; xx2=x2-2; yy2=y2+1;
		m_lscurrentRect = 6;
		break;
	case 7:
		xx3=x3-1; yy3=y3+1; xx4=x4+1; yy4=y4+1;
		m_lscurrentRect = 71;
		break;
	case 71:
		xx1=x1+2; xx2=x2-1; yy2=y2+1; xx4=x4+1; yy4=y4-1;
		m_lscurrentRect = 72;
		break;
	case 72:
		xx1=x1-2; xx3=x3-1; yy3=y3+1; xx4=x4-1; yy4=y4+1;
		m_lscurrentRect = 73;
		break;
	case 73:
		xx2=x2+1; yy2=y2-1; xx3=x3+2; yy3=y3-2; xx4=x4-1; yy4=y4-1;
		m_lscurrentRect = 7;
		break;
	}

	//如果变形后所在的区域内无其他方块,则表示有足够空间,可以变形
	//且不能超越边界
	GameStatus[x1][y1] = MAP_STATE_EMPTY;
	GameStatus[x2][y2] = MAP_STATE_EMPTY;
	GameStatus[x3][y3] = MAP_STATE_EMPTY;
	GameStatus[x4][y4] = MAP_STATE_EMPTY;
	if (GameStatus[xx1][yy1]==MAP_STATE_EMPTY &&
		GameStatus[xx2][yy2]==MAP_STATE_EMPTY &&
		GameStatus[xx3][yy3]==MAP_STATE_EMPTY && 
		GameStatus[xx4][yy4]==MAP_STATE_EMPTY 
		&& yy1>=0 && yy4<=m_iCol-1 
		&& !(xx1<0 || xx2<0 || xx3<0 || xx4<0) 
		&& !(xx1>m_iRow-1 || xx2>m_iRow-1 || xx3>m_iRow-1 || xx4>m_iRow-1) )
	{
		InvalidateCurrent();

		ActiveStatus[0][0]=xx1;
		ActiveStatus[1][0]=xx2;
		ActiveStatus[2][0]=xx3;
		ActiveStatus[3][0]=xx4;
		ActiveStatus[0][1]=yy1;
		ActiveStatus[1][1]=yy2;
		ActiveStatus[2][1]=yy3;
		ActiveStatus[3][1]=yy4;

		GameStatus[xx1][yy1] = MAP_STATE_NOT_EMPTY;
		GameStatus[xx2][yy2] = MAP_STATE_NOT_EMPTY;
		GameStatus[xx3][yy3] = MAP_STATE_NOT_EMPTY;
		GameStatus[xx4][yy4] = MAP_STATE_NOT_EMPTY;

⌨️ 快捷键说明

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